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/player-move.h"
30 #include "player/player-status-flags.h"
31 #include "player/special-defense-types.h"
32 #include "status/element-resistance.h"
33 #include "system/floor-type-definition.h"
34 #include "target/projection-path-calculator.h"
35 #include "util/bit-flags-calculator.h"
36 #include "world/world.h"
39 typedef struct um_type {
51 * @brief 騎乗中のモンスター情報を更新する
52 * @param target_ptr プレーヤーへの参照ポインタ
53 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
54 * @param m_idx モンスターID
55 * @param oy 移動前の、モンスターのY座標
56 * @param ox 移動前の、モンスターのX座標
57 * @param ny 移動後の、モンスターのY座標
58 * @param ox 移動後の、モンスターのX座標
59 * @return アイテム等に影響を及ぼしたらTRUE
61 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)
63 monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
64 grid_type *g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
65 monster_type *y_ptr = &target_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
66 if (turn_flags_ptr->is_riding_mon)
67 return move_player_effect(target_ptr, ny, nx, MPE_DONT_PICKUP);
69 target_ptr->current_floor_ptr->grid_array[oy][ox].m_idx = g_ptr->m_idx;
73 update_monster(target_ptr, g_ptr->m_idx, TRUE);
79 update_monster(target_ptr, m_idx, TRUE);
81 lite_spot(target_ptr, oy, ox);
82 lite_spot(target_ptr, ny, nx);
87 * @brief updateフィールドを更新する
88 * @param target_ptr プレーヤーへの参照ポインタ
89 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
92 void update_player_type(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_race *r_ptr)
94 if (turn_flags_ptr->do_view) {
95 target_ptr->update |= PU_FLOW;
96 target_ptr->window_flags |= PW_OVERHEAD | PW_DUNGEON;
99 if (turn_flags_ptr->do_move
100 && ((r_ptr->flags7 & (RF7_SELF_LD_MASK | RF7_HAS_DARK_1 | RF7_HAS_DARK_2))
101 || ((r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) && !target_ptr->phase_out))) {
102 target_ptr->update |= PU_MON_LITE;
107 * @brief モンスターのフラグを更新する
108 * @param target_ptr プレーヤーへの参照ポインタ
109 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
110 * @param m_ptr モンスターへの参照ポインタ
113 void update_monster_race_flags(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr)
115 monster_race *r_ptr = &r_info[m_ptr->r_idx];
116 if (!is_original_ap_and_seen(target_ptr, m_ptr))
119 if (turn_flags_ptr->did_open_door)
120 r_ptr->r_flags2 |= RF2_OPEN_DOOR;
122 if (turn_flags_ptr->did_bash_door)
123 r_ptr->r_flags2 |= RF2_BASH_DOOR;
125 if (turn_flags_ptr->did_take_item)
126 r_ptr->r_flags2 |= RF2_TAKE_ITEM;
128 if (turn_flags_ptr->did_kill_item)
129 r_ptr->r_flags2 |= RF2_KILL_ITEM;
131 if (turn_flags_ptr->did_move_body)
132 r_ptr->r_flags2 |= RF2_MOVE_BODY;
134 if (turn_flags_ptr->did_pass_wall)
135 r_ptr->r_flags2 |= RF2_PASS_WALL;
137 if (turn_flags_ptr->did_kill_wall)
138 r_ptr->r_flags2 |= RF2_KILL_WALL;
142 * @brief モンスターフラグの更新に基づき、モンスター表示を更新する
143 * @param monster_race_idx モンスターID
144 * @param window ウィンドウフラグ
145 * @param old_race_flags_ptr モンスターフラグへの参照ポインタ
148 void update_player_window(player_type *target_ptr, old_race_flags *old_race_flags_ptr)
151 r_ptr = &r_info[target_ptr->monster_race_idx];
152 if ((old_race_flags_ptr->old_r_flags1 != r_ptr->r_flags1) || (old_race_flags_ptr->old_r_flags2 != r_ptr->r_flags2)
153 || (old_race_flags_ptr->old_r_flags3 != r_ptr->r_flags3) || (old_race_flags_ptr->old_r_flags4 != r_ptr->r_flags4)
154 || (old_race_flags_ptr->old_r_flags5 != r_ptr->r_flags5) || (old_race_flags_ptr->old_r_flags6 != r_ptr->r_flags6)
155 || (old_race_flags_ptr->old_r_flagsr != r_ptr->r_flagsr) || (old_race_flags_ptr->old_r_blows0 != r_ptr->r_blows[0])
156 || (old_race_flags_ptr->old_r_blows1 != r_ptr->r_blows[1]) || (old_race_flags_ptr->old_r_blows2 != r_ptr->r_blows[2])
157 || (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)) {
158 target_ptr->window_flags |= PW_MONSTER;
162 static um_type *initialize_um_type(player_type *subject_ptr, um_type *um_ptr, MONSTER_IDX m_idx, bool full)
164 um_ptr->m_ptr = &subject_ptr->current_floor_ptr->m_list[m_idx];
165 um_ptr->do_disturb = disturb_move;
166 um_ptr->fy = um_ptr->m_ptr->fy;
167 um_ptr->fx = um_ptr->m_ptr->fx;
168 um_ptr->flag = FALSE;
169 um_ptr->easy = FALSE;
170 um_ptr->in_darkness = (d_info[subject_ptr->dungeon_idx].flags1 & DF1_DARKNESS) && !subject_ptr->see_nocto;
175 static POSITION decide_updated_distance(player_type *subject_ptr, um_type *um_ptr)
178 return um_ptr->m_ptr->cdis;
180 int dy = (subject_ptr->y > um_ptr->fy) ? (subject_ptr->y - um_ptr->fy) : (um_ptr->fy - subject_ptr->y);
181 int dx = (subject_ptr->x > um_ptr->fx) ? (subject_ptr->x - um_ptr->fx) : (um_ptr->fx - subject_ptr->x);
182 POSITION distance = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
189 um_ptr->m_ptr->cdis = distance;
193 static void update_smart_stupid_flags(monster_race *r_ptr)
195 if (r_ptr->flags2 & RF2_SMART)
196 r_ptr->r_flags2 |= RF2_SMART;
198 if (r_ptr->flags2 & RF2_STUPID)
199 r_ptr->r_flags2 |= RF2_STUPID;
203 * @brief WEIRD_MINDフラグ持ちのモンスターを1/10の確率でテレパシーに引っかける
204 * @param subject_ptr プレーヤーへの参照ポインタ
205 * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
206 * @param m_idx モンスターID
207 * @return WEIRD_MINDフラグがあるならTRUE
209 static bool update_weird_telepathy(player_type *subject_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
211 monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
212 if ((r_ptr->flags2 & RF2_WEIRD_MIND) == 0)
215 if ((m_idx % 10) != (current_world_ptr->game_turn % 10))
219 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
220 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image) {
221 r_ptr->r_flags2 |= RF2_WEIRD_MIND;
222 update_smart_stupid_flags(r_ptr);
228 static void update_telepathy_sight(player_type *subject_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
230 monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
231 if (subject_ptr->special_defense & KATA_MUSOU) {
233 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
234 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
235 update_smart_stupid_flags(r_ptr);
240 if (!subject_ptr->telepathy)
243 if (r_ptr->flags2 & RF2_EMPTY_MIND) {
244 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
245 r_ptr->r_flags2 |= RF2_EMPTY_MIND;
250 if (update_weird_telepathy(subject_ptr, um_ptr, m_idx))
254 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
255 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
256 update_smart_stupid_flags(r_ptr);
259 static void update_specific_race_telepathy(player_type *subject_ptr, um_type *um_ptr)
261 monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
262 if ((subject_ptr->esp_animal) && (r_ptr->flags3 & RF3_ANIMAL)) {
264 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
265 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
266 r_ptr->r_flags3 |= RF3_ANIMAL;
269 if ((subject_ptr->esp_undead) && (r_ptr->flags3 & RF3_UNDEAD)) {
271 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
272 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
273 r_ptr->r_flags3 |= RF3_UNDEAD;
276 if ((subject_ptr->esp_demon) && (r_ptr->flags3 & RF3_DEMON)) {
278 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
279 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
280 r_ptr->r_flags3 |= RF3_DEMON;
283 if ((subject_ptr->esp_orc) && (r_ptr->flags3 & RF3_ORC)) {
285 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
286 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
287 r_ptr->r_flags3 |= RF3_ORC;
290 if ((subject_ptr->esp_troll) && (r_ptr->flags3 & RF3_TROLL)) {
292 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
293 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
294 r_ptr->r_flags3 |= RF3_TROLL;
297 if ((subject_ptr->esp_giant) && (r_ptr->flags3 & RF3_GIANT)) {
299 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
300 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
301 r_ptr->r_flags3 |= RF3_GIANT;
304 if ((subject_ptr->esp_dragon) && (r_ptr->flags3 & RF3_DRAGON)) {
306 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
307 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
308 r_ptr->r_flags3 |= RF3_DRAGON;
311 if ((subject_ptr->esp_human) && (r_ptr->flags2 & RF2_HUMAN)) {
313 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
314 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
315 r_ptr->r_flags2 |= RF2_HUMAN;
318 if ((subject_ptr->esp_evil) && (r_ptr->flags3 & RF3_EVIL)) {
320 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
321 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
322 r_ptr->r_flags3 |= RF3_EVIL;
325 if ((subject_ptr->esp_good) && (r_ptr->flags3 & RF3_GOOD)) {
327 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
328 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
329 r_ptr->r_flags3 |= RF3_GOOD;
332 if ((subject_ptr->esp_nonliving) && ((r_ptr->flags3 & (RF3_DEMON | RF3_UNDEAD | RF3_NONLIVING)) == RF3_NONLIVING)) {
334 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
335 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
336 r_ptr->r_flags3 |= RF3_NONLIVING;
339 if ((subject_ptr->esp_unique) && (r_ptr->flags1 & RF1_UNIQUE)) {
341 um_ptr->m_ptr->mflag.set(MFLAG::ESP);
342 if (is_original_ap(um_ptr->m_ptr) && !subject_ptr->image)
343 r_ptr->r_flags1 |= RF1_UNIQUE;
347 static bool check_cold_blood(player_type *subject_ptr, um_type *um_ptr, const POSITION distance)
349 if (distance > subject_ptr->see_infra)
352 monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
353 if ((r_ptr->flags2 & (RF2_COLD_BLOOD | RF2_AURA_FIRE)) == RF2_COLD_BLOOD)
361 static bool check_invisible(player_type *subject_ptr, um_type *um_ptr)
363 if (!player_can_see_bold(subject_ptr, um_ptr->fy, um_ptr->fx))
366 monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
367 if (r_ptr->flags2 & RF2_INVISIBLE) {
368 if (subject_ptr->see_inv) {
381 * @brief テレパシー・赤外線視力・可視透明によってモンスターを感知できるかどうかの判定
382 * @param subject_ptr プレーヤーへの参照ポインタ
383 * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
386 static void decide_sight_invisible_monster(player_type *subject_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
388 POSITION distance = decide_updated_distance(subject_ptr, um_ptr);
389 monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
391 um_ptr->m_ptr->mflag.reset(MFLAG::ESP);
393 if (distance > (um_ptr->in_darkness ? MAX_SIGHT / 2 : MAX_SIGHT))
396 if (!um_ptr->in_darkness || (distance <= MAX_SIGHT / 4)) {
397 update_telepathy_sight(subject_ptr, um_ptr, m_idx);
398 update_specific_race_telepathy(subject_ptr, um_ptr);
401 if (!player_has_los_bold(subject_ptr, um_ptr->fy, um_ptr->fx) || subject_ptr->blind)
404 if (subject_ptr->concent >= CONCENT_RADAR_THRESHOLD) {
409 bool do_cold_blood = check_cold_blood(subject_ptr, um_ptr, distance);
410 bool do_invisible = check_invisible(subject_ptr, um_ptr);
411 if (!um_ptr->flag || !is_original_ap(um_ptr->m_ptr) || subject_ptr->image)
415 r_ptr->r_flags2 |= RF2_INVISIBLE;
418 r_ptr->r_flags2 |= RF2_COLD_BLOOD;
422 * @brief 壁の向こうにいるモンスターへのテレパシー・赤外線視力による冷血動物以外の透明モンスター・可視透明能力による透明モンスター
424 * @param subject_ptr プレーヤーへの参照ポインタ
425 * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
426 * @param m_idx フロアのモンスター番号
428 * @details 感知した結果、エルドリッチホラー持ちがいたら精神を破壊する
430 static void update_invisible_monster(player_type *subject_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
432 if (um_ptr->m_ptr->ml)
435 um_ptr->m_ptr->ml = TRUE;
436 lite_spot(subject_ptr, um_ptr->fy, um_ptr->fx);
438 if (subject_ptr->health_who == m_idx)
439 subject_ptr->redraw |= PR_HEALTH;
441 if (subject_ptr->riding == m_idx)
442 subject_ptr->redraw |= PR_UHEALTH;
444 if (!subject_ptr->image) {
445 monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
446 if ((um_ptr->m_ptr->ap_r_idx == MON_KAGE) && (r_info[MON_KAGE].r_sights < MAX_SHORT))
447 r_info[MON_KAGE].r_sights++;
448 else if (is_original_ap(um_ptr->m_ptr) && (r_ptr->r_sights < MAX_SHORT))
452 if (current_world_ptr->is_loading_now && current_world_ptr->character_dungeon && !subject_ptr->phase_out
453 && r_info[um_ptr->m_ptr->ap_r_idx].flags2 & RF2_ELDRITCH_HORROR)
454 um_ptr->m_ptr->mflag.set(MFLAG::SANITY_BLAST);
457 && (projectable(subject_ptr, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx, subject_ptr->y, subject_ptr->x)
458 && projectable(subject_ptr, subject_ptr->y, subject_ptr->x, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx))) {
459 if (disturb_pets || is_hostile(um_ptr->m_ptr))
460 disturb(subject_ptr, TRUE, TRUE);
464 static void update_visible_monster(player_type *subject_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
466 if (!um_ptr->m_ptr->ml)
469 um_ptr->m_ptr->ml = FALSE;
470 lite_spot(subject_ptr, um_ptr->fy, um_ptr->fx);
472 if (subject_ptr->health_who == m_idx)
473 subject_ptr->redraw |= PR_HEALTH;
475 if (subject_ptr->riding == m_idx)
476 subject_ptr->redraw |= PR_UHEALTH;
478 if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
479 disturb(subject_ptr, TRUE, TRUE);
482 static bool update_clear_monster(player_type *subject_ptr, um_type *um_ptr)
487 if (um_ptr->m_ptr->mflag.has_not(MFLAG::VIEW)) {
488 um_ptr->m_ptr->mflag.set(MFLAG::VIEW);
489 if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
490 disturb(subject_ptr, TRUE, TRUE);
497 * @brief モンスターの各情報を更新する / This function updates the monster record of the given monster
498 * @param m_idx 更新するモンスター情報のID
499 * @param full プレイヤーとの距離更新を行うならばtrue
502 void update_monster(player_type *subject_ptr, MONSTER_IDX m_idx, bool full)
505 um_type *um_ptr = initialize_um_type(subject_ptr, &tmp_um, m_idx, full);
507 monster_race *ap_r_ptr = &r_info[um_ptr->m_ptr->ap_r_idx];
508 if (ap_r_ptr->r_tkills && ap_r_ptr->level >= subject_ptr->lev)
509 um_ptr->do_disturb = TRUE;
512 if (um_ptr->m_ptr->mflag2.has(MFLAG2::MARK))
515 decide_sight_invisible_monster(subject_ptr, um_ptr, m_idx);
517 update_invisible_monster(subject_ptr, um_ptr, m_idx);
519 update_visible_monster(subject_ptr, um_ptr, m_idx);
521 if (update_clear_monster(subject_ptr, um_ptr) || um_ptr->m_ptr->mflag.has_not(MFLAG::VIEW))
524 um_ptr->m_ptr->mflag.reset(MFLAG::VIEW);
525 if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
526 disturb(subject_ptr, TRUE, TRUE);
530 * @param player_ptr プレーヤーへの参照ポインタ
531 * @brief 単純に生存している全モンスターの更新処理を行う / This function simply updates all the (non-dead) monsters (see above).
532 * @param full 距離更新を行うならtrue
534 * @todo モンスターの感知状況しか更新していないように見える。関数名変更を検討する
536 void update_monsters(player_type *player_ptr, bool full)
538 floor_type *floor_ptr = player_ptr->current_floor_ptr;
539 for (MONSTER_IDX i = 1; i < floor_ptr->m_max; i++) {
540 monster_type *m_ptr = &floor_ptr->m_list[i];
541 if (!monster_is_valid(m_ptr))
544 update_monster(player_ptr, i, full);
549 * @brief SMART(適格に攻撃を行う)モンスターの学習状況を更新する / Learn about an "observed" resistance.
550 * @param m_idx 更新を行う「モンスター情報ID
554 void update_smart_learn(player_type *player_ptr, MONSTER_IDX m_idx, int what)
556 monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
557 monster_race *r_ptr = &r_info[m_ptr->r_idx];
558 if (!smart_learn || ((r_ptr->flags2 & RF2_STUPID) != 0) || (((r_ptr->flags2 & RF2_SMART) == 0) && (randint0(100) < 50)))
563 if (has_resist_acid(player_ptr))
564 m_ptr->smart.set(SM::RES_ACID);
566 if (is_oppose_acid(player_ptr))
567 m_ptr->smart.set(SM::OPP_ACID);
569 if (has_immune_acid(player_ptr))
570 m_ptr->smart.set(SM::IMM_ACID);
574 if (has_resist_elec(player_ptr))
575 m_ptr->smart.set(SM::RES_ELEC);
577 if (is_oppose_elec(player_ptr))
578 m_ptr->smart.set(SM::OPP_ELEC);
580 if (has_immune_elec(player_ptr))
581 m_ptr->smart.set(SM::IMM_ELEC);
585 if (has_resist_fire(player_ptr))
586 m_ptr->smart.set(SM::RES_FIRE);
588 if (is_oppose_fire(player_ptr))
589 m_ptr->smart.set(SM::OPP_FIRE);
591 if (has_immune_fire(player_ptr))
592 m_ptr->smart.set(SM::IMM_FIRE);
596 if (has_resist_cold(player_ptr))
597 m_ptr->smart.set(SM::RES_COLD);
599 if (is_oppose_cold(player_ptr))
600 m_ptr->smart.set(SM::OPP_COLD);
602 if (has_immune_cold(player_ptr))
603 m_ptr->smart.set(SM::IMM_COLD);
607 if (has_resist_pois(player_ptr))
608 m_ptr->smart.set(SM::RES_POIS);
610 if (is_oppose_pois(player_ptr))
611 m_ptr->smart.set(SM::OPP_POIS);
615 if (has_resist_neth(player_ptr))
616 m_ptr->smart.set(SM::RES_NETH);
620 if (has_resist_lite(player_ptr))
621 m_ptr->smart.set(SM::RES_LITE);
625 if (has_resist_dark(player_ptr))
626 m_ptr->smart.set(SM::RES_DARK);
630 if (has_resist_fear(player_ptr))
631 m_ptr->smart.set(SM::RES_FEAR);
635 if (has_resist_conf(player_ptr))
636 m_ptr->smart.set(SM::RES_CONF);
640 if (has_resist_chaos(player_ptr))
641 m_ptr->smart.set(SM::RES_CHAOS);
645 if (has_resist_disen(player_ptr))
646 m_ptr->smart.set(SM::RES_DISEN);
650 if (has_resist_blind(player_ptr))
651 m_ptr->smart.set(SM::RES_BLIND);
655 if (has_resist_nexus(player_ptr))
656 m_ptr->smart.set(SM::RES_NEXUS);
660 if (has_resist_sound(player_ptr))
661 m_ptr->smart.set(SM::RES_SOUND);
665 if (has_resist_shard(player_ptr))
666 m_ptr->smart.set(SM::RES_SHARD);
670 if (player_ptr->free_act)
671 m_ptr->smart.set(SM::IMM_FREE);
675 if (!player_ptr->msp)
676 m_ptr->smart.set(SM::IMM_MANA);
680 if (has_reflect(player_ptr))
681 m_ptr->smart.set(SM::IMM_REFLECT);