+int get_mproc_idx(int 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;
+}
+
+
+static void mproc_add(int m_idx, int mproc_type)
+{
+ if (mproc_max[mproc_type] < max_m_idx) mproc_list[mproc_type][mproc_max[mproc_type]++] = m_idx;
+}
+
+
+static void mproc_remove(int 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]];
+}
+
+
+/*
+ * Initialize monster process
+ */
+void mproc_init(void)
+{
+ monster_type *m_ptr;
+ int i, 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);
+ }
+ }
+}
+
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_CSLEEP]", notice observable changes
+ */
+bool set_monster_csleep(int 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] = 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;
+}
+
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_FAST]", notice observable changes
+ */
+bool set_monster_fast(int 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] = 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(int 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] = 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_STUNNED]", notice observable changes
+ */
+bool set_monster_stunned(int 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] = v;
+
+ return notice;
+}
+
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_CONFUSED]", notice observable changes
+ */
+bool set_monster_confused(int 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] = v;
+
+ return notice;
+}
+
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_MONFEAR]", notice observable changes
+ */
+bool set_monster_monfear(int 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] = 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;
+}
+
+
+/*
+ * Set "m_ptr->mtimed[MTIMED_INVULNER]", notice observable changes
+ */
+bool set_monster_invulner(int 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] = 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;
+
+static void process_monsters_mtimed_aux(int 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);
+
+ /* Nightmare monsters are more alert */
+ if (ironman_nightmare) notice /= 2;
+
+ /* Hack -- See if monster "notices" player */
+ if ((notice * notice * notice) <= csleep_noise)
+ {
+ /* Hack -- amount of "waking" */
+ /* Wake up faster near the player */
+ int d = (m_ptr->cdis < AAF_LIMIT / 2) ? (AAF_LIMIT / m_ptr->cdis) : 1;
+
+ /* Hack -- amount of "waking" is affected by speed of player */
+ d = (d * SPEED_TO_ENERGY(p_ptr->pspeed)) / 10;
+ if (d < 0) d = 1;
+
+ /* Monster wakes up "a little bit" */
+
+ /* Still asleep */
+ if (!set_monster_csleep(m_idx, MON_CSLEEP(m_ptr) - d))
+ {
+ /* Notice the "not waking up" */
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ /* Hack -- Count the ignores */
+ if (r_ptr->r_ignore < MAX_UCHAR) r_ptr->r_ignore++;
+ }
+ }
+
+ /* Just woke up */
+ else
+ {
+ /* Notice the "waking up" */
+ if (m_ptr->ml)
+ {
+ char m_name[80];
+
+ /* Acquire the monster name */
+ monster_desc(m_name, m_ptr, 0);
+
+ /* Dump a message */
+#ifdef JP
+ msg_format("%^s¤¬Ìܤò³Ð¤Þ¤·¤¿¡£", m_name);
+#else
+ msg_format("%^s wakes up.", m_name);
+#endif
+ }
+
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ /* Hack -- Count the wakings */
+ if (r_ptr->r_wake < MAX_UCHAR) r_ptr->r_wake++;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case MTIMED_FAST:
+ /* Reduce by one, note if expires */
+ if (set_monster_fast(m_idx, MON_FAST(m_ptr) - 1))
+ {
+ if (is_seen(m_ptr))
+ {
+ char m_name[80];
+
+ /* Acquire the monster name */
+ monster_desc(m_name, m_ptr, 0);
+
+ /* Dump a message */
+#ifdef JP
+ msg_format("%^s¤Ï¤â¤¦²Ã®¤µ¤ì¤Æ¤¤¤Ê¤¤¡£", m_name);
+#else
+ msg_format("%^s is no longer fast.", m_name);
+#endif
+ }
+ }
+ break;
+
+ case MTIMED_SLOW:
+ /* Reduce by one, note if expires */
+ if (set_monster_slow(m_idx, MON_SLOW(m_ptr) - 1))
+ {
+ if (is_seen(m_ptr))
+ {
+ char m_name[80];
+
+ /* Acquire the monster name */
+ monster_desc(m_name, m_ptr, 0);
+
+ /* Dump a message */
+#ifdef JP
+ msg_format("%^s¤Ï¤â¤¦¸ºÂ®¤µ¤ì¤Æ¤¤¤Ê¤¤¡£", m_name);
+#else
+ msg_format("%^s is no longer slow.", m_name);
+#endif
+ }
+ }
+ break;
+
+ case MTIMED_STUNNED:
+ {
+ int rlev = r_info[m_ptr->r_idx].level;
+
+ /* Recover from stun */
+ if (set_monster_stunned(m_idx, (randint0(10000) <= rlev * rlev) ? 0 : (MON_STUNNED(m_ptr) - 1)))
+ {
+ /* Message if visible */
+ if (is_seen(m_ptr))
+ {
+ char m_name[80];
+
+ /* Acquire the monster name */
+ monster_desc(m_name, m_ptr, 0);
+
+ /* Dump a message */
+#ifdef JP
+ msg_format("%^s¤ÏÛ¯Û°¾õÂÖ¤«¤éΩ¤Áľ¤Ã¤¿¡£", m_name);
+#else
+ msg_format("%^s is no longer stunned.", m_name);
+#endif
+ }
+ }
+ break;
+ }
+
+ case MTIMED_CONFUSED:
+ /* Reduce the confusion */
+ if (set_monster_confused(m_idx, MON_CONFUSED(m_ptr) - randint1(r_info[m_ptr->r_idx].level / 20 + 1)))
+ {
+ /* Message if visible */
+ if (is_seen(m_ptr))
+ {
+ char m_name[80];
+
+ /* Acquire the monster name */
+ monster_desc(m_name, m_ptr, 0);
+
+ /* Dump a message */
+#ifdef JP
+ msg_format("%^s¤Ïº®Í𤫤éΩ¤Áľ¤Ã¤¿¡£", m_name);
+#else
+ msg_format("%^s is no longer confused.", m_name);
+#endif
+ }
+ }
+ break;
+
+ case MTIMED_MONFEAR:
+ /* Reduce the fear */
+ if (set_monster_monfear(m_idx, MON_MONFEAR(m_ptr) - randint1(r_info[m_ptr->r_idx].level / 20 + 1)))
+ {
+ /* Visual note */
+ if (is_seen(m_ptr))
+ {
+ char m_name[80];
+#ifndef JP
+ char m_poss[80];
+
+ /* Acquire the monster possessive */
+ monster_desc(m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
+#endif
+
+ /* Acquire the monster name */
+ monster_desc(m_name, m_ptr, 0);
+
+ /* Dump a message */
+#ifdef JP
+ msg_format("%^s¤Ïͦµ¤¤ò¼è¤êÌᤷ¤¿¡£", m_name);
+#else
+ msg_format("%^s recovers %s courage.", m_name, m_poss);
+#endif
+ }
+ }
+ break;
+
+ case MTIMED_INVULNER:
+ /* Reduce by one, note if expires */
+ if (set_monster_invulner(m_idx, MON_INVULNER(m_ptr) - 1, TRUE))
+ {
+ if (is_seen(m_ptr))
+ {
+ char m_name[80];
+
+ /* Acquire the monster name */
+ monster_desc(m_name, m_ptr, 0);
+
+ /* Dump a message */
+#ifdef JP
+ msg_format("%^s¤Ï¤â¤¦ÌµÅ¨¤Ç¤Ê¤¤¡£", m_name);
+#else
+ msg_format("%^s is no longer invulnerable.", m_name);
+#endif
+ }
+ }
+ break;
+ }
+}
+
+
+/*
+ * Process the counters of monsters (once per 10 game turns)
+ *
+ * These functions are to process monsters' counters same as player's.
+ */
+void process_monsters_mtimed(int mtimed_idx)
+{
+ int i;
+ s16b *cur_mproc_list = mproc_list[mtimed_idx];
+
+ /* Hack -- calculate the "player noise" */
+ if (mtimed_idx == MTIMED_CSLEEP) csleep_noise = (1L << (30 - p_ptr->skill_stl));
+
+ /* Process the monsters (backwards) */
+ for (i = mproc_max[mtimed_idx] - 1; i >= 0; i--)
+ {
+ /* Access the monster */
+ process_monsters_mtimed_aux(cur_mproc_list[i], mtimed_idx);
+ }
+}
+
+
+void dispel_monster_status(int m_idx)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ char m_name[80];
+
+ monster_desc(m_name, m_ptr, 0);
+ if (set_monster_invulner(m_idx, 0, TRUE))
+ {
+#ifdef JP
+ if (m_ptr->ml) msg_format("%s¤Ï¤â¤¦ÌµÅ¨¤Ç¤Ï¤Ê¤¤¡£", m_name);
+#else
+ if (m_ptr->ml) msg_format("%^s is no longer invulnerable.", m_name);
+#endif
+ }
+ if (set_monster_fast(m_idx, 0))
+ {
+#ifdef JP
+ if (m_ptr->ml) msg_format("%s¤Ï¤â¤¦²Ã®¤µ¤ì¤Æ¤¤¤Ê¤¤¡£", m_name);
+#else
+ if (m_ptr->ml) msg_format("%^s is no longer fast.", m_name);
+#endif
+ }
+ if (set_monster_slow(m_idx, 0))
+ {
+#ifdef JP
+ if (m_ptr->ml) msg_format("%s¤Ï¤â¤¦¸ºÂ®¤µ¤ì¤Æ¤¤¤Ê¤¤¡£", m_name);
+#else
+ if (m_ptr->ml) msg_format("%^s is no longer slow.", m_name);
+#endif
+ }
+}
+