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-brightness-flags.h"
7 #include "monster-race/race-flags-resistance.h"
8 #include "monster-race/race-flags1.h"
9 #include "monster-race/race-flags2.h"
10 #include "monster-race/race-flags3.h"
11 #include "monster-race/race-flags7.h"
12 #include "system/monster-entity.h"
13 #include "system/monster-race-info.h"
14 #include "term/term-color-types.h"
16 void display_monster_hp_ac(lore_type *lore_ptr)
18 if (!know_armour(lore_ptr->r_idx, lore_ptr->know_everything)) {
22 hooked_roff(format(_("%s^は AC%d の防御力と", "%s^ has an armor rating of %d"), Who::who(lore_ptr->msex), lore_ptr->r_ptr->ac));
23 if (lore_ptr->misc_flags.has(MonsterMiscType::FORCE_MAXHP) || (lore_ptr->r_ptr->hside == 1)) {
24 auto hp = lore_ptr->r_ptr->hdice * (lore_ptr->nightmare ? 2 : 1) * lore_ptr->r_ptr->hside;
25 hooked_roff(format(_(" %d の体力がある。", " and a life rating of %d. "), std::min(MONSTER_MAXHP, hp)));
28 _(" %dd%d の体力がある。", " and a life rating of %dd%d. "), lore_ptr->r_ptr->hdice * (lore_ptr->nightmare ? 2 : 1), lore_ptr->r_ptr->hside));
32 void display_monster_concrete_abilities(lore_type *lore_ptr)
34 if (lore_ptr->brightness_flags.has_any_of({ MonsterBrightnessType::HAS_LITE_1, MonsterBrightnessType::HAS_LITE_2 })) {
35 lore_ptr->vp[lore_ptr->vn] = _("ダンジョンを照らす", "illuminate the dungeon");
36 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
39 if (lore_ptr->brightness_flags.has_any_of({ MonsterBrightnessType::HAS_DARK_1, MonsterBrightnessType::HAS_DARK_2 })) {
40 lore_ptr->vp[lore_ptr->vn] = _("ダンジョンを暗くする", "darken the dungeon");
41 lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
44 if (lore_ptr->behavior_flags.has(MonsterBehaviorType::OPEN_DOOR)) {
45 lore_ptr->vp[lore_ptr->vn] = _("ドアを開ける", "open doors");
46 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
49 if (lore_ptr->behavior_flags.has(MonsterBehaviorType::BASH_DOOR)) {
50 lore_ptr->vp[lore_ptr->vn] = _("ドアを打ち破る", "bash down doors");
51 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
54 if (lore_ptr->r_ptr->feature_flags.has(MonsterFeatureType::CAN_FLY)) {
55 lore_ptr->vp[lore_ptr->vn] = _("空を飛ぶ", "fly");
56 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
59 if (lore_ptr->r_ptr->feature_flags.has(MonsterFeatureType::CAN_SWIM)) {
60 lore_ptr->vp[lore_ptr->vn] = _("水を渡る", "swim");
61 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
64 if (lore_ptr->feature_flags.has(MonsterFeatureType::PASS_WALL)) {
65 lore_ptr->vp[lore_ptr->vn] = _("壁をすり抜ける", "pass through walls");
66 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
69 if (lore_ptr->feature_flags.has(MonsterFeatureType::KILL_WALL)) {
70 lore_ptr->vp[lore_ptr->vn] = _("壁を掘り進む", "bore through walls");
71 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
74 if (lore_ptr->behavior_flags.has(MonsterBehaviorType::MOVE_BODY)) {
75 lore_ptr->vp[lore_ptr->vn] = _("弱いモンスターを押しのける", "push past weaker monsters");
76 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
79 if (lore_ptr->behavior_flags.has(MonsterBehaviorType::KILL_BODY)) {
80 lore_ptr->vp[lore_ptr->vn] = _("弱いモンスターを倒す", "destroy weaker monsters");
81 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
84 if (lore_ptr->behavior_flags.has(MonsterBehaviorType::TAKE_ITEM)) {
85 lore_ptr->vp[lore_ptr->vn] = _("アイテムを拾う", "pick up objects");
86 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
89 if (lore_ptr->behavior_flags.has(MonsterBehaviorType::KILL_ITEM)) {
90 lore_ptr->vp[lore_ptr->vn] = _("アイテムを壊す", "destroy objects");
91 lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
95 void display_monster_abilities(lore_type *lore_ptr)
97 if (lore_ptr->vn <= 0) {
101 hooked_roff(format(_("%s^は", "%s^"), Who::who(lore_ptr->msex)));
102 for (int n = 0; n < lore_ptr->vn; n++) {
104 if (n != lore_ptr->vn - 1) {
105 const auto verb = conjugate_jverb(lore_ptr->vp[n], JVerbConjugationType::AND);
106 hook_c_roff(lore_ptr->color[n], verb);
109 hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
113 hooked_roff(" can ");
114 } else if (n < lore_ptr->vn - 1) {
117 hooked_roff(" and ");
120 hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
124 hooked_roff(_("ことができる。", ". "));
127 void display_monster_constitutions(lore_type *lore_ptr)
129 if (lore_ptr->r_ptr->feature_flags.has(MonsterFeatureType::AQUATIC)) {
130 hooked_roff(format(_("%s^は水中に棲んでいる。", "%s^ lives in water. "), Who::who(lore_ptr->msex)));
133 if (lore_ptr->brightness_flags.has_any_of({ MonsterBrightnessType::SELF_LITE_1, MonsterBrightnessType::SELF_LITE_2 })) {
134 hooked_roff(format(_("%s^は光っている。", "%s^ is shining. "), Who::who(lore_ptr->msex)));
137 if (lore_ptr->brightness_flags.has_any_of({ MonsterBrightnessType::SELF_DARK_1, MonsterBrightnessType::SELF_DARK_2 })) {
138 hook_c_roff(TERM_L_DARK, format(_("%s^は暗黒に包まれている。", "%s^ is surrounded by darkness. "), Who::who(lore_ptr->msex)));
141 if (lore_ptr->misc_flags.has(MonsterMiscType::INVISIBLE)) {
142 hooked_roff(format(_("%s^は透明で目に見えない。", "%s^ is invisible. "), Who::who(lore_ptr->msex)));
145 if (lore_ptr->misc_flags.has(MonsterMiscType::COLD_BLOOD)) {
146 hooked_roff(format(_("%s^は冷血動物である。", "%s^ is cold blooded. "), Who::who(lore_ptr->msex)));
149 if (lore_ptr->flags2 & RF2_EMPTY_MIND) {
150 hooked_roff(format(_("%s^はテレパシーでは感知できない。", "%s^ is not detected by telepathy. "), Who::who(lore_ptr->msex)));
151 } else if (lore_ptr->flags2 & RF2_WEIRD_MIND) {
152 hooked_roff(format(_("%s^はまれにテレパシーで感知できる。", "%s^ is rarely detected by telepathy. "), Who::who(lore_ptr->msex)));
155 if (lore_ptr->misc_flags.has(MonsterMiscType::MULTIPLY)) {
156 hook_c_roff(TERM_L_UMBER, format(_("%s^は爆発的に増殖する。", "%s^ breeds explosively. "), Who::who(lore_ptr->msex)));
159 if (lore_ptr->flags2 & RF2_REGENERATE) {
160 hook_c_roff(TERM_L_WHITE, format(_("%s^は素早く体力を回復する。", "%s^ regenerates quickly. "), Who::who(lore_ptr->msex)));
163 if (lore_ptr->misc_flags.has(MonsterMiscType::RIDING)) {
164 hook_c_roff(TERM_SLATE, format(_("%s^に乗ることができる。", "%s^ is suitable for riding. "), Who::who(lore_ptr->msex)));
168 void display_monster_concrete_weakness(lore_type *lore_ptr)
170 if (lore_ptr->resistance_flags.has(MonsterResistanceType::HURT_ROCK)) {
171 lore_ptr->vp[lore_ptr->vn] = _("岩を除去するもの", "rock remover");
172 lore_ptr->color[lore_ptr->vn++] = TERM_UMBER;
175 if (lore_ptr->resistance_flags.has(MonsterResistanceType::HURT_LITE)) {
176 lore_ptr->vp[lore_ptr->vn] = _("明るい光", "bright light");
177 lore_ptr->color[lore_ptr->vn++] = TERM_YELLOW;
180 if (lore_ptr->resistance_flags.has(MonsterResistanceType::HURT_FIRE)) {
181 lore_ptr->vp[lore_ptr->vn] = _("炎", "fire");
182 lore_ptr->color[lore_ptr->vn++] = TERM_RED;
185 if (lore_ptr->resistance_flags.has(MonsterResistanceType::HURT_COLD)) {
186 lore_ptr->vp[lore_ptr->vn] = _("冷気", "cold");
187 lore_ptr->color[lore_ptr->vn++] = TERM_L_WHITE;
191 void display_monster_weakness(lore_type *lore_ptr)
193 if (lore_ptr->vn <= 0) {
197 hooked_roff(format(_("%s^には", "%s^"), Who::who(lore_ptr->msex)));
198 for (int n = 0; n < lore_ptr->vn; n++) {
205 hooked_roff(" is hurt by ");
206 } else if (n < lore_ptr->vn - 1) {
209 hooked_roff(" and ");
212 hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
215 hooked_roff(_("でダメージを与えられる。", ". "));
218 void display_monster_concrete_resistances(lore_type *lore_ptr)
220 if (lore_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_ACID)) {
221 lore_ptr->vp[lore_ptr->vn] = _("酸", "acid");
222 lore_ptr->color[lore_ptr->vn++] = TERM_GREEN;
225 if (lore_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_ELEC)) {
226 lore_ptr->vp[lore_ptr->vn] = _("稲妻", "lightning");
227 lore_ptr->color[lore_ptr->vn++] = TERM_BLUE;
230 if (lore_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_FIRE)) {
231 lore_ptr->vp[lore_ptr->vn] = _("炎", "fire");
232 lore_ptr->color[lore_ptr->vn++] = TERM_RED;
235 if (lore_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_COLD)) {
236 lore_ptr->vp[lore_ptr->vn] = _("冷気", "cold");
237 lore_ptr->color[lore_ptr->vn++] = TERM_L_WHITE;
240 if (lore_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_POISON)) {
241 lore_ptr->vp[lore_ptr->vn] = _("毒", "poison");
242 lore_ptr->color[lore_ptr->vn++] = TERM_L_GREEN;
245 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_LITE)) {
246 lore_ptr->vp[lore_ptr->vn] = _("閃光", "light");
247 lore_ptr->color[lore_ptr->vn++] = TERM_YELLOW;
250 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_DARK)) {
251 lore_ptr->vp[lore_ptr->vn] = _("暗黒", "dark");
252 lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
255 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_NETHER)) {
256 lore_ptr->vp[lore_ptr->vn] = _("地獄", "nether");
257 lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
260 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_WATER)) {
261 lore_ptr->vp[lore_ptr->vn] = _("水", "water");
262 lore_ptr->color[lore_ptr->vn++] = TERM_BLUE;
265 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_PLASMA)) {
266 lore_ptr->vp[lore_ptr->vn] = _("プラズマ", "plasma");
267 lore_ptr->color[lore_ptr->vn++] = TERM_L_RED;
270 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_SHARDS)) {
271 lore_ptr->vp[lore_ptr->vn] = _("破片", "shards");
272 lore_ptr->color[lore_ptr->vn++] = TERM_L_UMBER;
275 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_SOUND)) {
276 lore_ptr->vp[lore_ptr->vn] = _("轟音", "sound");
277 lore_ptr->color[lore_ptr->vn++] = TERM_ORANGE;
280 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_CHAOS)) {
281 lore_ptr->vp[lore_ptr->vn] = _("カオス", "chaos");
282 lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
285 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_NEXUS)) {
286 lore_ptr->vp[lore_ptr->vn] = _("因果混乱", "nexus");
287 lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
290 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_DISENCHANT)) {
291 lore_ptr->vp[lore_ptr->vn] = _("劣化", "disenchantment");
292 lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
295 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_FORCE)) {
296 lore_ptr->vp[lore_ptr->vn] = _("フォース", "force");
297 lore_ptr->color[lore_ptr->vn++] = TERM_UMBER;
300 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_INERTIA)) {
301 lore_ptr->vp[lore_ptr->vn] = _("遅鈍", "inertia");
302 lore_ptr->color[lore_ptr->vn++] = TERM_SLATE;
305 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_TIME)) {
306 lore_ptr->vp[lore_ptr->vn] = _("時間逆転", "time");
307 lore_ptr->color[lore_ptr->vn++] = TERM_L_BLUE;
310 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_GRAVITY)) {
311 lore_ptr->vp[lore_ptr->vn] = _("重力", "gravity");
312 lore_ptr->color[lore_ptr->vn++] = TERM_SLATE;
315 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_METEOR)) {
316 lore_ptr->vp[lore_ptr->vn] = _("隕石", "meteor");
317 lore_ptr->color[lore_ptr->vn++] = TERM_UMBER;
320 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_ALL)) {
321 lore_ptr->vp[lore_ptr->vn] = _("あらゆる攻撃", "all");
322 lore_ptr->color[lore_ptr->vn++] = TERM_YELLOW;
325 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_TELEPORT) && lore_ptr->r_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
326 lore_ptr->vp[lore_ptr->vn] = _("テレポート", "teleportation");
327 lore_ptr->color[lore_ptr->vn++] = TERM_ORANGE;
331 void display_monster_resistances(lore_type *lore_ptr)
333 if (lore_ptr->vn <= 0) {
337 hooked_roff(format(_("%s^は", "%s^"), Who::who(lore_ptr->msex)));
338 for (int n = 0; n < lore_ptr->vn; n++) {
345 hooked_roff(" resists ");
346 } else if (n < lore_ptr->vn - 1) {
349 hooked_roff(" and ");
352 hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
355 hooked_roff(_("の耐性を持っている。", ". "));
358 void display_monster_evolution(lore_type *lore_ptr)
360 if (!lore_ptr->r_ptr->r_can_evolve && !lore_ptr->know_everything) {
364 if (MonsterRace(lore_ptr->r_ptr->next_r_idx).is_valid()) {
365 hooked_roff(format(_("%s^は経験を積むと、", "%s^ will evolve into "), Who::who(lore_ptr->msex)));
366 hook_c_roff(TERM_YELLOW, format("%s", monraces_info[lore_ptr->r_ptr->next_r_idx].name.data()));
368 hooked_roff(_(format("に進化する。"), format(" when %s gets enough experience. ", Who::who(lore_ptr->msex))));
369 } else if (lore_ptr->r_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
370 hooked_roff(format(_("%sは進化しない。", "%s won't evolve. "), Who::who(lore_ptr->msex)));
374 void display_monster_concrete_immunities(lore_type *lore_ptr)
376 if (lore_ptr->resistance_flags.has(MonsterResistanceType::NO_STUN)) {
377 lore_ptr->vp[lore_ptr->vn] = _("朦朧としない", "stunned");
378 lore_ptr->color[lore_ptr->vn++] = TERM_ORANGE;
381 if (lore_ptr->resistance_flags.has(MonsterResistanceType::NO_FEAR)) {
382 lore_ptr->vp[lore_ptr->vn] = _("恐怖を感じない", "frightened");
383 lore_ptr->color[lore_ptr->vn++] = TERM_SLATE;
386 if (lore_ptr->resistance_flags.has(MonsterResistanceType::NO_CONF)) {
387 lore_ptr->vp[lore_ptr->vn] = _("混乱しない", "confused");
388 lore_ptr->color[lore_ptr->vn++] = TERM_L_UMBER;
391 if (lore_ptr->resistance_flags.has(MonsterResistanceType::NO_SLEEP)) {
392 lore_ptr->vp[lore_ptr->vn] = _("眠らされない", "slept");
393 lore_ptr->color[lore_ptr->vn++] = TERM_BLUE;
396 if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_TELEPORT) && lore_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
397 lore_ptr->vp[lore_ptr->vn] = _("テレポートされない", "teleported");
398 lore_ptr->color[lore_ptr->vn++] = TERM_ORANGE;
401 if (lore_ptr->resistance_flags.has(MonsterResistanceType::NO_INSTANTLY_DEATH) || lore_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
402 lore_ptr->vp[lore_ptr->vn] = _("即死しない", "instantly killed");
403 lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
407 void display_monster_immunities(lore_type *lore_ptr)
409 if (lore_ptr->vn <= 0) {
413 hooked_roff(format(_("%s^は", "%s^"), Who::who(lore_ptr->msex)));
414 for (int n = 0; n < lore_ptr->vn; n++) {
421 hooked_roff(" cannot be ");
422 } else if (n < lore_ptr->vn - 1) {
428 hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
431 hooked_roff(_("。", ". "));
434 void display_monster_alert(lore_type *lore_ptr)
436 bool alert = ((int)lore_ptr->r_ptr->r_wake * (int)lore_ptr->r_ptr->r_wake) > lore_ptr->r_ptr->sleep;
437 alert |= lore_ptr->r_ptr->r_ignore == MAX_UCHAR;
438 alert |= (lore_ptr->r_ptr->sleep == 0) && (lore_ptr->r_ptr->r_tkills >= 10);
439 alert |= lore_ptr->know_everything;
445 if (lore_ptr->r_ptr->sleep > 200) {
446 act = _("を無視しがちであるが", "prefers to ignore");
447 } else if (lore_ptr->r_ptr->sleep > 95) {
448 act = _("に対してほとんど注意を払わないが", "pays very little attention to");
449 } else if (lore_ptr->r_ptr->sleep > 75) {
450 act = _("に対してあまり注意を払わないが", "pays little attention to");
451 } else if (lore_ptr->r_ptr->sleep > 45) {
452 act = _("を見過ごしがちであるが", "tends to overlook");
453 } else if (lore_ptr->r_ptr->sleep > 25) {
454 act = _("をほんの少しは見ており", "takes quite a while to see");
455 } else if (lore_ptr->r_ptr->sleep > 10) {
456 act = _("をしばらくは見ており", "takes a while to see");
457 } else if (lore_ptr->r_ptr->sleep > 5) {
458 act = _("を幾分注意深く見ており", "is fairly observant of");
459 } else if (lore_ptr->r_ptr->sleep > 3) {
460 act = _("を注意深く見ており", "is observant of");
461 } else if (lore_ptr->r_ptr->sleep > 1) {
462 act = _("をかなり注意深く見ており", "is very observant of");
463 } else if (lore_ptr->r_ptr->sleep > 0) {
464 act = _("を警戒しており", "is vigilant for");
466 act = _("をかなり警戒しており", "is ever vigilant for");
469 hooked_roff(_(format("%s^は侵入者%s、 %d フィート先から侵入者に気付くことがある。", Who::who(lore_ptr->msex), act, 10 * lore_ptr->r_ptr->aaf),
470 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)));