2 * @brief モンスター情報のアップデート処理
7 #include "monster/monster-update.h"
8 #include "core/disturbance.h"
9 #include "core/window-redrawer.h"
10 #include "dungeon/dungeon-flag-types.h"
11 #include "floor/geometry.h"
12 #include "game-option/birth-options.h"
13 #include "game-option/disturbance-options.h"
14 #include "grid/grid.h"
15 #include "mind/drs-types.h"
16 #include "monster-race/monster-race.h"
17 #include "monster-race/race-brightness-flags.h"
18 #include "monster-race/race-brightness-mask.h"
19 #include "monster-race/race-indice-types.h"
20 #include "monster/monster-flag-types.h"
21 #include "monster/monster-info.h"
22 #include "monster/monster-processor-util.h"
23 #include "monster/monster-status.h"
24 #include "monster/monster-util.h"
25 #include "monster/smart-learn-types.h"
26 #include "player-base/player-class.h"
27 #include "player-info/samurai-data-type.h"
28 #include "player-info/sniper-data-type.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/angband-system.h"
34 #include "system/dungeon-info.h"
35 #include "system/floor-type-definition.h"
36 #include "system/grid-type-definition.h"
37 #include "system/monster-entity.h"
38 #include "system/monster-race-info.h"
39 #include "system/player-type-definition.h"
40 #include "system/redrawing-flags-updater.h"
41 #include "target/projection-path-calculator.h"
42 #include "timed-effect/player-blindness.h"
43 #include "timed-effect/player-hallucination.h"
44 #include "timed-effect/timed-effects.h"
45 #include "util/bit-flags-calculator.h"
46 #include "world/world.h"
61 * @brief 騎乗中のモンスター情報を更新する
62 * @param player_ptr プレイヤーへの参照ポインタ
63 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
64 * @param m_idx モンスターID
65 * @param oy 移動前の、モンスターのY座標
66 * @param ox 移動前の、モンスターのX座標
67 * @param ny 移動後の、モンスターのY座標
68 * @param ox 移動後の、モンスターのX座標
69 * @return アイテム等に影響を及ぼしたらTRUE
71 bool update_riding_monster(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, POSITION ny, POSITION nx)
73 auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
74 auto *g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
75 MonsterEntity *y_ptr = &player_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
76 if (turn_flags_ptr->is_riding_mon) {
77 return move_player_effect(player_ptr, ny, nx, MPE_DONT_PICKUP);
80 player_ptr->current_floor_ptr->grid_array[oy][ox].m_idx = g_ptr->m_idx;
81 if (is_monster(g_ptr->m_idx)) {
84 update_monster(player_ptr, g_ptr->m_idx, true);
90 update_monster(player_ptr, m_idx, true);
92 lite_spot(player_ptr, oy, ox);
93 lite_spot(player_ptr, ny, nx);
98 * @brief マップ及びミニマップの更新フラグをセットする
99 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
101 void update_map_flags(turn_flags *turn_flags_ptr)
103 auto &rfu = RedrawingFlagsUpdater::get_instance();
104 if (!turn_flags_ptr->do_view) {
108 rfu.set_flag(StatusRecalculatingFlag::FLOW);
109 static constexpr auto flags = {
110 SubWindowRedrawingFlag::OVERHEAD,
111 SubWindowRedrawingFlag::DUNGEON,
113 rfu.set_flags(flags);
117 * @brief モンスターの光源フラグに基づいてフロアの光源状態更新フラグをセットする
118 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
119 * @param r_ptr モンスター種族への参照ポインタ
121 void update_lite_flags(turn_flags *turn_flags_ptr, MonsterRaceInfo *r_ptr)
123 using Mbt = MonsterBrightnessType;
124 const auto has_lite = r_ptr->brightness_flags.has_any_of({ Mbt::HAS_LITE_1, Mbt::HAS_LITE_2 });
125 const auto except_has_lite = EnumClassFlagGroup<Mbt>(self_ld_mask).set({ Mbt::HAS_DARK_1, Mbt::HAS_DARK_2 });
126 if (turn_flags_ptr->do_move && (r_ptr->brightness_flags.has_any_of(except_has_lite) || (has_lite && !AngbandSystem::get_instance().is_phase_out()))) {
127 RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::MONSTER_LITE);
132 * @brief モンスターのフラグを更新する
133 * @param player_ptr プレイヤーへの参照ポインタ
134 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
135 * @param m_ptr モンスターへの参照ポインタ
137 void update_monster_race_flags(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr)
139 auto *r_ptr = &m_ptr->get_monrace();
140 if (!is_original_ap_and_seen(player_ptr, m_ptr)) {
144 if (turn_flags_ptr->did_open_door) {
145 r_ptr->r_behavior_flags.set(MonsterBehaviorType::OPEN_DOOR);
148 if (turn_flags_ptr->did_bash_door) {
149 r_ptr->r_behavior_flags.set(MonsterBehaviorType::BASH_DOOR);
152 if (turn_flags_ptr->did_take_item) {
153 r_ptr->r_behavior_flags.set(MonsterBehaviorType::TAKE_ITEM);
156 if (turn_flags_ptr->did_kill_item) {
157 r_ptr->r_behavior_flags.set(MonsterBehaviorType::KILL_ITEM);
160 if (turn_flags_ptr->did_move_body) {
161 r_ptr->r_behavior_flags.set(MonsterBehaviorType::MOVE_BODY);
164 if (turn_flags_ptr->did_pass_wall) {
165 r_ptr->r_feature_flags.set(MonsterFeatureType::PASS_WALL);
168 if (turn_flags_ptr->did_kill_wall) {
169 r_ptr->r_feature_flags.set(MonsterFeatureType::KILL_WALL);
174 * @brief モンスターフラグの更新に基づき、モンスター表示を更新する
175 * @param monster_race_idx モンスターID
176 * @param window ウィンドウフラグ
177 * @param old_race_flags_ptr モンスターフラグへの参照ポインタ
179 void update_player_window(PlayerType *player_ptr, old_race_flags *old_race_flags_ptr)
181 MonsterRaceInfo *r_ptr;
182 r_ptr = &monraces_info[player_ptr->monster_race_idx];
183 if ((old_race_flags_ptr->old_r_ability_flags != r_ptr->r_ability_flags) ||
184 (old_race_flags_ptr->old_r_resistance_flags != r_ptr->r_resistance_flags) || (old_race_flags_ptr->old_r_blows0 != r_ptr->r_blows[0]) ||
185 (old_race_flags_ptr->old_r_blows1 != r_ptr->r_blows[1]) || (old_race_flags_ptr->old_r_blows2 != r_ptr->r_blows[2]) ||
186 (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) ||
187 (old_race_flags_ptr->old_r_behavior_flags != r_ptr->r_behavior_flags) || (old_race_flags_ptr->old_r_kind_flags != r_ptr->r_kind_flags) ||
188 (old_race_flags_ptr->old_r_drop_flags != r_ptr->r_drop_flags) || (old_race_flags_ptr->old_r_feature_flags != r_ptr->r_feature_flags) ||
189 (old_race_flags_ptr->old_r_special_flags != r_ptr->r_special_flags)) {
190 RedrawingFlagsUpdater::get_instance().set_flag(SubWindowRedrawingFlag::MONSTER_LORE);
194 static um_type *initialize_um_type(PlayerType *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx, bool full)
196 auto &floor = *player_ptr->current_floor_ptr;
197 um_ptr->m_ptr = &floor.m_list[m_idx];
198 um_ptr->do_disturb = disturb_move;
199 um_ptr->fy = um_ptr->m_ptr->fy;
200 um_ptr->fx = um_ptr->m_ptr->fx;
201 um_ptr->flag = false;
202 um_ptr->easy = false;
203 um_ptr->in_darkness = floor.get_dungeon_definition().flags.has(DungeonFeatureType::DARKNESS) && !player_ptr->see_nocto;
208 static POSITION decide_updated_distance(PlayerType *player_ptr, um_type *um_ptr)
211 return um_ptr->m_ptr->cdis;
214 int dy = (player_ptr->y > um_ptr->fy) ? (player_ptr->y - um_ptr->fy) : (um_ptr->fy - player_ptr->y);
215 int dx = (player_ptr->x > um_ptr->fx) ? (player_ptr->x - um_ptr->fx) : (um_ptr->fx - player_ptr->x);
216 POSITION distance = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
217 if (distance > 255) {
225 um_ptr->m_ptr->cdis = distance;
229 static void update_smart_stupid_flags(MonsterRaceInfo *r_ptr)
231 if (r_ptr->behavior_flags.has(MonsterBehaviorType::SMART)) {
232 r_ptr->r_behavior_flags.set(MonsterBehaviorType::SMART);
235 if (r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID)) {
236 r_ptr->r_behavior_flags.set(MonsterBehaviorType::STUPID);
241 * @brief WEIRD_MINDフラグ持ちのモンスターを1/10の確率でテレパシーに引っかける
242 * @param player_ptr プレイヤーへの参照ポインタ
243 * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
244 * @param m_idx モンスターID
245 * @return WEIRD_MINDフラグがあるならTRUE
247 static bool update_weird_telepathy(PlayerType *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
249 auto *m_ptr = um_ptr->m_ptr;
250 auto *r_ptr = &m_ptr->get_monrace();
251 if (r_ptr->misc_flags.has_not(MonsterMiscType::WEIRD_MIND)) {
255 if ((m_idx % 10) != (w_ptr->game_turn % 10)) {
260 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
261 if (m_ptr->is_original_ap() && !player_ptr->effects()->hallucination()->is_hallucinated()) {
262 r_ptr->r_misc_flags.set(MonsterMiscType::WEIRD_MIND);
263 update_smart_stupid_flags(r_ptr);
269 static void update_telepathy_sight(PlayerType *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
271 auto *m_ptr = um_ptr->m_ptr;
272 auto *r_ptr = &m_ptr->get_monrace();
273 if (PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU)) {
275 um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
276 if (um_ptr->m_ptr->is_original_ap() && !player_ptr->effects()->hallucination()->is_hallucinated()) {
277 update_smart_stupid_flags(r_ptr);
283 if (!player_ptr->telepathy) {
287 auto is_hallucinated = player_ptr->effects()->hallucination()->is_hallucinated();
288 if (r_ptr->misc_flags.has(MonsterMiscType::EMPTY_MIND)) {
289 if (m_ptr->is_original_ap() && !is_hallucinated) {
290 r_ptr->r_misc_flags.set(MonsterMiscType::EMPTY_MIND);
296 if (update_weird_telepathy(player_ptr, um_ptr, m_idx)) {
301 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
302 if (m_ptr->is_original_ap() && !is_hallucinated) {
303 update_smart_stupid_flags(r_ptr);
307 static void update_specific_race_telepathy(PlayerType *player_ptr, um_type *um_ptr)
309 auto *m_ptr = um_ptr->m_ptr;
310 auto *r_ptr = &m_ptr->get_monrace();
311 auto is_hallucinated = player_ptr->effects()->hallucination()->is_hallucinated();
312 if ((player_ptr->esp_animal) && r_ptr->kind_flags.has(MonsterKindType::ANIMAL)) {
314 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
315 if (m_ptr->is_original_ap() && !is_hallucinated) {
316 r_ptr->r_kind_flags.set(MonsterKindType::ANIMAL);
320 if ((player_ptr->esp_undead) && r_ptr->kind_flags.has(MonsterKindType::UNDEAD)) {
322 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
323 if (m_ptr->is_original_ap() && !is_hallucinated) {
324 r_ptr->r_kind_flags.set(MonsterKindType::UNDEAD);
328 if ((player_ptr->esp_demon) && r_ptr->kind_flags.has(MonsterKindType::DEMON)) {
330 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
331 if (m_ptr->is_original_ap() && !is_hallucinated) {
332 r_ptr->r_kind_flags.set(MonsterKindType::DEMON);
336 if ((player_ptr->esp_orc) && r_ptr->kind_flags.has(MonsterKindType::ORC)) {
338 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
339 if (m_ptr->is_original_ap() && !is_hallucinated) {
340 r_ptr->r_kind_flags.set(MonsterKindType::ORC);
344 if ((player_ptr->esp_troll) && r_ptr->kind_flags.has(MonsterKindType::TROLL)) {
346 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
347 if (m_ptr->is_original_ap() && !is_hallucinated) {
348 r_ptr->r_kind_flags.set(MonsterKindType::TROLL);
352 if ((player_ptr->esp_giant) && r_ptr->kind_flags.has(MonsterKindType::GIANT)) {
354 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
355 if (m_ptr->is_original_ap() && !is_hallucinated) {
356 r_ptr->r_kind_flags.set(MonsterKindType::GIANT);
360 if ((player_ptr->esp_dragon) && r_ptr->kind_flags.has(MonsterKindType::DRAGON)) {
362 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
363 if (m_ptr->is_original_ap() && !is_hallucinated) {
364 r_ptr->r_kind_flags.set(MonsterKindType::DRAGON);
368 if ((player_ptr->esp_human) && r_ptr->kind_flags.has(MonsterKindType::HUMAN)) {
370 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
371 if (m_ptr->is_original_ap() && !is_hallucinated) {
372 r_ptr->r_kind_flags.set(MonsterKindType::HUMAN);
376 if ((player_ptr->esp_evil) && r_ptr->kind_flags.has(MonsterKindType::EVIL)) {
378 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
379 if (m_ptr->is_original_ap() && !is_hallucinated) {
380 r_ptr->r_kind_flags.set(MonsterKindType::EVIL);
384 if ((player_ptr->esp_good) && r_ptr->kind_flags.has(MonsterKindType::GOOD)) {
386 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
387 if (m_ptr->is_original_ap() && !is_hallucinated) {
388 r_ptr->r_kind_flags.set(MonsterKindType::GOOD);
392 if ((player_ptr->esp_nonliving) && r_ptr->kind_flags.has(MonsterKindType::NONLIVING) && r_ptr->kind_flags.has_none_of({ MonsterKindType::DEMON, MonsterKindType::UNDEAD })) {
394 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
395 if (m_ptr->is_original_ap() && !is_hallucinated) {
396 r_ptr->r_kind_flags.set(MonsterKindType::NONLIVING);
400 if ((player_ptr->esp_unique) && r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
402 m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
403 if (m_ptr->is_original_ap() && !is_hallucinated) {
404 r_ptr->r_kind_flags.set(MonsterKindType::UNIQUE);
409 static bool check_cold_blood(PlayerType *player_ptr, um_type *um_ptr, const POSITION distance)
411 if (distance > player_ptr->see_infra) {
415 auto *r_ptr = &um_ptr->m_ptr->get_monrace();
416 if (r_ptr->misc_flags.has(MonsterMiscType::COLD_BLOOD) && r_ptr->aura_flags.has_not(MonsterAuraType::FIRE)) {
425 static bool check_invisible(PlayerType *player_ptr, um_type *um_ptr)
427 if (!player_can_see_bold(player_ptr, um_ptr->fy, um_ptr->fx)) {
431 auto *r_ptr = &um_ptr->m_ptr->get_monrace();
432 if (r_ptr->misc_flags.has(MonsterMiscType::INVISIBLE)) {
433 if (player_ptr->see_inv) {
446 * @brief テレパシー・赤外線視力・可視透明によってモンスターを感知できるかどうかの判定
447 * @param player_ptr プレイヤーへの参照ポインタ
448 * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
450 static void decide_sight_invisible_monster(PlayerType *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
452 POSITION distance = decide_updated_distance(player_ptr, um_ptr);
453 auto *m_ptr = um_ptr->m_ptr;
454 auto *r_ptr = &m_ptr->get_monrace();
456 m_ptr->mflag.reset(MonsterTemporaryFlagType::ESP);
458 if (distance > (um_ptr->in_darkness ? MAX_PLAYER_SIGHT / 2 : MAX_PLAYER_SIGHT)) {
462 if (!um_ptr->in_darkness || (distance <= MAX_PLAYER_SIGHT / 4)) {
463 update_telepathy_sight(player_ptr, um_ptr, m_idx);
464 update_specific_race_telepathy(player_ptr, um_ptr);
467 if (!player_ptr->current_floor_ptr->has_los({ um_ptr->fy, um_ptr->fx }) || player_ptr->effects()->blindness()->is_blind()) {
471 auto sniper_data = PlayerClass(player_ptr).get_specific_data<SniperData>();
472 if (sniper_data && (sniper_data->concent >= CONCENT_RADAR_THRESHOLD)) {
477 bool do_cold_blood = check_cold_blood(player_ptr, um_ptr, distance);
478 bool do_invisible = check_invisible(player_ptr, um_ptr);
479 if (!um_ptr->flag || !m_ptr->is_original_ap() || player_ptr->effects()->hallucination()->is_hallucinated()) {
484 r_ptr->r_misc_flags.set(MonsterMiscType::INVISIBLE);
488 r_ptr->r_misc_flags.set(MonsterMiscType::COLD_BLOOD);
493 * @brief 壁の向こうにいるモンスターへのテレパシー・赤外線視力による冷血動物以外の透明モンスター・可視透明能力による透明モンスター
495 * @param player_ptr プレイヤーへの参照ポインタ
496 * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
497 * @param m_idx フロアのモンスター番号
498 * @details 感知した結果、エルドリッチホラー持ちがいたら精神を破壊する
500 static void update_invisible_monster(PlayerType *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
502 auto *m_ptr = um_ptr->m_ptr;
508 lite_spot(player_ptr, um_ptr->fy, um_ptr->fx);
510 auto &rfu = RedrawingFlagsUpdater::get_instance();
511 if (player_ptr->health_who == m_idx) {
512 rfu.set_flag(MainWindowRedrawingFlag::HEALTH);
515 if (player_ptr->riding == m_idx) {
516 rfu.set_flag(MainWindowRedrawingFlag::UHEALTH);
519 if (!player_ptr->effects()->hallucination()->is_hallucinated()) {
520 auto *r_ptr = &m_ptr->get_monrace();
521 if ((m_ptr->ap_r_idx == MonsterRaceId::KAGE) && (monraces_info[MonsterRaceId::KAGE].r_sights < MAX_SHORT)) {
522 monraces_info[MonsterRaceId::KAGE].r_sights++;
523 } else if (m_ptr->is_original_ap() && (r_ptr->r_sights < MAX_SHORT)) {
528 if (w_ptr->is_loading_now && w_ptr->character_dungeon && !AngbandSystem::get_instance().is_phase_out() && m_ptr->get_appearance_monrace().misc_flags.has(MonsterMiscType::ELDRITCH_HORROR)) {
529 m_ptr->mflag.set(MonsterTemporaryFlagType::SANITY_BLAST);
532 const auto projectable_from_monster = projectable(player_ptr, m_ptr->fy, m_ptr->fx, player_ptr->y, player_ptr->x);
533 const auto projectable_from_player = projectable(player_ptr, player_ptr->y, player_ptr->x, m_ptr->fy, m_ptr->fx);
534 if (disturb_near && projectable_from_monster && projectable_from_player) {
535 if (disturb_pets || m_ptr->is_hostile()) {
536 disturb(player_ptr, true, true);
541 static void update_visible_monster(PlayerType *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
543 if (!um_ptr->m_ptr->ml) {
547 um_ptr->m_ptr->ml = false;
548 lite_spot(player_ptr, um_ptr->fy, um_ptr->fx);
550 auto &rfu = RedrawingFlagsUpdater::get_instance();
551 if (player_ptr->health_who == m_idx) {
552 rfu.set_flag(MainWindowRedrawingFlag::HEALTH);
555 if (player_ptr->riding == m_idx) {
556 rfu.set_flag(MainWindowRedrawingFlag::UHEALTH);
559 if (um_ptr->do_disturb && (disturb_pets || um_ptr->m_ptr->is_hostile())) {
560 disturb(player_ptr, true, true);
564 static bool update_clear_monster(PlayerType *player_ptr, um_type *um_ptr)
570 if (um_ptr->m_ptr->mflag.has_not(MonsterTemporaryFlagType::VIEW)) {
571 um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::VIEW);
572 if (um_ptr->do_disturb && (disturb_pets || um_ptr->m_ptr->is_hostile())) {
573 disturb(player_ptr, true, true);
581 * @brief モンスターの各情報を更新する / This function updates the monster record of the given monster
582 * @param m_idx 更新するモンスター情報のID
583 * @param full プレイヤーとの距離更新を行うならばtrue
585 void update_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool full)
588 um_type *um_ptr = initialize_um_type(player_ptr, &tmp_um, m_idx, full);
590 auto *ap_r_ptr = &um_ptr->m_ptr->get_appearance_monrace();
591 if (ap_r_ptr->r_tkills && ap_r_ptr->level >= player_ptr->lev) {
592 um_ptr->do_disturb = true;
596 if (um_ptr->m_ptr->mflag2.has(MonsterConstantFlagType::MARK)) {
600 decide_sight_invisible_monster(player_ptr, um_ptr, m_idx);
602 update_invisible_monster(player_ptr, um_ptr, m_idx);
604 update_visible_monster(player_ptr, um_ptr, m_idx);
607 if (update_clear_monster(player_ptr, um_ptr) || um_ptr->m_ptr->mflag.has_not(MonsterTemporaryFlagType::VIEW)) {
611 um_ptr->m_ptr->mflag.reset(MonsterTemporaryFlagType::VIEW);
612 if (um_ptr->do_disturb && (disturb_pets || um_ptr->m_ptr->is_hostile())) {
613 disturb(player_ptr, true, true);
618 * @param player_ptr プレイヤーへの参照ポインタ
619 * @brief 単純に生存している全モンスターの更新処理を行う / This function simply updates all the (non-dead) monsters (see above).
620 * @param full 距離更新を行うならtrue
621 * @todo モンスターの感知状況しか更新していないように見える。関数名変更を検討する
623 void update_monsters(PlayerType *player_ptr, bool full)
625 auto *floor_ptr = player_ptr->current_floor_ptr;
626 for (MONSTER_IDX i = 1; i < floor_ptr->m_max; i++) {
627 auto *m_ptr = &floor_ptr->m_list[i];
628 if (!m_ptr->is_valid()) {
632 update_monster(player_ptr, i, full);
637 * @brief SMART(適格に攻撃を行う)モンスターの学習状況を更新する / Learn about an "observed" resistance.
638 * @param m_idx 更新を行う「モンスター情報ID
641 void update_smart_learn(PlayerType *player_ptr, MONSTER_IDX m_idx, int what)
643 auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
644 auto *r_ptr = &m_ptr->get_monrace();
645 if (!smart_learn || (r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID)) || ((r_ptr->behavior_flags.has_not(MonsterBehaviorType::SMART)) && (randint0(100) < 50))) {
651 if (has_resist_acid(player_ptr)) {
652 m_ptr->smart.set(MonsterSmartLearnType::RES_ACID);
655 if (is_oppose_acid(player_ptr)) {
656 m_ptr->smart.set(MonsterSmartLearnType::OPP_ACID);
659 if (has_immune_acid(player_ptr)) {
660 m_ptr->smart.set(MonsterSmartLearnType::IMM_ACID);
665 if (has_resist_elec(player_ptr)) {
666 m_ptr->smart.set(MonsterSmartLearnType::RES_ELEC);
669 if (is_oppose_elec(player_ptr)) {
670 m_ptr->smart.set(MonsterSmartLearnType::OPP_ELEC);
673 if (has_immune_elec(player_ptr)) {
674 m_ptr->smart.set(MonsterSmartLearnType::IMM_ELEC);
679 if (has_resist_fire(player_ptr)) {
680 m_ptr->smart.set(MonsterSmartLearnType::RES_FIRE);
683 if (is_oppose_fire(player_ptr)) {
684 m_ptr->smart.set(MonsterSmartLearnType::OPP_FIRE);
687 if (has_immune_fire(player_ptr)) {
688 m_ptr->smart.set(MonsterSmartLearnType::IMM_FIRE);
693 if (has_resist_cold(player_ptr)) {
694 m_ptr->smart.set(MonsterSmartLearnType::RES_COLD);
697 if (is_oppose_cold(player_ptr)) {
698 m_ptr->smart.set(MonsterSmartLearnType::OPP_COLD);
701 if (has_immune_cold(player_ptr)) {
702 m_ptr->smart.set(MonsterSmartLearnType::IMM_COLD);
707 if (has_resist_pois(player_ptr)) {
708 m_ptr->smart.set(MonsterSmartLearnType::RES_POIS);
711 if (is_oppose_pois(player_ptr)) {
712 m_ptr->smart.set(MonsterSmartLearnType::OPP_POIS);
717 if (has_resist_neth(player_ptr)) {
718 m_ptr->smart.set(MonsterSmartLearnType::RES_NETH);
723 if (has_resist_lite(player_ptr)) {
724 m_ptr->smart.set(MonsterSmartLearnType::RES_LITE);
729 if (has_resist_dark(player_ptr) || has_immune_dark(player_ptr)) {
730 m_ptr->smart.set(MonsterSmartLearnType::RES_DARK);
735 if (has_resist_fear(player_ptr)) {
736 m_ptr->smart.set(MonsterSmartLearnType::RES_FEAR);
741 if (has_resist_conf(player_ptr)) {
742 m_ptr->smart.set(MonsterSmartLearnType::RES_CONF);
747 if (has_resist_chaos(player_ptr)) {
748 m_ptr->smart.set(MonsterSmartLearnType::RES_CHAOS);
753 if (has_resist_disen(player_ptr)) {
754 m_ptr->smart.set(MonsterSmartLearnType::RES_DISEN);
759 if (has_resist_blind(player_ptr)) {
760 m_ptr->smart.set(MonsterSmartLearnType::RES_BLIND);
765 if (has_resist_nexus(player_ptr)) {
766 m_ptr->smart.set(MonsterSmartLearnType::RES_NEXUS);
771 if (has_resist_sound(player_ptr)) {
772 m_ptr->smart.set(MonsterSmartLearnType::RES_SOUND);
777 if (has_resist_shard(player_ptr)) {
778 m_ptr->smart.set(MonsterSmartLearnType::RES_SHARD);
783 if (player_ptr->free_act) {
784 m_ptr->smart.set(MonsterSmartLearnType::IMM_FREE);
789 if (!player_ptr->msp) {
790 m_ptr->smart.set(MonsterSmartLearnType::IMM_MANA);
795 if (has_reflect(player_ptr)) {
796 m_ptr->smart.set(MonsterSmartLearnType::IMM_REFLECT);