2 * @brief モンスター情報のアップデート処理
7 #include "monster/monster-update.h"
8 #include "core/disturbance.h"
9 #include "core/player-redraw-types.h"
10 #include "core/player-update-types.h"
11 #include "core/window-redrawer.h"
12 #include "dungeon/dungeon-flag-types.h"
13 #include "dungeon/dungeon.h"
14 #include "floor/cave.h"
15 #include "game-option/birth-options.h"
16 #include "game-option/disturbance-options.h"
17 #include "grid/grid.h"
18 #include "mind/drs-types.h"
19 #include "monster-race/monster-race.h"
20 #include "monster-race/race-flags1.h"
21 #include "monster-race/race-flags2.h"
22 #include "monster-race/race-flags3.h"
23 #include "monster-race/race-flags7.h"
24 #include "monster-race/race-indice-types.h"
25 #include "monster/monster-flag-types.h"
26 #include "monster/monster-info.h"
27 #include "monster/monster-status.h"
28 #include "monster/smart-learn-types.h"
29 #include "player/eldritch-horror.h"
30 #include "player/player-move.h"
31 #include "player/player-status-flags.h"
32 #include "player/special-defense-types.h"
33 #include "status/element-resistance.h"
34 #include "system/floor-type-definition.h"
35 #include "target/projection-path-calculator.h"
38 * @brief 騎乗中のモンスター情報を更新する
39 * @param target_ptr プレーヤーへの参照ポインタ
40 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
41 * @param m_idx モンスターID
42 * @param oy 移動前の、モンスターのY座標
43 * @param ox 移動前の、モンスターのX座標
44 * @param ny 移動後の、モンスターのY座標
45 * @param ox 移動後の、モンスターのX座標
46 * @return アイテム等に影響を及ぼしたらTRUE
48 bool update_riding_monster(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, POSITION ny, POSITION nx)
50 monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
51 grid_type *g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
52 monster_type *y_ptr = &target_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
53 if (turn_flags_ptr->is_riding_mon)
54 return move_player_effect(target_ptr, ny, nx, MPE_DONT_PICKUP);
56 target_ptr->current_floor_ptr->grid_array[oy][ox].m_idx = g_ptr->m_idx;
60 update_monster(target_ptr, g_ptr->m_idx, TRUE);
66 update_monster(target_ptr, m_idx, TRUE);
68 lite_spot(target_ptr, oy, ox);
69 lite_spot(target_ptr, ny, nx);
74 * @brief updateフィールドを更新する
75 * @param target_ptr プレーヤーへの参照ポインタ
76 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
79 void update_player_type(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_race *r_ptr)
81 if (turn_flags_ptr->do_view) {
82 target_ptr->update |= PU_FLOW;
83 target_ptr->window |= PW_OVERHEAD | PW_DUNGEON;
86 if (turn_flags_ptr->do_move
87 && ((r_ptr->flags7 & (RF7_SELF_LD_MASK | RF7_HAS_DARK_1 | RF7_HAS_DARK_2))
88 || ((r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) && !target_ptr->phase_out))) {
89 target_ptr->update |= PU_MON_LITE;
94 * @brief モンスターのフラグを更新する
95 * @param target_ptr プレーヤーへの参照ポインタ
96 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
97 * @param m_ptr モンスターへの参照ポインタ
100 void update_monster_race_flags(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr)
102 monster_race *r_ptr = &r_info[m_ptr->r_idx];
103 if (!is_original_ap_and_seen(target_ptr, m_ptr))
106 if (turn_flags_ptr->did_open_door)
107 r_ptr->r_flags2 |= RF2_OPEN_DOOR;
109 if (turn_flags_ptr->did_bash_door)
110 r_ptr->r_flags2 |= RF2_BASH_DOOR;
112 if (turn_flags_ptr->did_take_item)
113 r_ptr->r_flags2 |= RF2_TAKE_ITEM;
115 if (turn_flags_ptr->did_kill_item)
116 r_ptr->r_flags2 |= RF2_KILL_ITEM;
118 if (turn_flags_ptr->did_move_body)
119 r_ptr->r_flags2 |= RF2_MOVE_BODY;
121 if (turn_flags_ptr->did_pass_wall)
122 r_ptr->r_flags2 |= RF2_PASS_WALL;
124 if (turn_flags_ptr->did_kill_wall)
125 r_ptr->r_flags2 |= RF2_KILL_WALL;
129 * @brief モンスターフラグの更新に基づき、モンスター表示を更新する
130 * @param monster_race_idx モンスターID
131 * @param window ウィンドウフラグ
132 * @param old_race_flags_ptr モンスターフラグへの参照ポインタ
135 void update_player_window(player_type *target_ptr, old_race_flags *old_race_flags_ptr)
138 r_ptr = &r_info[target_ptr->monster_race_idx];
139 if ((old_race_flags_ptr->old_r_flags1 != r_ptr->r_flags1) || (old_race_flags_ptr->old_r_flags2 != r_ptr->r_flags2)
140 || (old_race_flags_ptr->old_r_flags3 != r_ptr->r_flags3) || (old_race_flags_ptr->old_r_flags4 != r_ptr->r_flags4)
141 || (old_race_flags_ptr->old_r_flags5 != r_ptr->r_flags5) || (old_race_flags_ptr->old_r_flags6 != r_ptr->r_flags6)
142 || (old_race_flags_ptr->old_r_flagsr != r_ptr->r_flagsr) || (old_race_flags_ptr->old_r_blows0 != r_ptr->r_blows[0])
143 || (old_race_flags_ptr->old_r_blows1 != r_ptr->r_blows[1]) || (old_race_flags_ptr->old_r_blows2 != r_ptr->r_blows[2])
144 || (old_race_flags_ptr->old_r_blows3 != r_ptr->r_blows[3]) || (old_race_flags_ptr->old_r_cast_spell != r_ptr->r_cast_spell)) {
145 target_ptr->window |= PW_MONSTER;
149 static POSITION decide_updated_distance(player_type *subject_ptr, const bool full, monster_type *m_ptr, const POSITION fy, const POSITION fx)
154 int dy = (subject_ptr->y > fy) ? (subject_ptr->y - fy) : (fy - subject_ptr->y);
155 int dx = (subject_ptr->x > fx) ? (subject_ptr->x - fx) : (fx - subject_ptr->x);
156 POSITION distance = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
163 m_ptr->cdis = distance;
168 * @brief モンスターの各情報を更新する / This function updates the monster record of the given monster
169 * @param m_idx 更新するモンスター情報のID
170 * @param full プレイヤーとの距離更新を行うならばtrue
173 void update_monster(player_type *subject_ptr, MONSTER_IDX m_idx, bool full)
175 monster_type *m_ptr = &subject_ptr->current_floor_ptr->m_list[m_idx];
176 monster_race *r_ptr = &r_info[m_ptr->r_idx];
177 bool do_disturb = disturb_move;
178 POSITION fy = m_ptr->fy;
179 POSITION fx = m_ptr->fx;
182 bool in_darkness = (d_info[subject_ptr->dungeon_idx].flags1 & DF1_DARKNESS) && !subject_ptr->see_nocto;
184 monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
185 if (ap_r_ptr->r_tkills && ap_r_ptr->level >= subject_ptr->lev)
189 POSITION distance = decide_updated_distance(subject_ptr, full, m_ptr, fy, fx);
190 if (m_ptr->mflag2 & MFLAG2_MARK)
193 if (distance <= (in_darkness ? MAX_SIGHT / 2 : MAX_SIGHT)) {
194 if (!in_darkness || (distance <= MAX_SIGHT / 4)) {
195 if (subject_ptr->special_defense & KATA_MUSOU) {
197 if (is_original_ap(m_ptr) && !subject_ptr->image) {
198 if (r_ptr->flags2 & RF2_SMART)
199 r_ptr->r_flags2 |= RF2_SMART;
200 if (r_ptr->flags2 & RF2_STUPID)
201 r_ptr->r_flags2 |= RF2_STUPID;
203 } else if (subject_ptr->telepathy) {
204 if (r_ptr->flags2 & RF2_EMPTY_MIND) {
205 if (is_original_ap(m_ptr) && !subject_ptr->image)
206 r_ptr->r_flags2 |= RF2_EMPTY_MIND;
207 } else if (r_ptr->flags2 & RF2_WEIRD_MIND) {
208 if ((m_idx % 10) == 5) {
210 if (is_original_ap(m_ptr) && !subject_ptr->image) {
211 r_ptr->r_flags2 |= RF2_WEIRD_MIND;
212 if (r_ptr->flags2 & RF2_SMART)
213 r_ptr->r_flags2 |= RF2_SMART;
214 if (r_ptr->flags2 & RF2_STUPID)
215 r_ptr->r_flags2 |= RF2_STUPID;
220 if (is_original_ap(m_ptr) && !subject_ptr->image) {
221 if (r_ptr->flags2 & RF2_SMART)
222 r_ptr->r_flags2 |= RF2_SMART;
223 if (r_ptr->flags2 & RF2_STUPID)
224 r_ptr->r_flags2 |= RF2_STUPID;
229 if ((subject_ptr->esp_animal) && (r_ptr->flags3 & RF3_ANIMAL)) {
231 if (is_original_ap(m_ptr) && !subject_ptr->image)
232 r_ptr->r_flags3 |= RF3_ANIMAL;
235 if ((subject_ptr->esp_undead) && (r_ptr->flags3 & RF3_UNDEAD)) {
237 if (is_original_ap(m_ptr) && !subject_ptr->image)
238 r_ptr->r_flags3 |= RF3_UNDEAD;
241 if ((subject_ptr->esp_demon) && (r_ptr->flags3 & RF3_DEMON)) {
243 if (is_original_ap(m_ptr) && !subject_ptr->image)
244 r_ptr->r_flags3 |= RF3_DEMON;
247 if ((subject_ptr->esp_orc) && (r_ptr->flags3 & RF3_ORC)) {
249 if (is_original_ap(m_ptr) && !subject_ptr->image)
250 r_ptr->r_flags3 |= RF3_ORC;
253 if ((subject_ptr->esp_troll) && (r_ptr->flags3 & RF3_TROLL)) {
255 if (is_original_ap(m_ptr) && !subject_ptr->image)
256 r_ptr->r_flags3 |= RF3_TROLL;
259 if ((subject_ptr->esp_giant) && (r_ptr->flags3 & RF3_GIANT)) {
261 if (is_original_ap(m_ptr) && !subject_ptr->image)
262 r_ptr->r_flags3 |= RF3_GIANT;
265 if ((subject_ptr->esp_dragon) && (r_ptr->flags3 & RF3_DRAGON)) {
267 if (is_original_ap(m_ptr) && !subject_ptr->image)
268 r_ptr->r_flags3 |= RF3_DRAGON;
271 if ((subject_ptr->esp_human) && (r_ptr->flags2 & RF2_HUMAN)) {
273 if (is_original_ap(m_ptr) && !subject_ptr->image)
274 r_ptr->r_flags2 |= RF2_HUMAN;
277 if ((subject_ptr->esp_evil) && (r_ptr->flags3 & RF3_EVIL)) {
279 if (is_original_ap(m_ptr) && !subject_ptr->image)
280 r_ptr->r_flags3 |= RF3_EVIL;
283 if ((subject_ptr->esp_good) && (r_ptr->flags3 & RF3_GOOD)) {
285 if (is_original_ap(m_ptr) && !subject_ptr->image)
286 r_ptr->r_flags3 |= RF3_GOOD;
289 if ((subject_ptr->esp_nonliving) && ((r_ptr->flags3 & (RF3_DEMON | RF3_UNDEAD | RF3_NONLIVING)) == RF3_NONLIVING)) {
291 if (is_original_ap(m_ptr) && !subject_ptr->image)
292 r_ptr->r_flags3 |= RF3_NONLIVING;
295 if ((subject_ptr->esp_unique) && (r_ptr->flags1 & (RF1_UNIQUE))) {
297 if (is_original_ap(m_ptr) && !subject_ptr->image)
298 r_ptr->r_flags1 |= RF1_UNIQUE;
302 if (player_has_los_bold(subject_ptr, fy, fx) && !subject_ptr->blind) {
303 bool do_invisible = FALSE;
304 bool do_cold_blood = FALSE;
305 if (subject_ptr->concent >= CONCENT_RADAR_THRESHOLD)
308 if (distance <= subject_ptr->see_infra)
309 if ((r_ptr->flags2 & (RF2_COLD_BLOOD | RF2_AURA_FIRE)) == RF2_COLD_BLOOD) {
310 do_cold_blood = TRUE;
316 if (player_can_see_bold(subject_ptr, fy, fx))
317 if (r_ptr->flags2 & RF2_INVISIBLE) {
319 if (subject_ptr->see_inv)
324 if (flag && is_original_ap(m_ptr) && !subject_ptr->image) {
326 r_ptr->r_flags2 |= RF2_INVISIBLE;
329 r_ptr->r_flags2 |= RF2_COLD_BLOOD;
334 /* The monster is now visible */
338 lite_spot(subject_ptr, fy, fx);
340 if (subject_ptr->health_who == m_idx)
341 subject_ptr->redraw |= PR_HEALTH;
343 if (subject_ptr->riding == m_idx)
344 subject_ptr->redraw |= PR_UHEALTH;
346 if (!subject_ptr->image) {
347 if ((m_ptr->ap_r_idx == MON_KAGE) && (r_info[MON_KAGE].r_sights < MAX_SHORT))
348 r_info[MON_KAGE].r_sights++;
349 else if (is_original_ap(m_ptr) && (r_ptr->r_sights < MAX_SHORT))
353 if (r_info[m_ptr->ap_r_idx].flags2 & RF2_ELDRITCH_HORROR)
354 sanity_blast(subject_ptr, m_ptr, FALSE);
357 && (projectable(subject_ptr, m_ptr->fy, m_ptr->fx, subject_ptr->y, subject_ptr->x)
358 && projectable(subject_ptr, subject_ptr->y, subject_ptr->x, m_ptr->fy, m_ptr->fx))) {
359 if (disturb_pets || is_hostile(m_ptr))
360 disturb(subject_ptr, TRUE, TRUE);
365 /* The monster is not visible */
369 lite_spot(subject_ptr, fy, fx);
371 if (subject_ptr->health_who == m_idx)
372 subject_ptr->redraw |= PR_HEALTH;
373 if (subject_ptr->riding == m_idx)
374 subject_ptr->redraw |= PR_UHEALTH;
376 if (disturb_pets || is_hostile(m_ptr))
377 disturb(subject_ptr, TRUE, TRUE);
382 /* The monster is now easily visible */
384 if (!(m_ptr->mflag & MFLAG_VIEW)) {
385 m_ptr->mflag |= MFLAG_VIEW;
386 if (do_disturb && (disturb_pets || is_hostile(m_ptr)))
387 disturb(subject_ptr, TRUE, TRUE);
393 /* The monster is not easily visible */
395 if (!(m_ptr->mflag & MFLAG_VIEW))
398 /* Mark as not easily visible */
399 m_ptr->mflag &= ~(MFLAG_VIEW);
402 if (disturb_pets || is_hostile(m_ptr))
403 disturb(subject_ptr, TRUE, TRUE);
408 * @param player_ptr プレーヤーへの参照ポインタ
409 * @brief 単純に生存している全モンスターの更新処理を行う / This function simply updates all the (non-dead) monsters (see above).
410 * @param full 距離更新を行うならtrue
413 void update_monsters(player_type *player_ptr, bool full)
415 floor_type *floor_ptr = player_ptr->current_floor_ptr;
416 for (MONSTER_IDX i = 1; i < floor_ptr->m_max; i++) {
417 monster_type *m_ptr = &floor_ptr->m_list[i];
418 if (!monster_is_valid(m_ptr))
420 update_monster(player_ptr, i, full);
425 * @brief SMART(適格に攻撃を行う)モンスターの学習状況を更新する / Learn about an "observed" resistance.
426 * @param m_idx 更新を行う「モンスター情報ID
430 void update_smart_learn(player_type *player_ptr, MONSTER_IDX m_idx, int what)
432 monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
433 monster_race *r_ptr = &r_info[m_ptr->r_idx];
435 if (!smart_learn || ((r_ptr->flags2 & RF2_STUPID) != 0) || (((r_ptr->flags2 & RF2_SMART) == 0) && (randint0(100) < 50)))
440 if (player_ptr->resist_acid)
441 m_ptr->smart |= SM_RES_ACID;
443 if (is_oppose_acid(player_ptr))
444 m_ptr->smart |= SM_OPP_ACID;
446 if (is_immune_acid(player_ptr))
447 m_ptr->smart |= SM_IMM_ACID;
451 if (player_ptr->resist_elec)
452 m_ptr->smart |= SM_RES_ELEC;
454 if (is_oppose_elec(player_ptr))
455 m_ptr->smart |= SM_OPP_ELEC;
457 if (is_immune_elec(player_ptr))
458 m_ptr->smart |= SM_IMM_ELEC;
462 if (player_ptr->resist_fire)
463 m_ptr->smart |= SM_RES_FIRE;
465 if (is_oppose_fire(player_ptr))
466 m_ptr->smart |= SM_OPP_FIRE;
468 if (is_immune_fire(player_ptr))
469 m_ptr->smart |= SM_IMM_FIRE;
473 if (player_ptr->resist_cold)
474 m_ptr->smart |= SM_RES_COLD;
476 if (is_oppose_cold(player_ptr))
477 m_ptr->smart |= SM_OPP_COLD;
479 if (is_immune_cold(player_ptr))
480 m_ptr->smart |= SM_IMM_COLD;
484 if (player_ptr->resist_pois)
485 m_ptr->smart |= SM_RES_POIS;
487 if (is_oppose_pois(player_ptr))
488 m_ptr->smart |= SM_OPP_POIS;
492 if (player_ptr->resist_neth)
493 m_ptr->smart |= SM_RES_NETH;
497 if (player_ptr->resist_lite)
498 m_ptr->smart |= SM_RES_LITE;
502 if (player_ptr->resist_dark)
503 m_ptr->smart |= SM_RES_DARK;
507 if (player_ptr->resist_fear)
508 m_ptr->smart |= SM_RES_FEAR;
512 if (player_ptr->resist_conf)
513 m_ptr->smart |= SM_RES_CONF;
517 if (player_ptr->resist_chaos)
518 m_ptr->smart |= SM_RES_CHAOS;
522 if (player_ptr->resist_disen)
523 m_ptr->smart |= SM_RES_DISEN;
527 if (player_ptr->resist_blind)
528 m_ptr->smart |= SM_RES_BLIND;
532 if (player_ptr->resist_nexus)
533 m_ptr->smart |= SM_RES_NEXUS;
537 if (player_ptr->resist_sound)
538 m_ptr->smart |= SM_RES_SOUND;
542 if (player_ptr->resist_shard)
543 m_ptr->smart |= SM_RES_SHARD;
547 if (player_ptr->free_act)
548 m_ptr->smart |= SM_IMM_FREE;
552 if (!player_ptr->msp)
553 m_ptr->smart |= SM_IMM_MANA;
557 if (player_ptr->reflect)
558 m_ptr->smart |= SM_IMM_REFLECT;