+/*!
+ * @brief モンスターの時限ステータスを取得する
+ * @return m_idx モンスターの参照ID
+ * @return mproc_type モンスターの時限ステータスID
+ * @return 残りターン値
+ */
+int get_mproc_idx(MONSTER_IDX m_idx, int mproc_type)
+{
+ s16b *cur_mproc_list = mproc_list[mproc_type];
+ int i;
+
+ for (i = mproc_max[mproc_type] - 1; i >= 0; i--)
+ {
+ if (cur_mproc_list[i] == m_idx) return i;
+ }
+
+ return -1;
+}
+
+/*!
+ * @brief モンスターの時限ステータスリストを追加する
+ * @return m_idx モンスターの参照ID
+ * @return mproc_type 追加したいモンスターの時限ステータスID
+ * @return なし
+ */
+static void mproc_add(MONSTER_IDX m_idx, int mproc_type)
+{
+ if (mproc_max[mproc_type] < max_m_idx) mproc_list[mproc_type][mproc_max[mproc_type]++] = (s16b)m_idx;
+}
+
+
+/*!
+ * @brief モンスターの時限ステータスリストを削除
+ * @return m_idx モンスターの参照ID
+ * @return mproc_type 削除したいモンスターの時限ステータスID
+ * @return なし
+ */
+static void mproc_remove(MONSTER_IDX m_idx, int mproc_type)
+{
+ int mproc_idx = get_mproc_idx(m_idx, mproc_type);
+ if (mproc_idx >= 0) mproc_list[mproc_type][mproc_idx] = mproc_list[mproc_type][--mproc_max[mproc_type]];
+}
+
+
+/*!
+ * @brief モンスターの時限ステータスリストを初期化する / Initialize monster process
+ * @return なし
+ */
+void mproc_init(void)
+{
+ monster_type *m_ptr;
+ MONSTER_IDX i;
+ int cmi;
+
+ /* Reset "mproc_max[]" */
+ for (cmi = 0; cmi < MAX_MTIMED; cmi++) mproc_max[cmi] = 0;
+
+ /* Process the monsters (backwards) */
+ for (i = m_max - 1; i >= 1; i--)
+ {
+ /* Access the monster */
+ m_ptr = &m_list[i];
+
+ /* Ignore "dead" monsters */
+ if (!m_ptr->r_idx) continue;
+
+ for (cmi = 0; cmi < MAX_MTIMED; cmi++)
+ {
+ if (m_ptr->mtimed[cmi]) mproc_add(i, cmi);
+ }
+ }
+}
+
+
+/*!
+ * @brief モンスターの睡眠状態値をセットする /
+ * Set "m_ptr->mtimed[MTIMED_CSLEEP]", notice observable changes
+ * @param m_idx モンスター参照ID
+ * @param v セットする値
+ * @return 別途更新処理が必要な場合TRUEを返す
+ */
+bool set_monster_csleep(MONSTER_IDX m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_CSLEEP(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_CSLEEP);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_CSLEEP(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_CSLEEP);
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_CSLEEP] = (s16b)v;
+
+ if (!notice) return FALSE;
+
+ if (m_ptr->ml)
+ {
+ /* Update health bar as needed */
+ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
+ }
+
+ if (r_info[m_ptr->r_idx].flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE);
+
+ return TRUE;
+}
+
+
+/*!
+ * @brief モンスターの加速状態値をセット /
+ * Set "m_ptr->mtimed[MTIMED_FAST]", notice observable changes
+ * @param m_idx モンスター参照ID
+ * @param v セットする値
+ * @return 別途更新処理が必要な場合TRUEを返す
+ */
+bool set_monster_fast(MONSTER_IDX m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_FAST(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_FAST);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_FAST(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_FAST);
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_FAST] = (s16b)v;
+
+ if (!notice) return FALSE;
+
+ if ((p_ptr->riding == m_idx) && !p_ptr->leaving) p_ptr->update |= (PU_BONUS);
+
+ return TRUE;
+}
+
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_SLOW]", notice observable changes
+ */
+bool set_monster_slow(MONSTER_IDX m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_SLOW(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_SLOW);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_SLOW(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_SLOW);
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_SLOW] = (s16b)v;
+
+ if (!notice) return FALSE;
+
+ if ((p_ptr->riding == m_idx) && !p_ptr->leaving) p_ptr->update |= (PU_BONUS);
+
+ return TRUE;
+}
+
+
+/*!
+ * @brief モンスターの朦朧状態値をセット /
+ * Set "m_ptr->mtimed[MTIMED_STUNNED]", notice observable changes
+ * @param m_idx モンスター参照ID
+ * @param v セットする値
+ * @return 別途更新処理が必要な場合TRUEを返す
+ */
+bool set_monster_stunned(MONSTER_IDX m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_STUNNED(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_STUNNED);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_STUNNED(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_STUNNED);
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_STUNNED] = (s16b)v;
+
+ return notice;
+}
+
+
+/*!
+ * @brief モンスターの混乱状態値をセット /
+ * Set "m_ptr->mtimed[MTIMED_CONFUSED]", notice observable changes
+ * @param m_idx モンスター参照ID
+ * @param v セットする値
+ * @return 別途更新処理が必要な場合TRUEを返す
+ */
+bool set_monster_confused(MONSTER_IDX m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_CONFUSED(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_CONFUSED);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_CONFUSED(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_CONFUSED);
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_CONFUSED] = (s16b)v;
+
+ return notice;
+}
+
+
+/*!
+ * @brief モンスターの恐慌状態値をセット /
+ * Set "m_ptr->mtimed[MTIMED_MONFEAR]", notice observable changes
+ * @param m_idx モンスター参照ID
+ * @param v セットする値
+ * @return 別途更新処理が必要な場合TRUEを返す
+ */
+bool set_monster_monfear(MONSTER_IDX m_idx, int v)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_MONFEAR(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_MONFEAR);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_MONFEAR(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_MONFEAR);
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_MONFEAR] = (s16b)v;
+
+ if (!notice) return FALSE;
+
+ if (m_ptr->ml)
+ {
+ /* Update health bar as needed */
+ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
+ }
+
+ return TRUE;
+}
+
+
+/*!
+ * @brief モンスターの無敵状態値をセット /
+ * Set "m_ptr->mtimed[MTIMED_INVULNER]", notice observable changes
+ * @param m_idx モンスター参照ID
+ * @param v セットする値
+ * @param energy_need TRUEならば無敵解除時に行動ターン消費を行う
+ * @return 別途更新処理が必要な場合TRUEを返す
+ */
+bool set_monster_invulner(MONSTER_IDX m_idx, int v, bool energy_need)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ bool notice = FALSE;
+
+ /* Hack -- Force good values */
+ v = (v > 200) ? 200 : (v < 0) ? 0 : v;
+
+ /* Open */
+ if (v)
+ {
+ if (!MON_INVULNER(m_ptr))
+ {
+ mproc_add(m_idx, MTIMED_INVULNER);
+ notice = TRUE;
+ }
+ }
+
+ /* Shut */
+ else
+ {
+ if (MON_INVULNER(m_ptr))
+ {
+ mproc_remove(m_idx, MTIMED_INVULNER);
+ if (energy_need && !p_ptr->wild_mode) m_ptr->energy_need += ENERGY_NEED();
+ notice = TRUE;
+ }
+ }
+
+ /* Use the value */
+ m_ptr->mtimed[MTIMED_INVULNER] = (s16b)v;
+
+ if (!notice) return FALSE;
+
+ if (m_ptr->ml)
+ {
+ /* Update health bar as needed */
+ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
+ }
+
+ return TRUE;
+}
+
+
+static u32b csleep_noise;
+
+/*!
+ * @brief モンスターの各種状態値を時間経過により更新するサブルーチン
+ * @param m_idx モンスター参照ID
+ * @param mtimed_idx 更新するモンスターの時限ステータスID
+ * @return なし
+ */
+static void process_monsters_mtimed_aux(MONSTER_IDX m_idx, int mtimed_idx)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+
+ switch (mtimed_idx)
+ {
+ case MTIMED_CSLEEP:
+ {
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+
+ /* Assume does not wake up */
+ bool test = FALSE;
+
+ /* Hack -- Require proximity */
+ if (m_ptr->cdis < AAF_LIMIT)
+ {
+ /* Handle "sensing radius" */
+ if (m_ptr->cdis <= (is_pet(m_ptr) ? ((r_ptr->aaf > MAX_SIGHT) ? MAX_SIGHT : r_ptr->aaf) : r_ptr->aaf))
+ {
+ /* We may wake up */
+ test = TRUE;
+ }
+
+ /* Handle "sight" and "aggravation" */
+ else if ((m_ptr->cdis <= MAX_SIGHT) && (player_has_los_bold(m_ptr->fy, m_ptr->fx)))
+ {
+ /* We may wake up */
+ test = TRUE;
+ }
+ }
+
+ if (test)
+ {
+ u32b notice = randint0(1024);