OSDN Git Service

[Refactor] #40514 player_type の pass_wall 変数を廃止. / Abolished pass_wall variable in...
[hengband/hengband.git] / src / monster / monster-info.c
1 /*!
2  * @brief モンスター情報の記述 / describe monsters (using monster memory)
3  * @date 2013/12/11
4  * @author
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
6  * This software may be copied and distributed for educational, research,
7  * and not for profit purposes provided that this copyright and statement
8  * are included in all such copies.  Other copyrights may also apply.
9  * 2014 Deskull rearranged comment for Doxygen.
10  */
11
12 #include "monster/monster-info.h"
13 #include "floor/cave.h"
14 #include "floor/wild.h"
15 #include "grid/feature.h"
16 #include "grid/grid.h"
17 #include "monster-race/monster-race.h"
18 #include "monster-race/race-flags-resistance.h"
19 #include "monster-race/race-flags1.h"
20 #include "monster-race/race-flags2.h"
21 #include "monster-race/race-flags3.h"
22 #include "monster-race/race-flags7.h"
23 #include "monster-race/race-flags8.h"
24 #include "monster-race/race-indice-types.h"
25 #include "monster/monster-describer.h"
26 #include "monster/monster-flag-types.h"
27 #include "monster/smart-learn-types.h"
28 #include "system/floor-type-definition.h"
29 #include "util/bit-flags-calculator.h"
30 #include "player/player-status-flags.h"
31
32 /*!
33  * @brief モンスターを友好的にする
34  * @param m_ptr モンスター情報構造体の参照ポインタ
35  * @return なし
36  */
37 void set_friendly(monster_type *m_ptr) { m_ptr->smart |= SM_FRIENDLY; }
38
39 /*!
40  * @brief モンスターが地形を踏破できるかどうかを返す
41  * Check if monster can cross terrain
42  * @param player_ptr プレーヤーへの参照ポインタ
43  * @param feat 地形ID
44  * @param r_ptr モンスター種族構造体の参照ポインタ
45  * @param mode オプション
46  * @return 踏破可能ならばTRUEを返す
47  */
48 bool monster_can_cross_terrain(player_type *player_ptr, FEAT_IDX feat, monster_race *r_ptr, BIT_FLAGS16 mode)
49 {
50     feature_type *f_ptr = &f_info[feat];
51
52     if (has_flag(f_ptr->flags, FF_PATTERN)) {
53         if (!(mode & CEM_RIDING)) {
54             if (!(r_ptr->flags7 & RF7_CAN_FLY))
55                 return FALSE;
56         } else {
57             if (!(mode & CEM_P_CAN_ENTER_PATTERN))
58                 return FALSE;
59         }
60     }
61
62     if (has_flag(f_ptr->flags, FF_CAN_FLY) && (r_ptr->flags7 & RF7_CAN_FLY))
63         return TRUE;
64     if (has_flag(f_ptr->flags, FF_CAN_SWIM) && (r_ptr->flags7 & RF7_CAN_SWIM))
65         return TRUE;
66     if (has_flag(f_ptr->flags, FF_CAN_PASS)) {
67         if ((r_ptr->flags2 & RF2_PASS_WALL) && (!(mode & CEM_RIDING) || has_pass_wall(player_ptr)))
68             return TRUE;
69     }
70
71     if (!has_flag(f_ptr->flags, FF_MOVE))
72         return FALSE;
73
74     if (has_flag(f_ptr->flags, FF_MOUNTAIN) && (r_ptr->flags8 & RF8_WILD_MOUNTAIN))
75         return TRUE;
76
77     if (has_flag(f_ptr->flags, FF_WATER)) {
78         if (!(r_ptr->flags7 & RF7_AQUATIC)) {
79             if (has_flag(f_ptr->flags, FF_DEEP))
80                 return FALSE;
81             else if (r_ptr->flags2 & RF2_AURA_FIRE)
82                 return FALSE;
83         }
84     } else if (r_ptr->flags7 & RF7_AQUATIC)
85         return FALSE;
86
87     if (has_flag(f_ptr->flags, FF_LAVA)) {
88         if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK))
89             return FALSE;
90     }
91
92     if (has_flag(f_ptr->flags, FF_COLD_PUDDLE)) {
93         if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK))
94             return FALSE;
95     }
96
97     if (has_flag(f_ptr->flags, FF_ELEC_PUDDLE)) {
98         if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK))
99             return FALSE;
100     }
101
102     if (has_flag(f_ptr->flags, FF_ACID_PUDDLE)) {
103         if (!(r_ptr->flagsr & RFR_EFF_IM_ACID_MASK))
104             return FALSE;
105     }
106
107     if (has_flag(f_ptr->flags, FF_POISON_PUDDLE)) {
108         if (!(r_ptr->flagsr & RFR_EFF_IM_POIS_MASK))
109             return FALSE;
110     }
111
112     return TRUE;
113 }
114
115 /*!
116  * @brief 指定された座標の地形をモンスターが踏破できるかどうかを返す
117  * Strictly check if monster can enter the grid
118  * @param player_ptr プレーヤーへの参照ポインタ
119  * @param y 地形のY座標
120  * @param x 地形のX座標
121  * @param r_ptr モンスター種族構造体の参照ポインタ
122  * @param mode オプション
123  * @return 踏破可能ならばTRUEを返す
124  */
125 bool monster_can_enter(player_type *player_ptr, POSITION y, POSITION x, monster_race *r_ptr, BIT_FLAGS16 mode)
126 {
127     grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
128     if (player_bold(player_ptr, y, x))
129         return FALSE;
130     if (g_ptr->m_idx)
131         return FALSE;
132
133     return monster_can_cross_terrain(player_ptr, g_ptr->feat, r_ptr, mode);
134 }
135
136 /*!
137  * @brief モンスターの属性の基づいた敵対関係の有無を返す(サブルーチン)
138  * Check if this monster has "hostile" alignment (aux)
139  * @param sub_align1 モンスター1のサブフラグ
140  * @param sub_align2 モンスター2のサブフラグ
141  * @return 敵対関係にあるならばTRUEを返す
142  */
143 static bool check_hostile_align(byte sub_align1, byte sub_align2)
144 {
145     if (sub_align1 != sub_align2) {
146         if (((sub_align1 & SUB_ALIGN_EVIL) && (sub_align2 & SUB_ALIGN_GOOD)) || ((sub_align1 & SUB_ALIGN_GOOD) && (sub_align2 & SUB_ALIGN_EVIL)))
147             return TRUE;
148     }
149
150     return FALSE;
151 }
152
153 /*!
154  * @brief モンスターの属性の基づいた敵対関係の有無を返す
155  * Check if two monsters are enemies
156  * @param m_ptr モンスター1の構造体参照ポインタ
157  * @param n_ptr モンスター2の構造体参照ポインタ
158  * @return 敵対関係にあるならばTRUEを返す
159  */
160 bool are_enemies(player_type *player_ptr, monster_type *m_ptr, monster_type *n_ptr)
161 {
162     monster_race *r_ptr = &r_info[m_ptr->r_idx];
163     monster_race *s_ptr = &r_info[n_ptr->r_idx];
164
165     if (player_ptr->phase_out) {
166         if (is_pet(m_ptr) || is_pet(n_ptr))
167             return FALSE;
168         return TRUE;
169     }
170
171     if ((r_ptr->flags8 & (RF8_WILD_TOWN | RF8_WILD_ALL)) && (s_ptr->flags8 & (RF8_WILD_TOWN | RF8_WILD_ALL))) {
172         if (!is_pet(m_ptr) && !is_pet(n_ptr))
173             return FALSE;
174     }
175
176     if (check_hostile_align(m_ptr->sub_align, n_ptr->sub_align)) {
177         if (!(m_ptr->mflag2 & MFLAG2_CHAMELEON) || !(n_ptr->mflag2 & MFLAG2_CHAMELEON))
178             return TRUE;
179     }
180
181     if (is_hostile(m_ptr) != is_hostile(n_ptr)) {
182         return TRUE;
183     }
184
185     return FALSE;
186 }
187
188 /*!
189  * @brief モンスターがプレイヤーに対して敵意を抱くかどうかを返す
190  * Check if this monster race has "hostile" alignment
191  * @param player_ptr プレーヤーへの参照ポインタ
192  * @param m_ptr モンスター情報構造体の参照ポインタ
193  * @param pa_good プレイヤーの善傾向値
194  * @param pa_evil プレイヤーの悪傾向値
195  * @param r_ptr モンスター種族情報の構造体参照ポインタ
196  * @return プレイヤーに敵意を持つならばTRUEを返す
197  * @details
198  * If user is player, m_ptr == NULL.
199  */
200 bool monster_has_hostile_align(player_type *player_ptr, monster_type *m_ptr, int pa_good, int pa_evil, monster_race *r_ptr)
201 {
202     byte sub_align1 = SUB_ALIGN_NEUTRAL;
203     byte sub_align2 = SUB_ALIGN_NEUTRAL;
204
205     if (m_ptr) /* For a monster */
206     {
207         sub_align1 = m_ptr->sub_align;
208     } else /* For player */
209     {
210         if (player_ptr->align >= pa_good)
211             sub_align1 |= SUB_ALIGN_GOOD;
212         if (player_ptr->align <= pa_evil)
213             sub_align1 |= SUB_ALIGN_EVIL;
214     }
215
216     /* Racial alignment flags */
217     if (r_ptr->flags3 & RF3_EVIL)
218         sub_align2 |= SUB_ALIGN_EVIL;
219     if (r_ptr->flags3 & RF3_GOOD)
220         sub_align2 |= SUB_ALIGN_GOOD;
221
222     if (check_hostile_align(sub_align1, sub_align2))
223         return TRUE;
224
225     return FALSE;
226 }
227
228 bool is_original_ap_and_seen(player_type *player_ptr, monster_type *m_ptr) { return m_ptr->ml && !player_ptr->image && (m_ptr->ap_r_idx == m_ptr->r_idx); }
229
230 /*  Determine monster race appearance index is same as race index */
231 bool is_original_ap(monster_type *m_ptr) { return m_ptr->ap_r_idx == m_ptr->r_idx; }
232
233 bool is_friendly(monster_type *m_ptr) { return (m_ptr->smart & SM_FRIENDLY) != 0; }
234
235 bool is_pet(monster_type *m_ptr) { return (m_ptr->smart & SM_PET) != 0; }
236
237 bool is_hostile(monster_type *m_ptr) { return !is_friendly(m_ptr) && !is_pet(m_ptr); }
238
239 /*!
240  * @brief モンスターの真の種族を返す / Extract monster race pointer of a monster's true form
241  * @param m_ptr モンスターの参照ポインタ
242  * @return 本当のモンスター種族参照ポインタ
243  */
244 monster_race *real_r_ptr(monster_type *m_ptr) { return &r_info[real_r_idx(m_ptr)]; }
245
246 MONRACE_IDX real_r_idx(monster_type *m_ptr)
247 {
248     monster_race *r_ptr = &r_info[m_ptr->r_idx];
249     if (m_ptr->mflag2 & MFLAG2_CHAMELEON) {
250         if (r_ptr->flags1 & RF1_UNIQUE)
251             return MON_CHAMELEON_K;
252         else
253             return MON_CHAMELEON;
254     }
255
256     return m_ptr->r_idx;
257 }
258
259 /*!
260  * @brief モンスターIDを取り、モンスター名をm_nameに代入する /
261  * @param player_ptr プレーヤーへの参照ポインタ
262  * @param m_idx モンスターID
263  * @param m_name モンスター名を入力する配列
264  */
265 void monster_name(player_type *player_ptr, MONSTER_IDX m_idx, char *m_name)
266 {
267     monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
268     monster_desc(player_ptr, m_name, m_ptr, 0x00);
269 }