OSDN Git Service

Merge pull request #3845 from dis-/feature/refactor-save-floors
[hengbandforosx/hengbandosx.git] / src / lore / monster-lore.cpp
1 /*!
2  * @brief モンスターの思い出表示に必要なフラグ類の処理
3  * @date 2020/06/09
4  * @author Hourier
5  */
6
7 #include "lore/monster-lore.h"
8 #include "game-option/cheat-options.h"
9 #include "lore/lore-calculator.h"
10 #include "lore/lore-util.h"
11 #include "lore/magic-types-setter.h"
12 #include "monster-race/monster-race.h"
13 #include "monster-race/race-flags1.h"
14 #include "monster-race/race-flags2.h"
15 #include "monster-race/race-flags3.h"
16 #include "monster-race/race-indice-types.h"
17 #include "monster-race/race-sex-const.h"
18 #include "player-ability/player-ability-types.h"
19 #include "system/angband.h"
20 #include "system/monster-race-info.h"
21 #include "term/term-color-types.h"
22 #include "view/display-lore-attacks.h"
23 #include "view/display-lore-drops.h"
24 #include "view/display-lore-magics.h"
25 #include "view/display-lore-status.h"
26 #include "view/display-lore.h"
27 #include <algorithm>
28
29 static void set_msex_flags(lore_type *lore_ptr)
30 {
31     lore_ptr->msex = MSEX_NONE;
32     if (is_male(*(lore_ptr->r_ptr))) {
33         lore_ptr->msex = MSEX_MALE;
34     }
35     if (is_female(*(lore_ptr->r_ptr))) {
36         lore_ptr->msex = MSEX_FEMALE;
37     }
38 }
39
40 static void set_flags1(lore_type *lore_ptr)
41 {
42     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
43         lore_ptr->kind_flags.set(MonsterKindType::UNIQUE);
44     }
45
46     if (lore_ptr->r_ptr->flags1 & RF1_QUESTOR) {
47         lore_ptr->flags1 |= (RF1_QUESTOR);
48     }
49
50     if (lore_ptr->r_ptr->flags1 & RF1_FRIENDS) {
51         lore_ptr->flags1 |= (RF1_FRIENDS);
52     }
53
54     if (lore_ptr->r_ptr->flags1 & RF1_ESCORT) {
55         lore_ptr->flags1 |= (RF1_ESCORT);
56     }
57
58     if (lore_ptr->r_ptr->flags1 & RF1_ESCORTS) {
59         lore_ptr->flags1 |= (RF1_ESCORTS);
60     }
61 }
62
63 static void set_race_flags(lore_type *lore_ptr)
64 {
65     if (!lore_ptr->r_ptr->r_tkills && !lore_ptr->know_everything) {
66         return;
67     }
68
69     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::ORC)) {
70         lore_ptr->kind_flags.set(MonsterKindType::ORC);
71     }
72
73     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::TROLL)) {
74         lore_ptr->kind_flags.set(MonsterKindType::TROLL);
75     }
76
77     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::GIANT)) {
78         lore_ptr->kind_flags.set(MonsterKindType::GIANT);
79     }
80
81     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::DRAGON)) {
82         lore_ptr->kind_flags.set(MonsterKindType::DRAGON);
83     }
84
85     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::DEMON)) {
86         lore_ptr->kind_flags.set(MonsterKindType::DEMON);
87     }
88
89     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::UNDEAD)) {
90         lore_ptr->kind_flags.set(MonsterKindType::UNDEAD);
91     }
92
93     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::EVIL)) {
94         lore_ptr->kind_flags.set(MonsterKindType::EVIL);
95     }
96
97     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::GOOD)) {
98         lore_ptr->kind_flags.set(MonsterKindType::GOOD);
99     }
100
101     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::ANIMAL)) {
102         lore_ptr->kind_flags.set(MonsterKindType::ANIMAL);
103     }
104
105     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::AMBERITE)) {
106         lore_ptr->kind_flags.set(MonsterKindType::AMBERITE);
107     }
108
109     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::HUMAN)) {
110         lore_ptr->kind_flags.set(MonsterKindType::HUMAN);
111     }
112
113     if (lore_ptr->r_ptr->kind_flags.has(MonsterKindType::QUANTUM)) {
114         lore_ptr->kind_flags.set(MonsterKindType::QUANTUM);
115     }
116
117     if (lore_ptr->r_ptr->flags1 & RF1_FORCE_DEPTH) {
118         lore_ptr->flags1 |= (RF1_FORCE_DEPTH);
119     }
120
121     if (lore_ptr->r_ptr->flags1 & RF1_FORCE_MAXHP) {
122         lore_ptr->flags1 |= (RF1_FORCE_MAXHP);
123     }
124 }
125
126 /*!
127  * @brief モンスターの思い出情報を表示するメインルーチン
128  * Hack -- display monster information using "hooked_roff()"
129  * @param r_idx モンスターの種族ID
130  * @param mode 表示オプション
131  * @details
132  * This function should only be called with the cursor placed at the
133  * left edge of the screen, on a cleared line, in which the recall is
134  * to take place.  One extra blank line is left after the recall.
135  */
136 void process_monster_lore(PlayerType *player_ptr, MonsterRaceId r_idx, monster_lore_mode mode)
137 {
138     lore_type tmp_lore(r_idx, mode);
139     lore_type *lore_ptr = &tmp_lore;
140
141     auto is_valid_reinforcer = [](const auto &reinforce) {
142         auto [r_idx, dd, ds] = reinforce;
143         auto is_reinforce = MonsterRace(r_idx).is_valid();
144         is_reinforce &= dd > 0;
145         is_reinforce &= ds > 0;
146         return is_reinforce;
147     };
148
149     lore_ptr->reinforce =
150         std::find_if(
151             lore_ptr->r_ptr->reinforces.begin(), lore_ptr->r_ptr->reinforces.end(),
152             is_valid_reinforcer) != lore_ptr->r_ptr->reinforces.end();
153
154     if (cheat_know || (mode == MONSTER_LORE_RESEARCH) || (mode == MONSTER_LORE_DEBUG)) {
155         lore_ptr->know_everything = true;
156     }
157
158     set_flags_for_full_knowledge(lore_ptr);
159     set_msex_flags(lore_ptr);
160     set_flags1(lore_ptr);
161     set_race_flags(lore_ptr);
162     display_kill_numbers(lore_ptr);
163     concptr tmp = lore_ptr->r_ptr->text.data();
164     if (tmp[0]) {
165         hooked_roff(tmp);
166         hooked_roff("\n");
167     }
168
169     if (r_idx == MonsterRaceId::KAGE) {
170         hooked_roff("\n");
171         return;
172     }
173
174     if (!display_where_to_appear(lore_ptr)) {
175         return;
176     }
177
178     display_monster_move(lore_ptr);
179     display_monster_never_move(lore_ptr);
180     if (lore_ptr->old) {
181         hooked_roff(_("。", ".  "));
182         lore_ptr->old = false;
183     }
184
185     display_lore_this(player_ptr, lore_ptr);
186     display_monster_aura(lore_ptr);
187     if (lore_ptr->flags2 & RF2_REFLECTING) {
188         hooked_roff(format(_("%s^は矢の呪文を跳ね返す。", "%s^ reflects bolt spells.  "), Who::who(lore_ptr->msex)));
189     }
190
191     display_monster_collective(lore_ptr);
192     lore_ptr->vn = 0;
193     if (lore_ptr->ability_flags.has(MonsterAbilityType::SHRIEK)) {
194         lore_ptr->vp[lore_ptr->vn] = _("悲鳴で助けを求める", "shriek for help");
195         lore_ptr->color[lore_ptr->vn++] = TERM_L_WHITE;
196     }
197
198     display_monster_launching(player_ptr, lore_ptr);
199     if (lore_ptr->ability_flags.has(MonsterAbilityType::SPECIAL)) {
200         lore_ptr->vp[lore_ptr->vn] = _("特別な行動をする", "do something");
201         lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
202     }
203
204     display_monster_sometimes(lore_ptr);
205     set_breath_types(player_ptr, lore_ptr);
206     display_monster_breath(lore_ptr);
207
208     lore_ptr->vn = 0;
209     set_ball_types(player_ptr, lore_ptr);
210     set_particular_types(player_ptr, lore_ptr);
211     set_bolt_types(player_ptr, lore_ptr);
212     set_status_types(lore_ptr);
213     set_teleport_types(lore_ptr);
214     set_floor_types(player_ptr, lore_ptr);
215     set_summon_types(lore_ptr);
216     display_monster_magic_types(lore_ptr);
217     display_mosnter_magic_possibility(lore_ptr);
218     display_monster_hp_ac(lore_ptr);
219
220     lore_ptr->vn = 0;
221     display_monster_concrete_abilities(lore_ptr);
222     display_monster_abilities(lore_ptr);
223     display_monster_constitutions(lore_ptr);
224
225     lore_ptr->vn = 0;
226     display_monster_concrete_weakness(lore_ptr);
227     display_monster_weakness(lore_ptr);
228
229     lore_ptr->vn = 0;
230     display_monster_concrete_resistances(lore_ptr);
231     display_monster_resistances(lore_ptr);
232     display_monster_evolution(lore_ptr);
233
234     lore_ptr->vn = 0;
235     display_monster_concrete_immunities(lore_ptr);
236     display_monster_immunities(lore_ptr);
237     display_monster_alert(lore_ptr);
238     display_monster_drops(lore_ptr);
239     display_monster_blows(lore_ptr);
240     display_monster_guardian(lore_ptr);
241 }