}
}
-static um_type* initialize_um_type(player_type* subject_ptr, um_type *um_ptr, MONSTER_IDX m_idx, bool full)
+static um_type *initialize_um_type(player_type *subject_ptr, um_type *um_ptr, MONSTER_IDX m_idx, bool full)
{
um_ptr->m_ptr = &subject_ptr->current_floor_ptr->m_list[m_idx];
um_ptr->do_disturb = disturb_move;
return;
}
-
+
if (!subject_ptr->telepathy)
return;
return;
}
-
+
if (update_weird_telepathy(subject_ptr, um_ptr))
return;
}
}
-static bool check_cold_blood(player_type *subject_ptr, um_type *um_ptr)
+static bool check_cold_blood(player_type *subject_ptr, um_type *um_ptr, const POSITION distance)
{
if (distance > subject_ptr->see_infra)
return FALSE;
- if ((r_info[um_ptr->m_ptr->r_idx].flags2 & (RF2_COLD_BLOOD | RF2_AURA_FIRE)) == RF2_COLD_BLOOD)
- return TRUE;
+ monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
+ if ((r_ptr->flags2 & (RF2_COLD_BLOOD | RF2_AURA_FIRE)) == RF2_COLD_BLOOD)
+ return FALSE;
um_ptr->easy = TRUE;
um_ptr->flag = TRUE;
return TRUE;
}
-/*!
- * @brief モンスターの各情報を更新する / This function updates the monster record of the given monster
- * @param m_idx 更新するモンスター情報のID
- * @param full プレイヤーとの距離更新を行うならばtrue
- * @return なし
- */
-void update_monster(player_type *subject_ptr, MONSTER_IDX m_idx, bool full)
+static bool check_invisible(player_type *subject_ptr, um_type *um_ptr)
{
- um_type tmp_um;
- um_type *um_ptr = initialize_um_type(subject_ptr, &tmp_um, m_idx, full);
- if (disturb_high) {
- monster_race *ap_r_ptr = &r_info[um_ptr->m_ptr->ap_r_idx];
- if (ap_r_ptr->r_tkills && ap_r_ptr->level >= subject_ptr->lev)
- um_ptr->do_disturb = TRUE;
- }
+ if (!player_can_see_bold(subject_ptr, um_ptr->fy, um_ptr->fx))
+ return FALSE;
- if (um_ptr->m_ptr->mflag2 & MFLAG2_MARK)
+ monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
+ if (r_ptr->flags2 & RF2_INVISIBLE) {
+ if (subject_ptr->see_inv) {
+ um_ptr->easy = TRUE;
+ um_ptr->flag = TRUE;
+ }
+ } else {
+ um_ptr->easy = TRUE;
um_ptr->flag = TRUE;
+ }
+ return TRUE;
+}
+
+/*!
+ * @brief テレパシー・赤外線視力・可視透明によってモンスターを感知できるかどうかの判定
+ * @param subject_ptr プレーヤーへの参照ポインタ
+ * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
+ * @return なし
+ */
+static void decide_sight_invisible_monster(player_type *subject_ptr, um_type *um_ptr)
+{
POSITION distance = decide_updated_distance(subject_ptr, um_ptr);
monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
- if (distance <= (um_ptr->in_darkness ? MAX_SIGHT / 2 : MAX_SIGHT)) {
- if (!um_ptr->in_darkness || (distance <= MAX_SIGHT / 4)) {
- update_telepathy_sight(subject_ptr, um_ptr);
- update_specific_race_telepathy(subject_ptr, um_ptr);
- }
+ if (distance > (um_ptr->in_darkness ? MAX_SIGHT / 2 : MAX_SIGHT))
+ return;
- if (player_has_los_bold(subject_ptr, um_ptr->fy, um_ptr->fx) && !subject_ptr->blind) {
- if (subject_ptr->concent >= CONCENT_RADAR_THRESHOLD) {
- um_ptr->easy = TRUE;
- um_ptr->flag = TRUE;
- }
-
- bool do_cold_blood = check_cold_blood(subject_ptr, um_ptr);
- bool do_invisible = FALSE;
- if (player_can_see_bold(subject_ptr, um_ptr->fy, um_ptr->fx))
- if (r_ptr->flags2 & RF2_INVISIBLE) {
- do_invisible = TRUE;
- if (subject_ptr->see_inv) {
- um_ptr->easy = TRUE;
- um_ptr->flag = TRUE;
- }
- } else {
- um_ptr->easy = TRUE;
- um_ptr->flag = TRUE;
- }
-
- if (um_ptr->flag && is_original_ap(um_ptr->m_ptr) && !subject_ptr->image) {
- if (do_invisible)
- r_ptr->r_flags2 |= RF2_INVISIBLE;
-
- if (do_cold_blood)
- r_ptr->r_flags2 |= RF2_COLD_BLOOD;
- }
- }
+ if (!um_ptr->in_darkness || (distance <= MAX_SIGHT / 4)) {
+ update_telepathy_sight(subject_ptr, um_ptr);
+ update_specific_race_telepathy(subject_ptr, um_ptr);
}
- /* The monster is now visible */
- if (um_ptr->flag) {
- if (!um_ptr->m_ptr->ml) {
- um_ptr->m_ptr->ml = TRUE;
- lite_spot(subject_ptr, um_ptr->fy, um_ptr->fx);
-
- if (subject_ptr->health_who == m_idx)
- subject_ptr->redraw |= PR_HEALTH;
-
- if (subject_ptr->riding == m_idx)
- subject_ptr->redraw |= PR_UHEALTH;
-
- if (!subject_ptr->image) {
- if ((um_ptr->m_ptr->ap_r_idx == MON_KAGE) && (r_info[MON_KAGE].r_sights < MAX_SHORT))
- r_info[MON_KAGE].r_sights++;
- else if (is_original_ap(um_ptr->m_ptr) && (r_ptr->r_sights < MAX_SHORT))
- r_ptr->r_sights++;
- }
-
- if (r_info[um_ptr->m_ptr->ap_r_idx].flags2 & RF2_ELDRITCH_HORROR)
- sanity_blast(subject_ptr, um_ptr->m_ptr, FALSE);
-
- if (disturb_near
- && (projectable(subject_ptr, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx, subject_ptr->y, subject_ptr->x)
- && projectable(subject_ptr, subject_ptr->y, subject_ptr->x, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx))) {
- if (disturb_pets || is_hostile(um_ptr->m_ptr))
- disturb(subject_ptr, TRUE, TRUE);
- }
- }
+ if (!player_has_los_bold(subject_ptr, um_ptr->fy, um_ptr->fx) || subject_ptr->blind)
+ return;
+
+ if (subject_ptr->concent >= CONCENT_RADAR_THRESHOLD) {
+ um_ptr->easy = TRUE;
+ um_ptr->flag = TRUE;
}
- /* The monster is not visible */
- else {
- if (um_ptr->m_ptr->ml) {
- um_ptr->m_ptr->ml = FALSE;
- lite_spot(subject_ptr, um_ptr->fy, um_ptr->fx);
+ bool do_cold_blood = check_cold_blood(subject_ptr, um_ptr, distance);
+ bool do_invisible = check_invisible(subject_ptr, um_ptr);
+ if (!um_ptr->flag || !is_original_ap(um_ptr->m_ptr) || subject_ptr->image)
+ return;
- if (subject_ptr->health_who == m_idx)
- subject_ptr->redraw |= PR_HEALTH;
+ if (do_invisible)
+ r_ptr->r_flags2 |= RF2_INVISIBLE;
- if (subject_ptr->riding == m_idx)
- subject_ptr->redraw |= PR_UHEALTH;
+ if (do_cold_blood)
+ r_ptr->r_flags2 |= RF2_COLD_BLOOD;
+}
- if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
- disturb(subject_ptr, TRUE, TRUE);
- }
+/*!
+ * @brief 壁の向こうにいるモンスターへのテレパシー・赤外線視力による冷血動物以外の透明モンスター・可視透明能力による透明モンスター
+ * 以上を感知する
+ * @param subject_ptr プレーヤーへの参照ポインタ
+ * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
+ * @param m_idx フロアのモンスター番号
+ * @return なし
+ * @details 感知した結果、エルドリッチホラー持ちがいたら精神を破壊する
+ */
+static void update_invisible_monster(player_type *subject_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
+{
+ if (um_ptr->m_ptr->ml)
+ return;
+
+ um_ptr->m_ptr->ml = TRUE;
+ lite_spot(subject_ptr, um_ptr->fy, um_ptr->fx);
+
+ if (subject_ptr->health_who == m_idx)
+ subject_ptr->redraw |= PR_HEALTH;
+
+ if (subject_ptr->riding == m_idx)
+ subject_ptr->redraw |= PR_UHEALTH;
+
+ if (!subject_ptr->image) {
+ monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
+ if ((um_ptr->m_ptr->ap_r_idx == MON_KAGE) && (r_info[MON_KAGE].r_sights < MAX_SHORT))
+ r_info[MON_KAGE].r_sights++;
+ else if (is_original_ap(um_ptr->m_ptr) && (r_ptr->r_sights < MAX_SHORT))
+ r_ptr->r_sights++;
}
- /* The monster is now easily visible */
- if (um_ptr->easy) {
- if (!(um_ptr->m_ptr->mflag & MFLAG_VIEW)) {
- um_ptr->m_ptr->mflag |= MFLAG_VIEW;
- if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
- disturb(subject_ptr, TRUE, TRUE);
- }
+ if (r_info[um_ptr->m_ptr->ap_r_idx].flags2 & RF2_ELDRITCH_HORROR)
+ sanity_blast(subject_ptr, um_ptr->m_ptr, FALSE);
- return;
+ if (disturb_near
+ && (projectable(subject_ptr, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx, subject_ptr->y, subject_ptr->x)
+ && projectable(subject_ptr, subject_ptr->y, subject_ptr->x, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx))) {
+ if (disturb_pets || is_hostile(um_ptr->m_ptr))
+ disturb(subject_ptr, TRUE, TRUE);
}
+}
- /* The monster is not easily visible */
- /* Change */
- if (!(um_ptr->m_ptr->mflag & MFLAG_VIEW))
+static void update_visible_monster(player_type *subject_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
+{
+ if (!um_ptr->m_ptr->ml)
return;
- /* Mark as not easily visible */
- um_ptr->m_ptr->mflag &= ~(MFLAG_VIEW);
+ um_ptr->m_ptr->ml = FALSE;
+ lite_spot(subject_ptr, um_ptr->fy, um_ptr->fx);
- if (um_ptr->do_disturb) {
- if (disturb_pets || is_hostile(um_ptr->m_ptr))
+ if (subject_ptr->health_who == m_idx)
+ subject_ptr->redraw |= PR_HEALTH;
+
+ if (subject_ptr->riding == m_idx)
+ subject_ptr->redraw |= PR_UHEALTH;
+
+ if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
+ disturb(subject_ptr, TRUE, TRUE);
+}
+
+static bool update_clear_monster(player_type *subject_ptr, um_type *um_ptr)
+{
+ if (!um_ptr->easy)
+ return FALSE;
+
+ if (!(um_ptr->m_ptr->mflag & MFLAG_VIEW)) {
+ um_ptr->m_ptr->mflag |= MFLAG_VIEW;
+ if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
disturb(subject_ptr, TRUE, TRUE);
}
+
+ return TRUE;
}
/*!
+ * @brief モンスターの各情報を更新する / This function updates the monster record of the given monster
+ * @param m_idx 更新するモンスター情報のID
+ * @param full プレイヤーとの距離更新を行うならばtrue
+ * @return なし
+ */
+void update_monster(player_type *subject_ptr, MONSTER_IDX m_idx, bool full)
+{
+ um_type tmp_um;
+ um_type *um_ptr = initialize_um_type(subject_ptr, &tmp_um, m_idx, full);
+ if (disturb_high) {
+ monster_race *ap_r_ptr = &r_info[um_ptr->m_ptr->ap_r_idx];
+ if (ap_r_ptr->r_tkills && ap_r_ptr->level >= subject_ptr->lev)
+ um_ptr->do_disturb = TRUE;
+ }
+
+ if (um_ptr->m_ptr->mflag2 & MFLAG2_MARK)
+ um_ptr->flag = TRUE;
+
+ decide_sight_invisible_monster(subject_ptr, um_ptr);
+ if (um_ptr->flag)
+ update_invisible_monster(subject_ptr, um_ptr, m_idx);
+ else
+ update_visible_monster(subject_ptr, um_ptr, m_idx);
+
+ if (update_clear_monster(subject_ptr, um_ptr) || ((um_ptr->m_ptr->mflag & MFLAG_VIEW) == 0))
+ return;
+
+ um_ptr->m_ptr->mflag &= ~(MFLAG_VIEW);
+ if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
+ disturb(subject_ptr, TRUE, TRUE);
+}
+
+/*!
+ * todo モンスターの感知状況しか更新していないように見える。関数名変更を検討する
* @param player_ptr プレーヤーへの参照ポインタ
* @brief 単純に生存している全モンスターの更新処理を行う / This function simply updates all the (non-dead) monsters (see above).
* @param full 距離更新を行うならtrue
monster_type *m_ptr = &floor_ptr->m_list[i];
if (!monster_is_valid(m_ptr))
continue;
+
update_monster(player_ptr, i, full);
}
}
{
monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
-
if (!smart_learn || ((r_ptr->flags2 & RF2_STUPID) != 0) || (((r_ptr->flags2 & RF2_SMART) == 0) && (randint0(100) < 50)))
return;
switch (what) {
case DRS_ACID:
- if (player_ptr->resist_acid)
+ if (has_resist_acid(player_ptr))
m_ptr->smart |= SM_RES_ACID;
if (is_oppose_acid(player_ptr))
m_ptr->smart |= SM_OPP_ACID;
- if (is_immune_acid(player_ptr))
+ if (has_immune_acid(player_ptr))
m_ptr->smart |= SM_IMM_ACID;
break;
case DRS_ELEC:
- if (player_ptr->resist_elec)
+ if (has_resist_elec(player_ptr))
m_ptr->smart |= SM_RES_ELEC;
if (is_oppose_elec(player_ptr))
m_ptr->smart |= SM_OPP_ELEC;
- if (is_immune_elec(player_ptr))
+ if (has_immune_elec(player_ptr))
m_ptr->smart |= SM_IMM_ELEC;
break;
case DRS_FIRE:
- if (player_ptr->resist_fire)
+ if (has_resist_fire(player_ptr))
m_ptr->smart |= SM_RES_FIRE;
if (is_oppose_fire(player_ptr))
m_ptr->smart |= SM_OPP_FIRE;
-
- if (is_immune_fire(player_ptr))
+
+ if (has_immune_fire(player_ptr))
m_ptr->smart |= SM_IMM_FIRE;
-
+
break;
case DRS_COLD:
- if (player_ptr->resist_cold)
+ if (has_resist_cold(player_ptr))
m_ptr->smart |= SM_RES_COLD;
if (is_oppose_cold(player_ptr))
m_ptr->smart |= SM_OPP_COLD;
- if (is_immune_cold(player_ptr))
+ if (has_immune_cold(player_ptr))
m_ptr->smart |= SM_IMM_COLD;
break;
case DRS_POIS:
- if (player_ptr->resist_pois)
+ if (has_resist_pois(player_ptr))
m_ptr->smart |= SM_RES_POIS;
if (is_oppose_pois(player_ptr))
break;
case DRS_LITE:
- if (player_ptr->resist_lite)
+ if (has_resist_lite(player_ptr))
m_ptr->smart |= SM_RES_LITE;
break;
break;
case DRS_CONF:
- if (player_ptr->resist_conf)
+ if (has_resist_conf(player_ptr))
m_ptr->smart |= SM_RES_CONF;
break;
break;
case DRS_SOUND:
- if (player_ptr->resist_sound)
+ if (has_resist_sound(player_ptr))
m_ptr->smart |= SM_RES_SOUND;
break;