OSDN Git Service

[Refactor] #37353 cmd4.c を cmd-dump.c に改名して関数整理.
[hengband/hengband.git] / src / monster-status.c
index 6c7ef8a..200a2dd 100644 (file)
@@ -1,9 +1,94 @@
 #include "angband.h"
+#include "util.h"
+
+#include "cmd-dump.h"
+#include "dungeon.h"
+#include "floor.h"
+#include "grid.h"
 #include "monster.h"
 #include "monster-status.h"
+#include "monster-spell.h"
+#include "monster-process.h"
+#include "spells.h"
 #include "spells-summon.h"
 #include "monsterrace-hook.h"
 #include "object-curse.h"
+#include "artifact.h"
+#include "avatar.h"
+#include "files.h"
+#include "player-effects.h"
+#include "view-mainwindow.h"
+#include "world.h"
+
+
+/*!
+* @brief モンスターIDからPOWERFULフラグの有無を取得する /
+* @param m_idx モンスターID
+* @return POWERFULフラグがあればTRUE、なければFALSEを返す。
+*/
+bool monster_is_powerful(MONSTER_IDX m_idx)
+{
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
+       monster_race *r_ptr = &r_info[m_ptr->r_idx];
+       bool powerful = r_ptr->flags2 & RF2_POWERFUL ? TRUE : FALSE;
+       return powerful;
+}
+
+/*!
+* @brief モンスターIDからモンスターのレベルを取得する(ただし最低1を保証する) /
+* @param m_idx モンスターID
+* @return モンスターのレベル
+*/
+DEPTH monster_level_idx(MONSTER_IDX m_idx)
+{
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
+       monster_race *r_ptr = &r_info[m_ptr->r_idx];
+       DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
+       return rlev;
+}
+
+/*!
+ * @brief モンスターに与えたダメージの修正処理 /
+ * Modify the physical damage done to the monster.
+ * @param m_ptr ダメージを受けるモンスターの構造体参照ポインタ
+ * @param dam ダメージ基本値
+ * @param is_psy_spear 攻撃手段が光の剣ならばTRUE
+ * @return 修正を行った結果のダメージ量
+ * @details
+ * <pre>
+ * (for example when it's invulnerable or shielded)
+ * ToDo: Accept a damage-type to calculate the modified damage from
+ * things like fire, frost, lightning, poison, ... attacks.
+ * "type" is not yet used and should be 0.
+ * </pre>
+ */
+HIT_POINT mon_damage_mod(monster_type *m_ptr, HIT_POINT dam, bool is_psy_spear)
+{
+       monster_race *r_ptr = &r_info[m_ptr->r_idx];
+
+       if ((r_ptr->flagsr & RFR_RES_ALL) && dam > 0)
+       {
+               dam /= 100;
+               if ((dam == 0) && one_in_(3)) dam = 1;
+       }
+
+       if (MON_INVULNER(m_ptr))
+       {
+               if (is_psy_spear)
+               {
+                       if (!p_ptr->blind && is_seen(m_ptr))
+                       {
+                               msg_print(_("バリアを切り裂いた!", "The barrier is penetrated!"));
+                       }
+               }
+               else if (!one_in_(PENETRATE_INVULNERABILITY))
+               {
+                       return (0);
+               }
+       }
+       return (dam);
+}
+
 
 
 /*!
@@ -29,7 +114,7 @@ static void get_exp_from_mon(HIT_POINT dam, monster_type *m_ptr)
        s32b div_h;
        u32b div_l;
 
-       if (!m_ptr->r_idx) return;
+       if (!monster_is_valid(m_ptr)) return;
        if (is_pet(m_ptr) || p_ptr->inside_battle) return;
 
        /*
@@ -49,7 +134,7 @@ static void get_exp_from_mon(HIT_POINT dam, monster_type *m_ptr)
                s64b_mul(&div_h, &div_l, 0, r_ptr->hdice * (ironman_nightmare ? 2 : 1) * r_ptr->hside * 2);
 
        /* Special penalty in the wilderness */
-       if (!dun_level && (!(r_ptr->flags8 & RF8_WILD_ONLY) || !(r_ptr->flags1 & RF1_UNIQUE)))
+       if (!current_floor_ptr->dun_level && (!(r_ptr->flags8 & RF8_WILD_ONLY) || !(r_ptr->flags1 & RF1_UNIQUE)))
                s64b_mul(&div_h, &div_l, 0, 5);
 
        /* Do division first to prevent overflaw */
@@ -99,10 +184,10 @@ static void get_exp_from_mon(HIT_POINT dam, monster_type *m_ptr)
 */
 int get_mproc_idx(MONSTER_IDX m_idx, int mproc_type)
 {
-       s16b *cur_mproc_list = mproc_list[mproc_type];
+       s16b *cur_mproc_list = current_floor_ptr->mproc_list[mproc_type];
        int i;
 
-       for (i = mproc_max[mproc_type] - 1; i >= 0; i--)
+       for (i = current_floor_ptr->mproc_max[mproc_type] - 1; i >= 0; i--)
        {
                if (cur_mproc_list[i] == m_idx) return i;
        }
@@ -118,7 +203,7 @@ int get_mproc_idx(MONSTER_IDX m_idx, int mproc_type)
 */
 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;
+       if (current_floor_ptr->mproc_max[mproc_type] < current_floor_ptr->max_m_idx) current_floor_ptr->mproc_list[mproc_type][current_floor_ptr->mproc_max[mproc_type]++] = (s16b)m_idx;
 }
 
 
@@ -131,7 +216,7 @@ static void mproc_add(MONSTER_IDX m_idx, int mproc_type)
 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]];
+       if (mproc_idx >= 0) current_floor_ptr->mproc_list[mproc_type][mproc_idx] = current_floor_ptr->mproc_list[mproc_type][--current_floor_ptr->mproc_max[mproc_type]];
 }
 
 
@@ -145,17 +230,17 @@ void mproc_init(void)
        MONSTER_IDX i;
        int cmi;
 
-       /* Reset "mproc_max[]" */
-       for (cmi = 0; cmi < MAX_MTIMED; cmi++) mproc_max[cmi] = 0;
+       /* Reset "current_floor_ptr->mproc_max[]" */
+       for (cmi = 0; cmi < MAX_MTIMED; cmi++) current_floor_ptr->mproc_max[cmi] = 0;
 
        /* Process the monsters (backwards) */
-       for (i = m_max - 1; i >= 1; i--)
+       for (i = current_floor_ptr->m_max - 1; i >= 1; i--)
        {
                /* Access the monster */
-               m_ptr = &m_list[i];
+               m_ptr = &current_floor_ptr->m_list[i];
 
                /* Ignore "dead" monsters */
-               if (!m_ptr->r_idx) continue;
+               if (!monster_is_valid(m_ptr)) continue;
 
                for (cmi = 0; cmi < MAX_MTIMED; cmi++)
                {
@@ -166,7 +251,7 @@ void mproc_init(void)
 
 
 /*!
-* @brief モンスターの睡眠状態値をセットする /
+* @brief モンスターの睡眠状態値をセットする。0で起きる。 /
 * Set "m_ptr->mtimed[MTIMED_CSLEEP]", notice observable changes
 * @param m_idx モンスター参照ID
 * @param v セットする値
@@ -174,10 +259,8 @@ void mproc_init(void)
 */
 bool set_monster_csleep(MONSTER_IDX m_idx, int v)
 {
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
        bool notice = FALSE;
-
-       /* Hack -- Force good values */
        v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
 
        /* Open */
@@ -227,10 +310,8 @@ bool set_monster_csleep(MONSTER_IDX m_idx, int v)
 */
 bool set_monster_fast(MONSTER_IDX m_idx, int v)
 {
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
        bool notice = FALSE;
-
-       /* Hack -- Force good values */
        v = (v > 200) ? 200 : (v < 0) ? 0 : v;
 
        /* Open */
@@ -269,10 +350,8 @@ bool set_monster_fast(MONSTER_IDX m_idx, int v)
 */
 bool set_monster_slow(MONSTER_IDX m_idx, int v)
 {
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
        bool notice = FALSE;
-
-       /* Hack -- Force good values */
        v = (v > 200) ? 200 : (v < 0) ? 0 : v;
 
        /* Open */
@@ -315,10 +394,8 @@ bool set_monster_slow(MONSTER_IDX m_idx, int v)
 */
 bool set_monster_stunned(MONSTER_IDX m_idx, int v)
 {
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
        bool notice = FALSE;
-
-       /* Hack -- Force good values */
        v = (v > 200) ? 200 : (v < 0) ? 0 : v;
 
        /* Open */
@@ -357,10 +434,8 @@ bool set_monster_stunned(MONSTER_IDX m_idx, int v)
 */
 bool set_monster_confused(MONSTER_IDX m_idx, int v)
 {
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
        bool notice = FALSE;
-
-       /* Hack -- Force good values */
        v = (v > 200) ? 200 : (v < 0) ? 0 : v;
 
        /* Open */
@@ -399,10 +474,8 @@ bool set_monster_confused(MONSTER_IDX m_idx, int v)
 */
 bool set_monster_monfear(MONSTER_IDX m_idx, int v)
 {
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
        bool notice = FALSE;
-
-       /* Hack -- Force good values */
        v = (v > 200) ? 200 : (v < 0) ? 0 : v;
 
        /* Open */
@@ -451,10 +524,8 @@ bool set_monster_monfear(MONSTER_IDX m_idx, int v)
 */
 bool set_monster_invulner(MONSTER_IDX m_idx, int v, bool energy_need)
 {
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
        bool notice = FALSE;
-
-       /* Hack -- Force good values */
        v = (v > 200) ? 200 : (v < 0) ? 0 : v;
 
        /* Open */
@@ -504,7 +575,7 @@ static u32b csleep_noise;
 */
 static void process_monsters_mtimed_aux(MONSTER_IDX m_idx, int mtimed_idx)
 {
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
 
        switch (mtimed_idx)
        {
@@ -695,13 +766,13 @@ static void process_monsters_mtimed_aux(MONSTER_IDX m_idx, int mtimed_idx)
 void process_monsters_mtimed(int mtimed_idx)
 {
        int  i;
-       s16b *cur_mproc_list = mproc_list[mtimed_idx];
+       s16b *cur_mproc_list = current_floor_ptr->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--)
+       for (i = current_floor_ptr->mproc_max[mtimed_idx] - 1; i >= 0; i--)
        {
                /* Access the monster */
                process_monsters_mtimed_aux(cur_mproc_list[i], mtimed_idx);
@@ -715,7 +786,7 @@ void process_monsters_mtimed(int mtimed_idx)
 */
 void dispel_monster_status(MONSTER_IDX m_idx)
 {
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
        GAME_TEXT m_name[MAX_NLEN];
 
        monster_desc(m_name, m_ptr, 0);
@@ -740,11 +811,11 @@ void dispel_monster_status(MONSTER_IDX m_idx)
 * @param vs_player TRUEならば時間停止開始処理を行う
 * @return 時間停止が行われている状態ならばTRUEを返す
 */
-bool process_the_world(int num, MONSTER_IDX who, bool vs_player)
+bool set_monster_timewalk(int num, MONSTER_IDX who, bool vs_player)
 {
-       monster_type *m_ptr = &m_list[hack_m_idx];  /* the world monster */
+       monster_type *m_ptr = &current_floor_ptr->m_list[hack_m_idx];  /* the world monster */
 
-       if (world_monster) return (FALSE);
+       if (current_world_ptr->timewalk_m_idx) return (FALSE);
 
        if (vs_player)
        {
@@ -761,14 +832,14 @@ bool process_the_world(int num, MONSTER_IDX who, bool vs_player)
        }
 
        /* This monster cast spells */
-       world_monster = hack_m_idx;
+       current_world_ptr->timewalk_m_idx = hack_m_idx;
 
        if (vs_player) do_cmd_redraw();
 
        while (num--)
        {
-               if (!m_ptr->r_idx) break;
-               process_monster(world_monster);
+               if (!monster_is_valid(m_ptr)) break;
+               process_monster(current_world_ptr->timewalk_m_idx);
                reset_target(m_ptr);
                handle_stuff();
 
@@ -779,7 +850,7 @@ bool process_the_world(int num, MONSTER_IDX who, bool vs_player)
        p_ptr->update |= (PU_MONSTERS);
        p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
 
-       world_monster = 0;
+       current_world_ptr->timewalk_m_idx = 0;
        if (vs_player || (player_has_los_bold(m_ptr->fy, m_ptr->fx) && projectable(p_ptr->y, p_ptr->x, m_ptr->fy, m_ptr->fx)))
        {
                msg_print(_("「時は動きだす…」", "You feel time flowing around you once more."));
@@ -796,20 +867,17 @@ bool process_the_world(int num, MONSTER_IDX who, bool vs_player)
 * @param s_idx 撃破されたモンスター種族の参照ID
 * @return なし
 */
-void monster_gain_exp(MONSTER_IDX m_idx, IDX s_idx)
+void monster_gain_exp(MONSTER_IDX m_idx, MONRACE_IDX s_idx)
 {
        monster_type *m_ptr;
        monster_race *r_ptr;
        monster_race *s_ptr;
        int new_exp;
-
-       /* Paranoia */
        if (m_idx <= 0 || s_idx <= 0) return;
 
-       m_ptr = &m_list[m_idx];
+       m_ptr = &current_floor_ptr->m_list[m_idx];
 
-       /* Paranoia -- Skip dead monsters */
-       if (!m_ptr->r_idx) return;
+       if (!monster_is_valid(m_ptr)) return;
 
        r_ptr = &r_info[m_ptr->r_idx];
        s_ptr = &r_info[s_idx];
@@ -820,7 +888,7 @@ void monster_gain_exp(MONSTER_IDX m_idx, IDX s_idx)
 
        new_exp = s_ptr->mexp * s_ptr->level / (r_ptr->level + 2);
        if (m_idx == p_ptr->riding) new_exp = (new_exp + 1) / 2;
-       if (!dun_level) new_exp /= 5;
+       if (!current_floor_ptr->dun_level) new_exp /= 5;
        m_ptr->exp += new_exp;
        if (m_ptr->mflag2 & MFLAG2_CHAMELEON) return;
 
@@ -940,7 +1008,7 @@ void monster_gain_exp(MONSTER_IDX m_idx, IDX s_idx)
  */
 bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
 {
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
        monster_race *r_ptr = &r_info[m_ptr->r_idx];
        monster_type exp_mon;
 
@@ -956,7 +1024,7 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
        get_exp_from_mon(expdam, &exp_mon);
 
        /* Genocided by chaos patron */
-       if (!m_ptr->r_idx) m_idx = 0;
+       if (!monster_is_valid(m_ptr)) m_idx = 0;
 
        /* Redraw (later) if needed */
        if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
@@ -1088,15 +1156,15 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
 #endif
                }
 
-               if (!(d_info[dungeon_type].flags1 & DF1_BEGINNER))
+               if (!(d_info[p_ptr->dungeon_idx].flags1 & DF1_BEGINNER))
                {
-                       if (!dun_level && !ambush_flag && !p_ptr->inside_arena)
+                       if (!current_floor_ptr->dun_level && !p_ptr->ambush_flag && !p_ptr->inside_arena)
                        {
                                chg_virtue(V_VALOUR, -1);
                        }
-                       else if (r_ptr->level > dun_level)
+                       else if (r_ptr->level > current_floor_ptr->dun_level)
                        {
-                               if (randint1(10) <= (r_ptr->level - dun_level))
+                               if (randint1(10) <= (r_ptr->level - current_floor_ptr->dun_level))
                                        chg_virtue(V_VALOUR, 1);
                        }
                        if (r_ptr->level > 60)
@@ -1125,14 +1193,14 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
                        chg_virtue(V_COMPASSION, -1);
                }
 
-               if ((r_ptr->flags3 & RF3_GOOD) && ((r_ptr->level) / 10 + (3 * dun_level) >= randint1(100)))
+               if ((r_ptr->flags3 & RF3_GOOD) && ((r_ptr->level) / 10 + (3 * current_floor_ptr->dun_level) >= randint1(100)))
                        chg_virtue(V_UNLIFE, 1);
 
                if (r_ptr->d_char == 'A')
                {
                        if (r_ptr->flags1 & RF1_UNIQUE)
                                chg_virtue(V_FAITH, -2);
-                       else if ((r_ptr->level) / 10 + (3 * dun_level) >= randint1(100))
+                       else if ((r_ptr->level) / 10 + (3 * current_floor_ptr->dun_level) >= randint1(100))
                        {
                                if (r_ptr->flags3 & RF3_GOOD) chg_virtue(V_FAITH, -1);
                                else chg_virtue(V_FAITH, 1);
@@ -1142,7 +1210,7 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
                {
                        if (r_ptr->flags1 & RF1_UNIQUE)
                                chg_virtue(V_FAITH, 2);
-                       else if ((r_ptr->level) / 10 + (3 * dun_level) >= randint1(100))
+                       else if ((r_ptr->level) / 10 + (3 * current_floor_ptr->dun_level) >= randint1(100))
                                chg_virtue(V_FAITH, 1);
                }
 
@@ -1155,7 +1223,7 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
                        {
                                chg_virtue(V_HONOUR, 10);
                        }
-                       else if ((r_ptr->level) / 10 + (2 * dun_level) >= randint1(100))
+                       else if ((r_ptr->level) / 10 + (2 * current_floor_ptr->dun_level) >= randint1(100))
                        {
                                chg_virtue(V_HONOUR, 1);
                        }
@@ -1182,7 +1250,7 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
                {
                        if (r_ptr->flags1 & RF1_UNIQUE)
                                chg_virtue(V_JUSTICE, 3);
-                       else if (1 + ((r_ptr->level) / 10 + (2 * dun_level)) >= randint1(100))
+                       else if (1 + ((r_ptr->level) / 10 + (2 * current_floor_ptr->dun_level)) >= randint1(100))
                                chg_virtue(V_JUSTICE, 1);
                }
                else if (innocent)
@@ -1215,7 +1283,7 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
                else if (!m_ptr->ml)
                {
 #ifdef JP
-                       if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
+                       if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON))
                                msg_format("せっかくだから%sを殺した。", m_name);
                        else
                                msg_format("%sを殺した。", m_name);
@@ -1241,7 +1309,7 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
                        else
                        {
 #ifdef JP
-                               if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
+                               if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON))
                                        msg_format("せっかくだから%sを倒した。", m_name);
                                else
                                        msg_format("%sを倒した。", m_name);
@@ -1255,7 +1323,7 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
                else
                {
 #ifdef JP
-                       if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
+                       if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON))
                                msg_format("せっかくだから%sを葬り去った。", m_name);
                        else
                                msg_format("%sを葬り去った。", m_name);
@@ -1268,7 +1336,7 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
                {
                        for (i = 0; i < MAX_KUBI; i++)
                        {
-                               if ((kubi_r_idx[i] == m_ptr->r_idx) && !(m_ptr->mflag2 & MFLAG2_CHAMELEON))
+                               if ((current_world_ptr->bounty_r_idx[i] == m_ptr->r_idx) && !(m_ptr->mflag2 & MFLAG2_CHAMELEON))
                                {
                                        msg_format(_("%sの首には賞金がかかっている。", "There is a price on %s's head."), m_name);
                                        break;
@@ -1348,3 +1416,7 @@ bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
        return (FALSE);
 }
 
+bool monster_is_valid(monster_type *m_ptr)
+{
+       return (m_ptr->r_idx != 0);
+}
\ No newline at end of file