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 "util/bit-flags-calculator.h"
28 #include "view/display-messages.h"
29 #include "world/world.h"
32 * 英語の複数系記述用マクロ / Pluralizer. Args(count, singular, plural)
34 #define plural(c, s, p) (((c) == 1) ? (s) : (p))
37 * @brief モンスター情報のヘッダを記述する
38 * Hack -- Display the "name" and "attr/chars" of a monster race
39 * @param r_idx モンスターの種族ID
41 void roff_top(MonsterRaceId r_idx)
43 auto *r_ptr = &monraces_info[r_idx];
44 char c1 = r_ptr->d_char;
45 char c2 = r_ptr->x_char;
47 TERM_COLOR a1 = r_ptr->d_attr;
48 TERM_COLOR a2 = r_ptr->x_attr;
50 term_erase(0, 0, 255);
55 if (r_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
56 term_addstr(-1, TERM_WHITE, "The ");
60 if (w_ptr->wizard || cheat_know) {
61 term_addstr(-1, TERM_WHITE, "[");
62 term_addstr(-1, TERM_L_BLUE, format("%d", r_idx));
63 term_addstr(-1, TERM_WHITE, "] ");
66 term_addstr(-1, TERM_WHITE, (r_ptr->name.data()));
68 term_addstr(-1, TERM_WHITE, " ('");
69 term_add_bigch(a1, c1);
70 term_addstr(-1, TERM_WHITE, "')");
72 term_addstr(-1, TERM_WHITE, "/('");
73 term_add_bigch(a2, c2);
74 term_addstr(-1, TERM_WHITE, "'):");
78 * @brief モンスター情報の表示と共に画面を一時消去するサブルーチン /
79 * Hack -- describe the given monster race at the top of the screen
80 * @param r_idx モンスターの種族ID
83 void screen_roff(PlayerType *player_ptr, MonsterRaceId r_idx, monster_lore_mode mode)
86 term_erase(0, 1, 255);
88 process_monster_lore(player_ptr, r_idx, mode);
93 * @brief モンスター情報の現在のウィンドウに表示する /
94 * Hack -- describe the given monster race in the current "term" window
95 * @param r_idx モンスターの種族ID
97 void display_roff(PlayerType *player_ptr)
99 for (int y = 0; y < game_term->hgt; y++) {
100 term_erase(0, y, 255);
104 hook_c_roff = c_roff;
105 MonsterRaceId r_idx = player_ptr->monster_race_idx;
106 process_monster_lore(player_ptr, r_idx, MONSTER_LORE_NORMAL);
111 * @brief モンスター詳細情報を自動スポイラー向けに出力する /
112 * Hack -- output description of the given monster race
113 * @param r_idx モンスターの種族ID
114 * @param roff_func 出力処理を行う関数ポインタ
115 * @todo ここのroff_funcの引数にFILE* を追加しないとspoiler_file をローカル関数化することができないと判明した、保留.
117 void output_monster_spoiler(MonsterRaceId r_idx, void (*roff_func)(TERM_COLOR attr, concptr str))
119 hook_c_roff = roff_func;
124 process_monster_lore(&dummy, r_idx, MONSTER_LORE_DEBUG);
127 static bool display_kill_unique(lore_type *lore_ptr)
129 if (lore_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
133 bool dead = (lore_ptr->r_ptr->max_num == 0);
134 if (lore_ptr->r_ptr->r_deaths) {
135 hooked_roff(format(_("%^sはあなたの先祖を %d 人葬っている", "%^s has slain %d of your ancestors"), Who::who(lore_ptr->msex), lore_ptr->r_ptr->r_deaths));
139 _(format("が、すでに仇討ちは果たしている!"), format(", but you have avenged %s! ", plural(lore_ptr->r_ptr->r_deaths, "him", "them"))));
142 _(format("のに、まだ仇討ちを果たしていない。"), format(", who %s unavenged. ", plural(lore_ptr->r_ptr->r_deaths, "remains", "remain"))));
148 hooked_roff(_("あなたはこの仇敵をすでに葬り去っている。", "You have slain this foe. "));
150 hooked_roff(_("この仇敵はまだ生きている!", "This foe is still alive! "));
159 static void display_killed(lore_type *lore_ptr)
161 hooked_roff(_(format("このモンスターはあなたの先祖を %d 人葬っている", lore_ptr->r_ptr->r_deaths),
162 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"))));
164 if (lore_ptr->r_ptr->r_pkills) {
165 hooked_roff(format(_("が、あなたはこのモンスターを少なくとも %d 体は倒している。", "and you have exterminated at least %d of the creatures. "),
166 lore_ptr->r_ptr->r_pkills));
167 } else if (lore_ptr->r_ptr->r_tkills) {
169 _("が、あなたの先祖はこのモンスターを少なくとも %d 体は倒している。", "and your ancestors have exterminated at least %d of the creatures. "),
170 lore_ptr->r_ptr->r_tkills));
172 hooked_roff(format(_("が、まだ%sを倒したことはない。", "and %s is not ever known to have been defeated. "), Who::who(lore_ptr->msex)));
176 static void display_no_killed(lore_type *lore_ptr)
178 if (lore_ptr->r_ptr->r_pkills) {
180 _("あなたはこのモンスターを少なくとも %d 体は殺している。", "You have killed at least %d of these creatures. "), lore_ptr->r_ptr->r_pkills));
181 } else if (lore_ptr->r_ptr->r_tkills) {
182 hooked_roff(format(_("あなたの先祖はこのモンスターを少なくとも %d 体は殺している。", "Your ancestors have killed at least %d of these creatures. "),
183 lore_ptr->r_ptr->r_tkills));
185 hooked_roff(_("このモンスターを倒したことはない。", "No battles to the death are recalled. "));
190 * @brief 生存数制限のあるモンスターの最大生存数を表示する
191 * @param lore_ptr モンスターの思い出構造体への参照ポインタ
193 * 一度も倒したことのないモンスターの情報は不明。
195 static void display_number_of_nazguls(lore_type *lore_ptr)
197 if (lore_ptr->mode != MONSTER_LORE_DEBUG && lore_ptr->r_ptr->r_tkills == 0) {
200 if (!lore_ptr->r_ptr->population_flags.has(MonsterPopulationType::NAZGUL)) {
204 int remain = lore_ptr->r_ptr->max_num;
205 int killed = lore_ptr->r_ptr->r_akills;
208 hooked_roff(format("%sはかつて %ld 体存在した。", Who::who(lore_ptr->msex, (killed > 1)), killed));
210 hooked_roff(format("You already killed all %ld of %s. ", killed, Who::whom(lore_ptr->msex, (killed > 1))));
214 hooked_roff(format("%sはまだ %ld 体生きている。", Who::who(lore_ptr->msex, (remain + killed > 1)), remain));
216 concptr be = (remain > 1) ? "are" : "is";
217 hooked_roff(format("%ld of %s %s still alive. ", remain, Who::whom(lore_ptr->msex, (remain + killed > 1)), be));
222 void display_kill_numbers(lore_type *lore_ptr)
224 if ((lore_ptr->mode & 0x02) != 0) {
228 if (display_kill_unique(lore_ptr)) {
232 if (lore_ptr->r_ptr->r_deaths == 0) {
233 display_no_killed(lore_ptr);
235 display_killed(lore_ptr);
238 display_number_of_nazguls(lore_ptr);
244 * @brief どこに出没するかを表示する
245 * @param lore_ptr モンスターの思い出構造体への参照ポインタ
246 * @return たぬきならFALSE、それ以外はTRUE
248 bool display_where_to_appear(lore_type *lore_ptr)
250 lore_ptr->old = false;
251 if (lore_ptr->r_ptr->level == 0) {
252 hooked_roff(format(_("%^sは町に住み", "%^s lives in the town"), Who::who(lore_ptr->msex)));
253 lore_ptr->old = true;
254 } else if (lore_ptr->r_ptr->r_tkills || lore_ptr->know_everything) {
257 _("%^sは通常地下 %d フィートで出現し", "%^s is normally found at depths of %d feet"), Who::who(lore_ptr->msex), lore_ptr->r_ptr->level * 50));
259 hooked_roff(format(_("%^sは通常地下 %d 階で出現し", "%^s is normally found on dungeon level %d"), Who::who(lore_ptr->msex), lore_ptr->r_ptr->level));
262 lore_ptr->old = true;
265 if (lore_ptr->r_idx == MonsterRaceId::CHAMELEON) {
266 hooked_roff(_("、他のモンスターに化ける。", "and can take the shape of other monster."));
271 hooked_roff(_("、", ", and "));
273 hooked_roff(format(_("%^sは", "%^s "), Who::who(lore_ptr->msex)));
274 lore_ptr->old = true;
280 // @todo モンスターの速度表記はmonster_typeのオブジェクトメソッドにした方がベター
281 void display_monster_move(lore_type *lore_ptr)
285 hooked_roff("moves");
288 display_random_move(lore_ptr);
289 if (lore_ptr->speed > STANDARD_SPEED) {
290 if (lore_ptr->speed > 139) {
291 hook_c_roff(TERM_RED, _("信じ難いほど", " incredibly"));
292 } else if (lore_ptr->speed > 134) {
293 hook_c_roff(TERM_ORANGE, _("猛烈に", " extremely"));
294 } else if (lore_ptr->speed > 129) {
295 hook_c_roff(TERM_ORANGE, _("非常に", " very"));
296 } else if (lore_ptr->speed > 124) {
297 hook_c_roff(TERM_UMBER, _("かなり", " fairly"));
298 } else if (lore_ptr->speed < 120) {
299 hook_c_roff(TERM_L_UMBER, _("やや", " somewhat"));
301 hook_c_roff(TERM_L_RED, _("素早く", " quickly"));
302 } else if (lore_ptr->speed < STANDARD_SPEED) {
303 if (lore_ptr->speed < 90) {
304 hook_c_roff(TERM_L_GREEN, _("信じ難いほど", " incredibly"));
305 } else if (lore_ptr->speed < 95) {
306 hook_c_roff(TERM_BLUE, _("非常に", " very"));
307 } else if (lore_ptr->speed < 100) {
308 hook_c_roff(TERM_BLUE, _("かなり", " fairly"));
309 } else if (lore_ptr->speed > 104) {
310 hook_c_roff(TERM_GREEN, _("やや", " somewhat"));
312 hook_c_roff(TERM_L_BLUE, _("ゆっくりと", " slowly"));
314 hooked_roff(_("普通の速さで", " at normal speed"));
318 hooked_roff("動いている");
322 void display_random_move(lore_type *lore_ptr)
324 if (lore_ptr->behavior_flags.has_none_of({ MonsterBehaviorType::RAND_MOVE_50, MonsterBehaviorType::RAND_MOVE_25 })) {
328 if (lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50) && lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_25)) {
329 hooked_roff(_("かなり", " extremely"));
330 } else if (lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50)) {
331 hooked_roff(_("幾分", " somewhat"));
332 } else if (lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_25)) {
333 hooked_roff(_("少々", " a bit"));
336 hooked_roff(_("不規則に", " erratically"));
337 if (lore_ptr->speed != STANDARD_SPEED) {
338 hooked_roff(_("、かつ", ", and"));
342 void display_monster_never_move(lore_type *lore_ptr)
344 if (lore_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_MOVE)) {
349 hooked_roff(_("、しかし", ", but "));
351 hooked_roff(format(_("%^sは", "%^s "), Who::who(lore_ptr->msex)));
352 lore_ptr->old = true;
355 hooked_roff(_("侵入者を追跡しない", "does not deign to chase intruders"));
358 void display_monster_kind(lore_type *lore_ptr)
360 if (lore_ptr->kind_flags.has_none_of({ MonsterKindType::DRAGON, MonsterKindType::DEMON, MonsterKindType::GIANT, MonsterKindType::TROLL, MonsterKindType::ORC, MonsterKindType::ANGEL, MonsterKindType::QUANTUM, MonsterKindType::HUMAN })) {
361 hooked_roff(_("モンスター", " creature"));
365 if (lore_ptr->kind_flags.has(MonsterKindType::DRAGON)) {
366 hook_c_roff(TERM_ORANGE, _("ドラゴン", " dragon"));
369 if (lore_ptr->kind_flags.has(MonsterKindType::DEMON)) {
370 hook_c_roff(TERM_VIOLET, _("デーモン", " demon"));
373 if (lore_ptr->kind_flags.has(MonsterKindType::GIANT)) {
374 hook_c_roff(TERM_L_UMBER, _("巨人", " giant"));
377 if (lore_ptr->kind_flags.has(MonsterKindType::TROLL)) {
378 hook_c_roff(TERM_BLUE, _("トロル", " troll"));
381 if (lore_ptr->kind_flags.has(MonsterKindType::ORC)) {
382 hook_c_roff(TERM_UMBER, _("オーク", " orc"));
385 if (lore_ptr->kind_flags.has(MonsterKindType::HUMAN)) {
386 hook_c_roff(TERM_L_WHITE, _("人間", " human"));
389 if (lore_ptr->kind_flags.has(MonsterKindType::QUANTUM)) {
390 hook_c_roff(TERM_VIOLET, _("量子生物", " quantum creature"));
393 if (lore_ptr->kind_flags.has(MonsterKindType::ANGEL)) {
394 hook_c_roff(TERM_YELLOW, _("天使", " angel"));
398 void display_monster_alignment(lore_type *lore_ptr)
400 if (lore_ptr->flags2 & RF2_ELDRITCH_HORROR) {
401 hook_c_roff(TERM_VIOLET, _("狂気を誘う", " sanity-blasting"));
404 if (lore_ptr->kind_flags.has(MonsterKindType::ANIMAL)) {
405 hook_c_roff(TERM_L_GREEN, _("自然界の", " natural"));
408 if (lore_ptr->kind_flags.has(MonsterKindType::EVIL)) {
409 hook_c_roff(TERM_L_DARK, _("邪悪なる", " evil"));
412 if (lore_ptr->kind_flags.has(MonsterKindType::GOOD)) {
413 hook_c_roff(TERM_YELLOW, _("善良な", " good"));
416 if (lore_ptr->kind_flags.has(MonsterKindType::UNDEAD)) {
417 hook_c_roff(TERM_VIOLET, _("アンデッドの", " undead"));
420 if (lore_ptr->kind_flags.has(MonsterKindType::AMBERITE)) {
421 hook_c_roff(TERM_VIOLET, _("アンバーの王族の", " Amberite"));
426 * @brief モンスターの経験値の思い出を表示する
427 * @param player_ptr プレイヤーの情報へのポインター
428 * @param lore_ptr モンスターの思い出の情報へのポインター
430 void display_monster_exp(PlayerType *player_ptr, lore_type *lore_ptr)
433 hooked_roff("を倒すことは");
436 int64_t base_exp = lore_ptr->r_ptr->mexp * lore_ptr->r_ptr->level * 3 / 2;
437 int64_t player_factor = (int64_t)player_ptr->max_plv + 2;
439 int64_t exp_integer = base_exp / player_factor;
440 int64_t exp_decimal = ((base_exp % player_factor * 1000 / player_factor) + 5) / 10;
443 hooked_roff(format(" %d レベルのキャラクタにとって 約%Ld.%02Ld ポイントの経験となる。", player_ptr->lev, exp_integer, exp_decimal));
445 hooked_roff(format(" is worth about %Ld.%02Ld point%s", exp_integer, exp_decimal, ((exp_integer == 1) && (exp_decimal == 0)) ? "" : "s"));
448 switch (player_ptr->lev % 10) {
464 switch (player_ptr->lev) {
475 hooked_roff(format(" for a%s %d%s level character. ", vowel, player_ptr->lev, ordinal));
479 void display_monster_aura(lore_type *lore_ptr)
481 auto has_fire_aura = lore_ptr->aura_flags.has(MonsterAuraType::FIRE);
482 auto has_elec_aura = lore_ptr->aura_flags.has(MonsterAuraType::ELEC);
483 auto has_cold_aura = lore_ptr->aura_flags.has(MonsterAuraType::COLD);
484 if (has_fire_aura && has_elec_aura && has_cold_aura) {
486 TERM_VIOLET, format(_("%^sは炎と氷とスパークに包まれている。", "%^s is surrounded by flames, ice and electricity. "), Who::who(lore_ptr->msex)));
487 } else if (has_fire_aura && has_elec_aura) {
488 hook_c_roff(TERM_L_RED, format(_("%^sは炎とスパークに包まれている。", "%^s is surrounded by flames and electricity. "), Who::who(lore_ptr->msex)));
489 } else if (has_fire_aura && has_cold_aura) {
490 hook_c_roff(TERM_BLUE, format(_("%^sは炎と氷に包まれている。", "%^s is surrounded by flames and ice. "), Who::who(lore_ptr->msex)));
491 } else if (has_cold_aura && has_elec_aura) {
492 hook_c_roff(TERM_L_GREEN, format(_("%^sは氷とスパークに包まれている。", "%^s is surrounded by ice and electricity. "), Who::who(lore_ptr->msex)));
493 } else if (has_fire_aura) {
494 hook_c_roff(TERM_RED, format(_("%^sは炎に包まれている。", "%^s is surrounded by flames. "), Who::who(lore_ptr->msex)));
495 } else if (has_cold_aura) {
496 hook_c_roff(TERM_BLUE, format(_("%^sは氷に包まれている。", "%^s is surrounded by ice. "), Who::who(lore_ptr->msex)));
497 } else if (has_elec_aura) {
498 hook_c_roff(TERM_L_BLUE, format(_("%^sはスパークに包まれている。", "%^s is surrounded by electricity. "), Who::who(lore_ptr->msex)));
502 void display_lore_this(PlayerType *player_ptr, lore_type *lore_ptr)
504 if ((lore_ptr->r_ptr->r_tkills == 0) && !lore_ptr->know_everything) {
511 if (lore_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
512 hooked_roff("Killing this");
514 hooked_roff("A kill of this");
518 display_monster_alignment(lore_ptr);
519 display_monster_kind(lore_ptr);
520 display_monster_exp(player_ptr, lore_ptr);
523 static void display_monster_escort_contents(lore_type *lore_ptr)
525 if (!lore_ptr->reinforce) {
529 hooked_roff(_("護衛の構成は", "These escorts"));
530 if ((lore_ptr->flags1 & RF1_ESCORT) || (lore_ptr->flags1 & RF1_ESCORTS)) {
531 hooked_roff(_("少なくとも", " at the least"));
536 hooked_roff(" contain ");
539 for (auto [r_idx, dd, ds] : lore_ptr->r_ptr->reinforces) {
540 auto is_reinforced = MonsterRace(r_idx).is_valid();
541 is_reinforced &= dd > 0;
542 is_reinforced &= ds > 0;
543 if (!is_reinforced) {
547 const auto *rf_ptr = &monraces_info[r_idx];
548 if (rf_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
549 hooked_roff(format(_("、%s", ", %s"), rf_ptr->name.data()));
554 hooked_roff(format("、 %dd%d 体の%s", dd, ds, rf_ptr->name.data()));
556 auto plural = (dd * ds > 1);
557 GAME_TEXT name[MAX_NLEN];
558 strcpy(name, rf_ptr->name.data());
562 hooked_roff(format(",%dd%d %s", dd, ds, name));
566 hooked_roff(_("で成り立っている。", "."));
569 void display_monster_collective(lore_type *lore_ptr)
571 if ((lore_ptr->flags1 & RF1_ESCORT) || (lore_ptr->flags1 & RF1_ESCORTS) || lore_ptr->reinforce) {
572 hooked_roff(format(_("%^sは通常護衛を伴って現れる。", "%^s usually appears with escorts. "), Who::who(lore_ptr->msex)));
573 display_monster_escort_contents(lore_ptr);
574 } else if (lore_ptr->flags1 & RF1_FRIENDS) {
575 hooked_roff(format(_("%^sは通常集団で現れる。", "%^s usually appears in groups. "), Who::who(lore_ptr->msex)));
580 * @brief モンスターの発射に関する情報を表示するルーチン /
581 * Display monster launching information
582 * @param player_ptr プレイヤーへの参照ポインタ
583 * @param lore_ptr モンスターの思い出構造体への参照ポインタ
585 * This function should only be called when display/dump a recall of
587 * @todo max_blows はゲームの中核的なパラメータの1つなのでどこかのヘッダに定数宣言しておきたい
589 void display_monster_launching(PlayerType *player_ptr, lore_type *lore_ptr)
591 if (lore_ptr->ability_flags.has(MonsterAbilityType::ROCKET)) {
592 set_damage(player_ptr, lore_ptr, MonsterAbilityType::ROCKET, _("ロケット%sを発射する", "shoot a rocket%s"));
593 lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
594 lore_ptr->color[lore_ptr->vn++] = TERM_UMBER;
595 lore_ptr->rocket = true;
598 if (lore_ptr->ability_flags.has_not(MonsterAbilityType::SHOOT)) {
602 int p = -1; /* Position of SHOOT */
603 int n = 0; /* Number of blows */
604 const int max_blows = 4;
605 for (int m = 0; m < max_blows; m++) {
606 if (lore_ptr->r_ptr->blow[m].method != RaceBlowMethodType::NONE) {
610 if (lore_ptr->r_ptr->blow[m].method == RaceBlowMethodType::SHOOT) {
611 p = m; /* Remember position */
616 /* When full blows, use a first damage */
617 if (n == max_blows) {
625 if (know_armour(lore_ptr->r_idx, lore_ptr->know_everything)) {
626 sprintf(lore_ptr->tmp_msg[lore_ptr->vn], _("威力 %dd%d の射撃をする", "fire an arrow (Power:%dd%d)"), lore_ptr->r_ptr->blow[p].d_dice,
627 lore_ptr->r_ptr->blow[p].d_side);
629 sprintf(lore_ptr->tmp_msg[lore_ptr->vn], _("射撃をする", "fire an arrow"));
632 lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
633 lore_ptr->color[lore_ptr->vn++] = TERM_UMBER;
634 lore_ptr->shoot = true;
637 void display_monster_sometimes(lore_type *lore_ptr)
639 if (lore_ptr->vn <= 0) {
643 hooked_roff(format(_("%^sは", "%^s"), Who::who(lore_ptr->msex)));
644 for (int n = 0; n < lore_ptr->vn; n++) {
646 if (n != lore_ptr->vn - 1) {
647 jverb(lore_ptr->vp[n], lore_ptr->jverb_buf, JVERB_OR);
648 hook_c_roff(lore_ptr->color[n], lore_ptr->jverb_buf);
649 hook_c_roff(lore_ptr->color[n], "り");
652 hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
656 hooked_roff(" may ");
657 } else if (n < lore_ptr->vn - 1) {
663 hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
667 hooked_roff(_("ことがある。", ". "));
670 void display_monster_guardian(lore_type *lore_ptr)
672 bool is_kingpin = (lore_ptr->flags1 & RF1_QUESTOR) != 0;
673 is_kingpin &= lore_ptr->r_ptr->r_sights > 0;
674 is_kingpin &= lore_ptr->r_ptr->max_num > 0;
675 is_kingpin &= (lore_ptr->r_idx == MonsterRaceId::OBERON) || (lore_ptr->r_idx == MonsterRaceId::SERPENT);
677 hook_c_roff(TERM_VIOLET, _("あなたはこのモンスターを殺したいという強い欲望を感じている...", "You feel an intense desire to kill this monster... "));
678 } else if (lore_ptr->flags7 & RF7_GUARDIAN) {
679 hook_c_roff(TERM_L_RED, _("このモンスターはダンジョンの主である。", "This monster is the master of a dungeon."));