OSDN Git Service

[Refactor] #37353 PROJECT_* 定義を新規ファイル projection.h へ移動。 / Move PROJECT_* definition...
[hengband/hengband.git] / src / melee1.c
index d1ba640..13b90f1 100644 (file)
@@ -14,6 +14,9 @@
 #include "angband.h"
 #include "cmd-pet.h"
 #include "player-damage.h"
+#include "monsterrace-hook.h"
+#include "melee.h"
+#include "projection.h"
 
 
 
  * Determine if the player "hits" a monster (normal combat).
  * @param chance 基本命中値
  * @param ac モンスターのAC
- * @param vis 目標を視界に捕らえているならばTRUEを指定
+ * @param visible 目標を視界に捕らえているならばTRUEを指定
  * @return 命中と判定された場合TRUEを返す
  * @note Always miss 5%, always hit 5%, otherwise random.
  */
-bool test_hit_norm(int chance, ARMOUR_CLASS ac, int vis)
+bool test_hit_norm(HIT_RELIABILITY chance, ARMOUR_CLASS ac, bool visible)
 {
-       int k;
-
-       /* Percentile dice */
-       k = randint0(100);
-
-       /* Hack -- Instant miss or hit */
-       if (k < 10) return (k < 5);
-
-       if (p_ptr->pseikaku == SEIKAKU_NAMAKE)
-               if (one_in_(20)) return (FALSE);
-
-       /* Wimpy attack never hits */
-       if (chance <= 0) return (FALSE);
+       if (!visible) chance = (chance + 1) / 2;
+       return hit_chance(chance, ac) >= randint1(100);
+}
 
-       /* Penalize invisible targets */
-       if (!vis) chance = (chance + 1) / 2;
+/*!
+ * @brief モンスターへの命中率の計算
+ * @param to_h 命中値
+ * @param ac 敵AC
+ * @return 命中確率
+ */
+PERCENTAGE hit_chance(HIT_RELIABILITY reli, ARMOUR_CLASS ac)
+{
+       PERCENTAGE chance = 5, chance_left = 90;
 
-       /* Power must defeat armor */
-       if (randint0(chance) < (ac * 3 / 4)) return (FALSE);
+       if (p_ptr->pseikaku == SEIKAKU_NAMAKE) chance_left = (chance_left * 19 + 9) / 20;
+       chance += (100 - ((ac * 75) / reli)) * chance_left / 100;
 
-       /* Assume hit */
-       return (TRUE);
+       return chance;
 }
 
 
+
 /*!
 * @brief プレイヤーからモンスターへの打撃クリティカル判定 /
 * Critical hits (by player) Factor in weapon weight, total plusses, player melee bonus
@@ -183,10 +183,8 @@ static int check_hit(int power, DEPTH level, int stun)
        return (FALSE);
 }
 
-
-
 /*! モンスターの侮辱行為メッセージテーブル / Hack -- possible "insult" messages */
-static cptr desc_insult[] =
+static concptr desc_insult[] =
 {
 #ifdef JP
        "があなたを侮辱した!",
@@ -214,9 +212,8 @@ static cptr desc_insult[] =
 
 };
 
-
 /*! マゴットのぼやきメッセージテーブル / Hack -- possible "insult" messages */
-static cptr desc_moan[] =
+static concptr desc_moan[] =
 {
 #ifdef JP
        "は何かを悲しんでいるようだ。",
@@ -232,7 +229,6 @@ static cptr desc_moan[] =
 
 };
 
-
 /*!
 * @brief 敵オーラによるプレイヤーのダメージ処理(補助)
 * @param m_ptr オーラを持つモンスターの構造体参照ポインタ
@@ -245,13 +241,13 @@ static cptr desc_moan[] =
 * @return なし
 */
 static void touch_zap_player_aux(monster_type *m_ptr, bool immune, int flags_offset, int r_flags_offset, u32b aura_flag,
-       HIT_POINT(*dam_func)(HIT_POINT dam, cptr kb_str, int monspell, bool aura), cptr message)
+       HIT_POINT(*dam_func)(HIT_POINT dam, concptr kb_str, int monspell, bool aura), concptr message)
 {
        monster_race *r_ptr = &r_info[m_ptr->r_idx];
 
        if ((atoffset(u32b, r_ptr, flags_offset) & aura_flag) && !immune)
        {
-               char mon_name[80];
+               GAME_TEXT mon_name[MAX_NLEN];
                int aura_damage = damroll(1 + (r_ptr->level / 26), 1 + (r_ptr->level / 17));
 
                /* Hack -- Get the "died from" name */
@@ -270,9 +266,6 @@ static void touch_zap_player_aux(monster_type *m_ptr, bool immune, int flags_off
        }
 }
 
-
-
-
 /*!
 * @brief 敵オーラによるプレイヤーのダメージ処理(メイン)
 * @param m_ptr オーラを持つモンスターの構造体参照ポインタ
@@ -303,11 +296,11 @@ static void natural_attack(s16b m_idx, int attack, bool *fear, bool *mdeath)
        int             n_weight = 0;
        monster_type    *m_ptr = &m_list[m_idx];
        monster_race    *r_ptr = &r_info[m_ptr->r_idx];
-       char            m_name[80];
+       GAME_TEXT m_name[MAX_NLEN];
 
        int             dice_num, dice_side;
 
-       cptr            atk_desc;
+       concptr            atk_desc;
 
        switch (attack)
        {
@@ -355,10 +348,8 @@ static void natural_attack(s16b m_idx, int attack, bool *fear, bool *mdeath)
        /* Extract monster name (or "it") */
        monster_desc(m_name, m_ptr, 0);
 
-
        /* Calculate the "attack quality" */
-       bonus = p_ptr->to_h_m;
-       bonus += (p_ptr->lev * 6 / 5);
+       bonus = p_ptr->to_h_m + (p_ptr->lev * 6 / 5);
        chance = (p_ptr->skill_thn + (bonus * BTH_PLUS_ADJ));
 
        /* Test for hit */
@@ -416,7 +407,6 @@ static void natural_attack(s16b m_idx, int attack, bool *fear, bool *mdeath)
        else
        {
                sound(SOUND_MISS);
-
                msg_format(_("ミス! %sにかわされた。", "You miss %s."), m_name);
        }
 }
@@ -447,7 +437,7 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
        /* Access the weapon */
        object_type     *o_ptr = &inventory[INVEN_RARM + hand];
 
-       char            m_name[80];
+       GAME_TEXT m_name[MAX_NLEN];
 
        bool            success_hit = FALSE;
        bool            backstab = FALSE;
@@ -550,7 +540,6 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
        chance = (p_ptr->skill_thn + (bonus * BTH_PLUS_ADJ));
        if (mode == HISSATSU_IAI) chance += 60;
        if (p_ptr->special_defense & KATA_KOUKIJIN) chance += 150;
-
        if (p_ptr->sutemi) chance = MAX(chance * 3 / 2, chance + 60);
 
        vir = virtue_number(V_VALOUR);
@@ -650,7 +639,7 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
                        if ((have_flag(flgs, TR_VAMPIRIC)) || (chaos_effect == 1) || (mode == HISSATSU_DRAIN) || hex_spelling(HEX_VAMP_BLADE))
                        {
                                /* Only drain "living" monsters */
-                               if (monster_living(r_ptr))
+                               if (monster_living(m_ptr->r_idx))
                                        can_drain = TRUE;
                                else
                                        can_drain = FALSE;
@@ -881,13 +870,13 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
                        drain_result += p_ptr->to_d[hand];
 
                        if ((mode == HISSATSU_SUTEMI) || (mode == HISSATSU_3DAN)) k *= 2;
-                       if ((mode == HISSATSU_SEKIRYUKA) && !monster_living(r_ptr)) k = 0;
+                       if ((mode == HISSATSU_SEKIRYUKA) && !monster_living(m_ptr->r_idx)) k = 0;
                        if ((mode == HISSATSU_SEKIRYUKA) && !p_ptr->cut) k /= 2;
 
                        /* No negative damage */
                        if (k < 0) k = 0;
 
-                       if ((mode == HISSATSU_ZANMA) && !(!monster_living(r_ptr) && (r_ptr->flags3 & RF3_EVIL)))
+                       if ((mode == HISSATSU_ZANMA) && !(!monster_living(m_ptr->r_idx) && (r_ptr->flags3 & RF3_EVIL)))
                        {
                                k = 0;
                        }
@@ -1172,7 +1161,7 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
                                if (target_ptr->hold_o_idx)
                                {
                                        object_type *q_ptr = &o_list[target_ptr->hold_o_idx];
-                                       char o_name[MAX_NLEN];
+                                       GAME_TEXT o_name[MAX_NLEN];
 
                                        object_desc(o_name, q_ptr, OD_NAME_ONLY);
                                        q_ptr->held_m_idx = 0;
@@ -1193,14 +1182,12 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
 
                        if ((o_ptr->tval == TV_POLEARM) && (o_ptr->sval == SV_DEATH_SCYTHE) && one_in_(3))
                        {
-                               u32b flgs_aux[TR_FLAG_SIZE];
+                               BIT_FLAGS flgs_aux[TR_FLAG_SIZE];
 
                                sound(SOUND_HIT);
 
                                msg_format(_("ミス! %sにかわされた。", "You miss %s."), m_name);
                                msg_print(_("振り回した大鎌が自分自身に返ってきた!", "Your scythe returns to you!"));
-
-                               /* Extract the flags */
                                object_flags(o_ptr, flgs_aux);
 
                                k = damroll(o_ptr->dd + p_ptr->to_dd[hand], o_ptr->ds + p_ptr->to_ds[hand]);
@@ -1285,12 +1272,11 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
                                if (k < 0) k = 0;
 
                                take_hit(DAMAGE_FORCE, k, _("死の大鎌", "Death scythe"), -1);
-                               redraw_stuff();
+                               handle_stuff();
                        }
                        else
                        {
                                sound(SOUND_MISS);
-
                                msg_format(_("ミス! %sにかわされた。", "You miss %s."), m_name);
                        }
                }
@@ -1318,7 +1304,6 @@ static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b
        }
 }
 
-
 /*!
 * @brief プレイヤーの打撃処理メインルーチン
 * @param y 攻撃目標のY座標
@@ -1337,7 +1322,7 @@ bool py_attack(POSITION y, POSITION x, BIT_FLAGS mode)
        cave_type       *c_ptr = &cave[y][x];
        monster_type    *m_ptr = &m_list[c_ptr->m_idx];
        monster_race    *r_ptr = &r_info[m_ptr->r_idx];
-       char            m_name[80];
+       GAME_TEXT m_name[MAX_NLEN];
 
        disturb(FALSE, TRUE);
 
@@ -1456,8 +1441,8 @@ bool py_attack(POSITION y, POSITION x, BIT_FLAGS mode)
 
                if (cur < max)
                {
-                       int ridinglevel = r_info[m_list[p_ptr->riding].r_idx].level;
-                       int targetlevel = r_ptr->level;
+                       DEPTH ridinglevel = r_info[m_list[p_ptr->riding].r_idx].level;
+                       DEPTH targetlevel = r_ptr->level;
                        int inc = 0;
 
                        if ((cur / 200 - 5) < targetlevel)
@@ -1473,7 +1458,6 @@ bool py_attack(POSITION y, POSITION x, BIT_FLAGS mode)
                        }
 
                        p_ptr->skill_exp[GINOU_RIDING] = MIN(max, cur + inc);
-
                        p_ptr->update |= (PU_BONUS);
                }
        }
@@ -1513,7 +1497,6 @@ bool py_attack(POSITION y, POSITION x, BIT_FLAGS mode)
        return mdeath;
 }
 
-
 /*!
  * @brief モンスターからプレイヤーへの打撃処理 / Attack the player via physical attacks.
  * @param m_idx 打撃を行うモンスターのID
@@ -1534,9 +1517,9 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 
        object_type *o_ptr;
 
-       char o_name[MAX_NLEN];
+       GAME_TEXT o_name[MAX_NLEN];
 
-       char m_name[80];
+       GAME_TEXT m_name[MAX_NLEN];
 
        char ddesc[80];
 
@@ -1587,7 +1570,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                HIT_POINT power = 0;
                HIT_POINT damage = 0;
 
-               cptr act = NULL;
+               concptr act = NULL;
 
                /* Extract the attack infomation */
                int effect = r_ptr->blow[ap_cnt].effect;
@@ -2012,7 +1995,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                if (apply_disenchant(0))
                                                {
                                                        /* Hack -- Update AC */
-                                                       update_stuff();
+                                                       update_creature(p_ptr);
                                                        obvious = TRUE;
                                                }
                                        }
@@ -2071,8 +2054,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                        o_ptr->pval = 0;
 
                                                        /* Combine / Reorder the pack */
-                                                       p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
+                                                       p_ptr->update |= (PU_COMBINE | PU_REORDER);
                                                        p_ptr->window |= (PW_INVEN);
 
                                                        break;
@@ -2161,16 +2143,14 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 
                                                /* Occasional "blink" anyway */
                                                blinked = TRUE;
-
                                                obvious = TRUE;
-
                                                break;
                                        }
 
                                        /* Find an item */
                                        for (k = 0; k < 10; k++)
                                        {
-                                               s16b o_idx;
+                                               OBJECT_IDX o_idx;
 
                                                /* Pick an item */
                                                i = (INVENTORY_IDX)randint0(INVEN_PACK);
@@ -2202,11 +2182,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                if (o_idx)
                                                {
                                                        object_type *j_ptr;
-
-                                                       /* Get new object */
                                                        j_ptr = &o_list[o_idx];
-
-                                                       /* Copy object */
                                                        object_copy(j_ptr, o_ptr);
 
                                                        /* Modify number */
@@ -2321,18 +2297,10 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                {
                                        if (explode) break;
                                        obvious = TRUE;
-
                                        msg_print(_("酸を浴びせられた!", "You are covered in acid!"));
-
-                                       /* Special damage */
                                        get_damage += acid_dam(damage, ddesc, -1, FALSE);
-
-                                       /* Hack -- Update AC */
-                                       update_stuff();
-
-                                       /* Learn about the player */
+                                       update_creature(p_ptr);
                                        update_smart_learn(m_idx, DRS_ACID);
-
                                        break;
                                }
 
@@ -2340,15 +2308,9 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                {
                                        if (explode) break;
                                        obvious = TRUE;
-
                                        msg_print(_("電撃を浴びせられた!", "You are struck by electricity!"));
-
-                                       /* Special damage */
                                        get_damage += elec_dam(damage, ddesc, -1, FALSE);
-
-                                       /* Learn about the player */
                                        update_smart_learn(m_idx, DRS_ELEC);
-
                                        break;
                                }
 
@@ -2356,15 +2318,9 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                {
                                        if (explode) break;
                                        obvious = TRUE;
-
                                        msg_print(_("全身が炎に包まれた!", "You are enveloped in flames!"));
-
-                                       /* Special damage */
                                        get_damage += fire_dam(damage, ddesc, -1, FALSE);
-
-                                       /* Learn about the player */
                                        update_smart_learn(m_idx, DRS_FIRE);
-
                                        break;
                                }
 
@@ -2372,22 +2328,15 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                {
                                        if (explode) break;
                                        obvious = TRUE;
-
                                        msg_print(_("全身が冷気で覆われた!", "You are covered with frost!"));
-
-                                       /* Special damage */
                                        get_damage += cold_dam(damage, ddesc, -1, FALSE);
-
-                                       /* Learn about the player */
                                        update_smart_learn(m_idx, DRS_COLD);
-
                                        break;
                                }
 
                                case RBE_BLIND:
                                {
                                        get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1);
-
                                        if (p_ptr->is_dead) break;
 
                                        /* Increase "blind" */
@@ -2735,7 +2684,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
                                                        {
                                                                msg_print(_("あなたは以前ほど力強くなくなってしまった...。", "You're not as powerful as you used to be..."));
 
-                                                               for (k = 0; k < 6; k++)
+                                                               for (k = 0; k < A_MAX; k++)
                                                                {
                                                                        p_ptr->stat_cur[k] = (p_ptr->stat_cur[k] * 7) / 8;
                                                                        if (p_ptr->stat_cur[k] < 3) p_ptr->stat_cur[k] = 3;
@@ -3255,6 +3204,33 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 #endif
 
                                }
+
+                               /* Gain shield experience */
+                               if (object_is_armour(&inventory[INVEN_RARM]) || object_is_armour(&inventory[INVEN_LARM]))
+                               {
+                                       int cur = p_ptr->skill_exp[GINOU_SHIELD];
+                                       int max = s_info[p_ptr->pclass].s_max[GINOU_SHIELD];
+
+                                       if (cur < max)
+                                       {
+                                               DEPTH targetlevel = r_ptr->level;
+                                               int inc = 0;
+
+
+                                               /* Extra experience */
+                                               if ((cur / 100) < targetlevel)
+                                               {
+                                                       if ((cur / 100 + 15) < targetlevel)
+                                                               inc += 1 + (targetlevel - (cur / 100 + 15));
+                                                       else
+                                                               inc += 1;
+                                               }
+
+                                               p_ptr->skill_exp[GINOU_SHIELD] = MIN(max, cur + inc);
+                                               p_ptr->update |= (PU_BONUS);
+                                       }
+                               }
+
                                damage = 0;
 
                                break;
@@ -3278,7 +3254,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 
                if (p_ptr->riding && damage)
                {
-                       char m_steed_name[80];
+                       char m_steed_name[MAX_NLEN];
                        monster_desc(m_steed_name, &m_list[p_ptr->riding], 0);
                        if (rakuba((damage > 200) ? 200 : damage, FALSE))
                        {
@@ -3301,7 +3277,7 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 #ifdef JP
                msg_format("攻撃が%s自身を傷つけた!", m_name);
 #else
-               char m_name_self[80];
+               GAME_TEXT m_name_self[80];
 
                /* hisself */
                monster_desc(m_name_self, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE | MD_OBJECTIVE);
@@ -3314,15 +3290,13 @@ bool make_attack_normal(MONSTER_IDX m_idx)
 
        if ((p_ptr->counter || (p_ptr->special_defense & KATA_MUSOU)) && alive && !p_ptr->is_dead && m_ptr->ml && (p_ptr->csp > 7))
        {
-               char m_target_name[80];
+               char m_target_name[MAX_NLEN];
                monster_desc(m_target_name, m_ptr, 0);
 
                p_ptr->csp -= 7;
                msg_format(_("%^sに反撃した!", "Your counterattack to %s!"), m_target_name);
                py_attack(m_ptr->fy, m_ptr->fx, HISSATSU_COUNTER);
                fear = FALSE;
-
-               /* Redraw mana */
                p_ptr->redraw |= (PR_MANA);
        }