2 * @brief モンスターの思い出を表示する処理
7 #include "view/display-lore.h"
8 #include "game-option/cheat-options.h"
9 #include "game-option/text-display-options.h"
10 #include "locale/english.h"
11 #include "locale/japanese.h"
12 #include "lore/lore-calculator.h"
13 #include "lore/lore-util.h"
14 #include "lore/monster-lore.h"
15 #include "monster-attack/monster-attack-table.h"
16 #include "monster-race/monster-race.h"
17 #include "monster-race/race-ability-flags.h"
18 #include "monster-race/race-flags1.h"
19 #include "monster-race/race-flags2.h"
20 #include "monster-race/race-flags3.h"
21 #include "monster-race/race-flags7.h"
22 #include "monster-race/race-indice-types.h"
23 #include "system/monster-race-info.h"
24 #include "system/player-type-definition.h"
25 #include "term/screen-processor.h"
26 #include "term/term-color-types.h"
27 #include "term/z-form.h"
28 #include "util/bit-flags-calculator.h"
29 #include "util/string-processor.h"
30 #include "view/display-messages.h"
31 #include "world/world.h"
34 * 英語の複数系記述用マクロ / Pluralizer. Args(count, singular, plural)
36 #define plural(c, s, p) (((c) == 1) ? (s) : (p))
39 * @brief モンスター情報のヘッダを記述する
40 * Hack -- Display the "name" and "attr/chars" of a monster race
41 * @param r_idx モンスターの種族ID
43 void roff_top(MonsterRaceId r_idx)
45 auto *r_ptr = &monraces_info[r_idx];
46 char c1 = r_ptr->d_char;
47 char c2 = r_ptr->x_char;
49 TERM_COLOR a1 = r_ptr->d_attr;
50 TERM_COLOR a2 = r_ptr->x_attr;
57 if (r_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
58 term_addstr(-1, TERM_WHITE, "The ");
62 if (w_ptr->wizard || cheat_know) {
63 term_addstr(-1, TERM_WHITE, "[");
64 term_addstr(-1, TERM_L_BLUE, format("%d", enum2i(r_idx)));
65 term_addstr(-1, TERM_WHITE, "] ");
68 term_addstr(-1, TERM_WHITE, r_ptr->name);
70 term_addstr(-1, TERM_WHITE, " ('");
71 term_add_bigch(a1, c1);
72 term_addstr(-1, TERM_WHITE, "')");
74 term_addstr(-1, TERM_WHITE, "/('");
75 term_add_bigch(a2, c2);
76 term_addstr(-1, TERM_WHITE, "'):");
80 * @brief モンスター情報の表示と共に画面を一時消去するサブルーチン /
81 * Hack -- describe the given monster race at the top of the screen
82 * @param r_idx モンスターの種族ID
85 void screen_roff(PlayerType *player_ptr, MonsterRaceId r_idx, monster_lore_mode mode)
90 process_monster_lore(player_ptr, r_idx, mode);
95 * @brief モンスター情報の現在のウィンドウに表示する /
96 * Hack -- describe the given monster race in the current "term" window
97 * @param r_idx モンスターの種族ID
99 void display_roff(PlayerType *player_ptr)
101 for (int y = 0; y < game_term->hgt; y++) {
106 hook_c_roff = c_roff;
107 MonsterRaceId r_idx = player_ptr->monster_race_idx;
108 process_monster_lore(player_ptr, r_idx, MONSTER_LORE_NORMAL);
113 * @brief モンスター詳細情報を自動スポイラー向けに出力する /
114 * Hack -- output description of the given monster race
115 * @param r_idx モンスターの種族ID
116 * @param roff_func 出力処理を行う関数ポインタ
117 * @todo ここのroff_funcの引数にFILE* を追加しないとspoiler_file をローカル関数化することができないと判明した、保留.
119 void output_monster_spoiler(MonsterRaceId r_idx, hook_c_roff_pf roff_func)
121 hook_c_roff = roff_func;
126 process_monster_lore(&dummy, r_idx, MONSTER_LORE_DEBUG);
129 static bool display_kill_unique(lore_type *lore_ptr)
131 if (lore_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
135 bool dead = (lore_ptr->r_ptr->max_num == 0);
136 if (lore_ptr->r_ptr->r_deaths) {
137 hooked_roff(format(_("%s^はあなたの先祖を %d 人葬っている", "%s^ has slain %d of your ancestors"), Who::who(lore_ptr->msex), lore_ptr->r_ptr->r_deaths));
141 _(format("が、すでに仇討ちは果たしている!"), format(", but you have avenged %s! ", plural(lore_ptr->r_ptr->r_deaths, "him", "them"))));
144 _(format("のに、まだ仇討ちを果たしていない。"), format(", who %s unavenged. ", plural(lore_ptr->r_ptr->r_deaths, "remains", "remain"))));
150 hooked_roff(_("あなたはこの仇敵をすでに葬り去っている。", "You have slain this foe. "));
152 hooked_roff(_("この仇敵はまだ生きている!", "This foe is still alive! "));
161 static void display_killed(lore_type *lore_ptr)
163 hooked_roff(_(format("このモンスターはあなたの先祖を %d 人葬っている", lore_ptr->r_ptr->r_deaths),
164 format("%d of your ancestors %s been killed by this creature, ", lore_ptr->r_ptr->r_deaths, plural(lore_ptr->r_ptr->r_deaths, "has", "have"))));
166 if (lore_ptr->r_ptr->r_pkills) {
167 hooked_roff(format(_("が、あなたはこのモンスターを少なくとも %d 体は倒している。", "and you have exterminated at least %d of the creatures. "),
168 lore_ptr->r_ptr->r_pkills));
169 } else if (lore_ptr->r_ptr->r_tkills) {
171 _("が、あなたの先祖はこのモンスターを少なくとも %d 体は倒している。", "and your ancestors have exterminated at least %d of the creatures. "),
172 lore_ptr->r_ptr->r_tkills));
174 hooked_roff(format(_("が、まだ%sを倒したことはない。", "and %s is not ever known to have been defeated. "), Who::who(lore_ptr->msex)));
178 static void display_no_killed(lore_type *lore_ptr)
180 if (lore_ptr->r_ptr->r_pkills) {
182 _("あなたはこのモンスターを少なくとも %d 体は殺している。", "You have killed at least %d of these creatures. "), lore_ptr->r_ptr->r_pkills));
183 } else if (lore_ptr->r_ptr->r_tkills) {
184 hooked_roff(format(_("あなたの先祖はこのモンスターを少なくとも %d 体は殺している。", "Your ancestors have killed at least %d of these creatures. "),
185 lore_ptr->r_ptr->r_tkills));
187 hooked_roff(_("このモンスターを倒したことはない。", "No battles to the death are recalled. "));
192 * @brief 生存数制限のあるモンスターの最大生存数を表示する
193 * @param lore_ptr モンスターの思い出構造体への参照ポインタ
195 * 一度も倒したことのないモンスターの情報は不明。
197 static void display_number_of_nazguls(lore_type *lore_ptr)
199 if (lore_ptr->mode != MONSTER_LORE_DEBUG && lore_ptr->r_ptr->r_tkills == 0) {
202 if (!lore_ptr->r_ptr->population_flags.has(MonsterPopulationType::NAZGUL)) {
206 int remain = lore_ptr->r_ptr->max_num;
207 int killed = lore_ptr->r_ptr->r_akills;
210 hooked_roff(format("%sはかつて %d 体存在した。", Who::who(lore_ptr->msex, (killed > 1)), killed));
212 hooked_roff(format("You already killed all %d of %s. ", killed, Who::whom(lore_ptr->msex, (killed > 1))));
216 hooked_roff(format("%sはまだ %d 体生きている。", Who::who(lore_ptr->msex, (remain + killed > 1)), remain));
218 concptr be = (remain > 1) ? "are" : "is";
219 hooked_roff(format("%d of %s %s still alive. ", remain, Who::whom(lore_ptr->msex, (remain + killed > 1)), be));
224 void display_kill_numbers(lore_type *lore_ptr)
226 if ((lore_ptr->mode & 0x02) != 0) {
230 if (display_kill_unique(lore_ptr)) {
234 if (lore_ptr->r_ptr->r_deaths == 0) {
235 display_no_killed(lore_ptr);
237 display_killed(lore_ptr);
240 display_number_of_nazguls(lore_ptr);
246 * @brief どこに出没するかを表示する
247 * @param lore_ptr モンスターの思い出構造体への参照ポインタ
248 * @return たぬきならFALSE、それ以外はTRUE
250 bool display_where_to_appear(lore_type *lore_ptr)
252 lore_ptr->old = false;
253 if (lore_ptr->r_ptr->level == 0) {
254 hooked_roff(format(_("%s^は町に住み", "%s^ lives in the town"), Who::who(lore_ptr->msex)));
255 lore_ptr->old = true;
256 } else if (lore_ptr->r_ptr->r_tkills || lore_ptr->know_everything) {
259 _("%s^は通常地下 %d フィートで出現し", "%s^ is normally found at depths of %d feet"), Who::who(lore_ptr->msex), lore_ptr->r_ptr->level * 50));
261 hooked_roff(format(_("%s^は通常地下 %d 階で出現し", "%s^ is normally found on dungeon level %d"), Who::who(lore_ptr->msex), lore_ptr->r_ptr->level));
264 lore_ptr->old = true;
267 if (lore_ptr->r_idx == MonsterRaceId::CHAMELEON) {
268 hooked_roff(_("、他のモンスターに化ける。", "and can take the shape of other monster."));
273 hooked_roff(_("、", ", and "));
275 hooked_roff(format(_("%s^は", "%s^ "), Who::who(lore_ptr->msex)));
276 lore_ptr->old = true;
282 // @todo モンスターの速度表記はmonster_typeのオブジェクトメソッドにした方がベター
283 void display_monster_move(lore_type *lore_ptr)
287 hooked_roff("moves");
290 display_random_move(lore_ptr);
291 if (lore_ptr->speed > STANDARD_SPEED) {
292 if (lore_ptr->speed > 139) {
293 hook_c_roff(TERM_RED, _("信じ難いほど", " incredibly"));
294 } else if (lore_ptr->speed > 134) {
295 hook_c_roff(TERM_ORANGE, _("猛烈に", " extremely"));
296 } else if (lore_ptr->speed > 129) {
297 hook_c_roff(TERM_ORANGE, _("非常に", " very"));
298 } else if (lore_ptr->speed > 124) {
299 hook_c_roff(TERM_UMBER, _("かなり", " fairly"));
300 } else if (lore_ptr->speed < 120) {
301 hook_c_roff(TERM_L_UMBER, _("やや", " somewhat"));
303 hook_c_roff(TERM_L_RED, _("素早く", " quickly"));
304 } else if (lore_ptr->speed < STANDARD_SPEED) {
305 if (lore_ptr->speed < 90) {
306 hook_c_roff(TERM_L_GREEN, _("信じ難いほど", " incredibly"));
307 } else if (lore_ptr->speed < 95) {
308 hook_c_roff(TERM_BLUE, _("非常に", " very"));
309 } else if (lore_ptr->speed < 100) {
310 hook_c_roff(TERM_BLUE, _("かなり", " fairly"));
311 } else if (lore_ptr->speed > 104) {
312 hook_c_roff(TERM_GREEN, _("やや", " somewhat"));
314 hook_c_roff(TERM_L_BLUE, _("ゆっくりと", " slowly"));
316 hooked_roff(_("普通の速さで", " at normal speed"));
320 hooked_roff("動いている");
324 void display_random_move(lore_type *lore_ptr)
326 if (lore_ptr->behavior_flags.has_none_of({ MonsterBehaviorType::RAND_MOVE_50, MonsterBehaviorType::RAND_MOVE_25 })) {
330 if (lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50) && lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_25)) {
331 hooked_roff(_("かなり", " extremely"));
332 } else if (lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50)) {
333 hooked_roff(_("幾分", " somewhat"));
334 } else if (lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_25)) {
335 hooked_roff(_("少々", " a bit"));
338 hooked_roff(_("不規則に", " erratically"));
339 if (lore_ptr->speed != STANDARD_SPEED) {
340 hooked_roff(_("、かつ", ", and"));
344 void display_monster_never_move(lore_type *lore_ptr)
346 if (lore_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_MOVE)) {
351 hooked_roff(_("、しかし", ", but "));
353 hooked_roff(format(_("%s^は", "%s^ "), Who::who(lore_ptr->msex)));
354 lore_ptr->old = true;
357 hooked_roff(_("侵入者を追跡しない", "does not deign to chase intruders"));
360 void display_monster_kind(lore_type *lore_ptr)
362 if (lore_ptr->kind_flags.has_none_of({ MonsterKindType::DRAGON, MonsterKindType::DEMON, MonsterKindType::GIANT, MonsterKindType::TROLL, MonsterKindType::ORC, MonsterKindType::ANGEL, MonsterKindType::QUANTUM, MonsterKindType::HUMAN })) {
363 hooked_roff(_("モンスター", " creature"));
367 if (lore_ptr->kind_flags.has(MonsterKindType::DRAGON)) {
368 hook_c_roff(TERM_ORANGE, _("ドラゴン", " dragon"));
371 if (lore_ptr->kind_flags.has(MonsterKindType::DEMON)) {
372 hook_c_roff(TERM_VIOLET, _("デーモン", " demon"));
375 if (lore_ptr->kind_flags.has(MonsterKindType::GIANT)) {
376 hook_c_roff(TERM_L_UMBER, _("巨人", " giant"));
379 if (lore_ptr->kind_flags.has(MonsterKindType::TROLL)) {
380 hook_c_roff(TERM_BLUE, _("トロル", " troll"));
383 if (lore_ptr->kind_flags.has(MonsterKindType::ORC)) {
384 hook_c_roff(TERM_UMBER, _("オーク", " orc"));
387 if (lore_ptr->kind_flags.has(MonsterKindType::HUMAN)) {
388 hook_c_roff(TERM_L_WHITE, _("人間", " human"));
391 if (lore_ptr->kind_flags.has(MonsterKindType::QUANTUM)) {
392 hook_c_roff(TERM_VIOLET, _("量子生物", " quantum creature"));
395 if (lore_ptr->kind_flags.has(MonsterKindType::ANGEL)) {
396 hook_c_roff(TERM_YELLOW, _("天使", " angel"));
400 void display_monster_alignment(lore_type *lore_ptr)
402 if (lore_ptr->flags2 & RF2_ELDRITCH_HORROR) {
403 hook_c_roff(TERM_VIOLET, _("狂気を誘う", " sanity-blasting"));
406 if (lore_ptr->kind_flags.has(MonsterKindType::ANIMAL)) {
407 hook_c_roff(TERM_L_GREEN, _("自然界の", " natural"));
410 if (lore_ptr->kind_flags.has(MonsterKindType::EVIL)) {
411 hook_c_roff(TERM_L_DARK, _("邪悪なる", " evil"));
414 if (lore_ptr->kind_flags.has(MonsterKindType::GOOD)) {
415 hook_c_roff(TERM_YELLOW, _("善良な", " good"));
418 if (lore_ptr->kind_flags.has(MonsterKindType::UNDEAD)) {
419 hook_c_roff(TERM_VIOLET, _("アンデッドの", " undead"));
422 if (lore_ptr->kind_flags.has(MonsterKindType::AMBERITE)) {
423 hook_c_roff(TERM_VIOLET, _("アンバーの王族の", " Amberite"));
428 * @brief モンスターの経験値の思い出を表示する
429 * @param player_ptr プレイヤーの情報へのポインター
430 * @param lore_ptr モンスターの思い出の情報へのポインター
432 void display_monster_exp(PlayerType *player_ptr, lore_type *lore_ptr)
435 hooked_roff("を倒すことは");
438 // 最も経験値の多い金無垢の指輪(level 110、mexp 5000000)でも符号付き32bit整数に収まる
439 const auto base_exp = lore_ptr->r_ptr->mexp * lore_ptr->r_ptr->level * 3 / 2;
440 const auto player_factor = player_ptr->max_plv + 2;
442 const auto exp_integer = base_exp / player_factor;
443 const auto exp_decimal = ((base_exp % player_factor * 1000 / player_factor) + 5) / 10;
446 hooked_roff(format(" %d レベルのキャラクタにとって 約%d.%02d ポイントの経験となる。", player_ptr->lev, exp_integer, exp_decimal));
448 hooked_roff(format(" is worth about %d.%02d point%s", exp_integer, exp_decimal, ((exp_integer == 1) && (exp_decimal == 0)) ? "" : "s"));
451 switch (player_ptr->lev % 10) {
467 switch (player_ptr->lev) {
478 hooked_roff(format(" for a%s %d%s level character. ", vowel, player_ptr->lev, ordinal));
482 void display_monster_aura(lore_type *lore_ptr)
484 auto has_fire_aura = lore_ptr->aura_flags.has(MonsterAuraType::FIRE);
485 auto has_elec_aura = lore_ptr->aura_flags.has(MonsterAuraType::ELEC);
486 auto has_cold_aura = lore_ptr->aura_flags.has(MonsterAuraType::COLD);
487 if (has_fire_aura && has_elec_aura && has_cold_aura) {
489 TERM_VIOLET, format(_("%s^は炎と氷とスパークに包まれている。", "%s^ is surrounded by flames, ice and electricity. "), Who::who(lore_ptr->msex)));
490 } else if (has_fire_aura && has_elec_aura) {
491 hook_c_roff(TERM_L_RED, format(_("%s^は炎とスパークに包まれている。", "%s^ is surrounded by flames and electricity. "), Who::who(lore_ptr->msex)));
492 } else if (has_fire_aura && has_cold_aura) {
493 hook_c_roff(TERM_BLUE, format(_("%s^は炎と氷に包まれている。", "%s^ is surrounded by flames and ice. "), Who::who(lore_ptr->msex)));
494 } else if (has_cold_aura && has_elec_aura) {
495 hook_c_roff(TERM_L_GREEN, format(_("%s^は氷とスパークに包まれている。", "%s^ is surrounded by ice and electricity. "), Who::who(lore_ptr->msex)));
496 } else if (has_fire_aura) {
497 hook_c_roff(TERM_RED, format(_("%s^は炎に包まれている。", "%s^ is surrounded by flames. "), Who::who(lore_ptr->msex)));
498 } else if (has_cold_aura) {
499 hook_c_roff(TERM_BLUE, format(_("%s^は氷に包まれている。", "%s^ is surrounded by ice. "), Who::who(lore_ptr->msex)));
500 } else if (has_elec_aura) {
501 hook_c_roff(TERM_L_BLUE, format(_("%s^はスパークに包まれている。", "%s^ is surrounded by electricity. "), Who::who(lore_ptr->msex)));
505 void display_lore_this(PlayerType *player_ptr, lore_type *lore_ptr)
507 if ((lore_ptr->r_ptr->r_tkills == 0) && !lore_ptr->know_everything) {
514 if (lore_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
515 hooked_roff("Killing this");
517 hooked_roff("A kill of this");
521 display_monster_alignment(lore_ptr);
522 display_monster_kind(lore_ptr);
523 display_monster_exp(player_ptr, lore_ptr);
526 static void display_monster_escort_contents(lore_type *lore_ptr)
528 if (!lore_ptr->reinforce) {
532 hooked_roff(_("護衛の構成は", "These escorts"));
533 if ((lore_ptr->flags1 & RF1_ESCORT) || (lore_ptr->flags1 & RF1_ESCORTS)) {
534 hooked_roff(_("少なくとも", " at the least"));
539 hooked_roff(" contain ");
542 for (auto [r_idx, dd, ds] : lore_ptr->r_ptr->reinforces) {
543 auto is_reinforced = MonsterRace(r_idx).is_valid();
544 is_reinforced &= dd > 0;
545 is_reinforced &= ds > 0;
546 if (!is_reinforced) {
550 const auto *rf_ptr = &monraces_info[r_idx];
551 if (rf_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
552 hooked_roff(format(_("、%s", ", %s"), rf_ptr->name.data()));
557 hooked_roff(format("、 %dd%d 体の%s", dd, ds, rf_ptr->name.data()));
559 auto plural = (dd * ds > 1);
560 GAME_TEXT name[MAX_NLEN];
561 strcpy(name, rf_ptr->name.data());
565 hooked_roff(format(",%dd%d %s", dd, ds, name));
569 hooked_roff(_("で成り立っている。", "."));
572 void display_monster_collective(lore_type *lore_ptr)
574 if ((lore_ptr->flags1 & RF1_ESCORT) || (lore_ptr->flags1 & RF1_ESCORTS) || lore_ptr->reinforce) {
575 hooked_roff(format(_("%s^は通常護衛を伴って現れる。", "%s^ usually appears with escorts. "), Who::who(lore_ptr->msex)));
576 display_monster_escort_contents(lore_ptr);
577 } else if (lore_ptr->flags1 & RF1_FRIENDS) {
578 hooked_roff(format(_("%s^は通常集団で現れる。", "%s^ usually appears in groups. "), Who::who(lore_ptr->msex)));
583 * @brief モンスターの発射に関する情報を表示するルーチン /
584 * Display monster launching information
585 * @param player_ptr プレイヤーへの参照ポインタ
586 * @param lore_ptr モンスターの思い出構造体への参照ポインタ
588 * This function should only be called when display/dump a recall of
590 * @todo max_blows はゲームの中核的なパラメータの1つなのでどこかのヘッダに定数宣言しておきたい
592 void display_monster_launching(PlayerType *player_ptr, lore_type *lore_ptr)
594 if (lore_ptr->ability_flags.has(MonsterAbilityType::ROCKET)) {
595 set_damage(player_ptr, lore_ptr, MonsterAbilityType::ROCKET, _("ロケット%sを発射する", "shoot a rocket%s"));
596 lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
597 lore_ptr->color[lore_ptr->vn++] = TERM_UMBER;
598 lore_ptr->rocket = true;
601 if (lore_ptr->ability_flags.has_not(MonsterAbilityType::SHOOT)) {
605 int p = -1; /* Position of SHOOT */
606 int n = 0; /* Number of blows */
607 const int max_blows = 4;
608 for (int m = 0; m < max_blows; m++) {
609 if (lore_ptr->r_ptr->blows[m].method != RaceBlowMethodType::NONE) {
613 if (lore_ptr->r_ptr->blows[m].method == RaceBlowMethodType::SHOOT) {
614 p = m; /* Remember position */
619 /* When full blows, use a first damage */
620 if (n == max_blows) {
628 if (know_armour(lore_ptr->r_idx, lore_ptr->know_everything)) {
629 strnfmt(lore_ptr->tmp_msg[lore_ptr->vn], sizeof(lore_ptr->tmp_msg[lore_ptr->vn]), _("威力 %dd%d の射撃をする", "fire an arrow (Power:%dd%d)"), lore_ptr->r_ptr->blows[p].d_dice,
630 lore_ptr->r_ptr->blows[p].d_side);
632 angband_strcpy(lore_ptr->tmp_msg[lore_ptr->vn], _("射撃をする", "fire an arrow"), sizeof(lore_ptr->tmp_msg[lore_ptr->vn]));
635 lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
636 lore_ptr->color[lore_ptr->vn++] = TERM_UMBER;
637 lore_ptr->shoot = true;
640 void display_monster_sometimes(lore_type *lore_ptr)
642 if (lore_ptr->vn <= 0) {
646 hooked_roff(format(_("%s^は", "%s^"), Who::who(lore_ptr->msex)));
647 for (int n = 0; n < lore_ptr->vn; n++) {
649 if (n != lore_ptr->vn - 1) {
650 const auto verb = conjugate_jverb(lore_ptr->vp[n], JVerbConjugationType::OR);
651 hook_c_roff(lore_ptr->color[n], verb);
652 hook_c_roff(lore_ptr->color[n], "り");
655 hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
659 hooked_roff(" may ");
660 } else if (n < lore_ptr->vn - 1) {
666 hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
670 hooked_roff(_("ことがある。", ". "));
673 void display_monster_guardian(lore_type *lore_ptr)
675 bool is_kingpin = (lore_ptr->flags1 & RF1_QUESTOR) != 0;
676 is_kingpin &= lore_ptr->r_ptr->r_sights > 0;
677 is_kingpin &= lore_ptr->r_ptr->max_num > 0;
678 is_kingpin &= (lore_ptr->r_idx == MonsterRaceId::OBERON) || (lore_ptr->r_idx == MonsterRaceId::SERPENT);
680 hook_c_roff(TERM_VIOLET, _("あなたはこのモンスターを殺したいという強い欲望を感じている...", "You feel an intense desire to kill this monster... "));
681 } else if (lore_ptr->flags7 & RF7_GUARDIAN) {
682 hook_c_roff(TERM_L_RED, _("このモンスターはダンジョンの主である。", "This monster is the master of a dungeon."));