OSDN Git Service

[Fix] 打撃効果 RBE_NONE の警告メッセージが出るバグを修正
[hengbandforosx/hengbandosx.git] / src / monster-attack / monster-attack-player.c
index 0818eff..62ecb41 100644 (file)
 #include "combat/aura-counterattack.h"
 #include "combat/combat-options-type.h"
 #include "combat/hallucination-attacks-table.h"
+#include "core/disturbance.h"
+#include "core/player-update-types.h"
+#include "dungeon/dungeon-flag-types.h"
 #include "dungeon/dungeon.h"
 #include "effect/effect-characteristics.h"
+#include "effect/effect-processor.h"
+#include "inventory/inventory-slot-types.h"
 #include "main/sound-definitions-table.h"
 #include "main/sound-of-music.h"
 #include "mind/mind-ninja.h"
 #include "monster-race/monster-race.h"
 #include "monster-race/race-flags1.h"
 #include "monster-race/race-flags3.h"
-#include "monster/monster-description-types.h"
 #include "monster/monster-describer.h"
-#include "monster/monster-status.h"
+#include "monster/monster-description-types.h"
 #include "monster/monster-info.h"
+#include "monster/monster-status.h"
 #include "monster/smart-learn-types.h"
 #include "object-hook/hook-armor.h"
 #include "object/item-tester-hooker.h"
 #include "pet/pet-fall-off.h"
-#include "player/bad-status-setter.h"
+#include "player/attack-defense-types.h"
 #include "player/player-damage.h"
-#include "player/player-effects.h"
-#include "player/player-move.h"
 #include "player/player-skill.h"
 #include "player/special-defense-types.h"
 #include "realm/realm-hex-numbers.h"
 #include "spell-kind/spells-teleport.h"
+#include "spell-realm/spells-crusade.h"
 #include "spell-realm/spells-hex.h"
-#include "spell/process-effect.h"
 #include "spell/spell-types.h"
+#include "status/action-setter.h"
+#include "status/bad-status-setter.h"
+#include "system/floor-type-definition.h"
 #include "view/display-messages.h"
 
 static bool check_no_blow(player_type *target_ptr, monap_type *monap_ptr)
@@ -67,7 +73,7 @@ static bool check_no_blow(player_type *target_ptr, monap_type *monap_ptr)
  * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
  * @return 攻撃続行ならばTRUE、打ち切りになったらFALSE
  */
-static bool check_monster_attack_terminated(player_type *target_ptr, monap_type *monap_ptr)
+static bool check_monster_continuous_attack(player_type *target_ptr, monap_type *monap_ptr)
 {
     if (!monster_is_valid(monap_ptr->m_ptr))
         return FALSE;
@@ -267,7 +273,7 @@ static void describe_attack_evasion(player_type *target_ptr, monap_type *monap_p
 
 static void gain_armor_exp(player_type *target_ptr, monap_type *monap_ptr)
 {
-    if (!object_is_armour(target_ptr, &target_ptr->inventory_list[INVEN_RARM]) && !object_is_armour(target_ptr, &target_ptr->inventory_list[INVEN_LARM]))
+    if (!object_is_armour(target_ptr, &target_ptr->inventory_list[INVEN_MAIN_HAND]) && !object_is_armour(target_ptr, &target_ptr->inventory_list[INVEN_SUB_HAND]))
         return;
 
     int cur = target_ptr->skill_exp[GINOU_SHIELD];
@@ -350,55 +356,96 @@ static void process_monster_attack_evasion(player_type *target_ptr, monap_type *
     }
 }
 
-static void increase_blow_type_seen(player_type *target_ptr, monap_type *monap_ptr)
+/*!
+ * @brief モンスターの打撃情報を蓄積させる
+ * @param target_ptr プレーヤーへの参照ポインタ
+ * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
+ * @param ap_cnt モンスターの打撃 N回目
+ * @return なし
+ */
+static void increase_blow_type_seen(player_type *target_ptr, monap_type *monap_ptr, const int ap_cnt)
 {
+    // どの敵が何をしてきたか正しく認識できていなければならない。
     if (!is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr) || monap_ptr->do_silly_attack)
         return;
 
     monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
-    if (!monap_ptr->obvious && (monap_ptr->damage == 0) && (r_ptr->r_blows[monap_ptr->ap_cnt] <= 10))
+
+    // 非自明な類の打撃については、そのダメージが 0 ならば基本的に知識が増えない。
+    // ただし、既に一定以上の知識があれば常に知識が増える(何をされたのか察知できる)。
+    if (!monap_ptr->obvious && (monap_ptr->damage == 0) && (r_ptr->r_blows[ap_cnt] <= 10))
         return;
 
-    if (r_ptr->r_blows[monap_ptr->ap_cnt] < MAX_UCHAR)
-        r_ptr->r_blows[monap_ptr->ap_cnt]++;
+    if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR)
+        r_ptr->r_blows[ap_cnt]++;
 }
 
+/*!
+ * @brief モンスターからプレイヤーへの打撃処理本体
+ * @return 打撃に反応してプレイヤーがその場から離脱したかどうか
+ */
 static bool process_monster_blows(player_type *target_ptr, monap_type *monap_ptr)
 {
     monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
-    for (monap_ptr->ap_cnt = 0; monap_ptr->ap_cnt < 4; monap_ptr->ap_cnt++) {
+
+    for (int ap_cnt = 0; ap_cnt < MAX_NUM_BLOWS; ap_cnt++) {
         monap_ptr->obvious = FALSE;
-        HIT_POINT power = 0;
         monap_ptr->damage = 0;
         monap_ptr->act = NULL;
-        monap_ptr->effect = r_ptr->blow[monap_ptr->ap_cnt].effect;
-        monap_ptr->method = r_ptr->blow[monap_ptr->ap_cnt].method;
-        monap_ptr->d_dice = r_ptr->blow[monap_ptr->ap_cnt].d_dice;
-        monap_ptr->d_side = r_ptr->blow[monap_ptr->ap_cnt].d_side;
+        monap_ptr->effect = r_ptr->blow[ap_cnt].effect;
+        monap_ptr->method = r_ptr->blow[ap_cnt].method;
+        monap_ptr->d_dice = r_ptr->blow[ap_cnt].d_dice;
+        monap_ptr->d_side = r_ptr->blow[ap_cnt].d_side;
 
-        if (!check_monster_attack_terminated(target_ptr, monap_ptr))
+        if (!check_monster_continuous_attack(target_ptr, monap_ptr))
             break;
 
+        // effect が RBE_NONE (無効値)になることはあり得ないはずだが、万一そう
+        // なっていたら単に攻撃を打ち切る。
+        // r_info.txt の "B:" トークンに effect 以降を書き忘れた場合が該当する。
+        if (monap_ptr->effect == RBE_NONE) {
+            plog("unexpected: monap_ptr->effect == RBE_NONE");
+            break;
+        }
+
         if (monap_ptr->method == RBM_SHOOT)
             continue;
 
-        power = mbe_info[monap_ptr->effect].power;
+        // フレーバーの打撃は必中扱い。それ以外は通常の命中判定を行う。
         monap_ptr->ac = target_ptr->ac + target_ptr->to_a;
-        if ((monap_ptr->effect == RBE_NONE)
-            || check_hit_from_monster_to_player(target_ptr, power, monap_ptr->rlev, monster_stunned_remaining(monap_ptr->m_ptr)))
-            if (!process_monster_attack_hit(target_ptr, monap_ptr))
+        bool hit;
+        if (monap_ptr->effect == RBE_FLAVOR) {
+            hit = TRUE;
+        } else {
+            const int power = mbe_info[monap_ptr->effect].power;
+            hit = (bool)check_hit_from_monster_to_player(target_ptr, power, monap_ptr->rlev, monster_stunned_remaining(monap_ptr->m_ptr));
+        }
+
+        if (hit) {
+            // 命中した。命中処理と思い出処理を行う。
+            // 打撃そのものは対邪悪結界で撃退した可能性がある。
+            const bool protect = !process_monster_attack_hit(target_ptr, monap_ptr);
+            increase_blow_type_seen(target_ptr, monap_ptr, ap_cnt);
+
+            // 撃退成功時はそのまま次の打撃へ移行。
+            if (protect)
                 continue;
-            else
-                process_monster_attack_evasion(target_ptr, monap_ptr);
-
-        increase_blow_type_seen(target_ptr, monap_ptr);
-        check_fall_off_horse(target_ptr, monap_ptr);
-        if (target_ptr->special_defense & NINJA_KAWARIMI) {
-            if (kawarimi(target_ptr, FALSE))
-                return TRUE;
+
+            // 撃退失敗時は落馬処理、変わり身のテレポート処理を行う。
+            check_fall_off_horse(target_ptr, monap_ptr);
+            if (target_ptr->special_defense & NINJA_KAWARIMI) {
+                // 変わり身のテレポートが成功したら攻撃を打ち切り、プレイヤーが離脱した旨を返す。
+                if (kawarimi(target_ptr, FALSE))
+                    return TRUE;
+            }
+        } else {
+            // 命中しなかった。回避時の処理、思い出処理を行う。
+            process_monster_attack_evasion(target_ptr, monap_ptr);
+            increase_blow_type_seen(target_ptr, monap_ptr, ap_cnt);
         }
     }
 
+    // 通常はプレイヤーはその場にとどまる。
     return FALSE;
 }
 
@@ -416,7 +463,7 @@ static void eyes_on_eyes(player_type *target_ptr, monap_type *monap_ptr)
 #ifdef JP
     msg_format("攻撃が%s自身を傷つけた!", monap_ptr->m_name);
 #else
-    GAME_TEXT m_name_self[80];
+    GAME_TEXT m_name_self[MAX_MONSTER_NAME];
     monster_desc(target_ptr, m_name_self, monap_ptr->m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE | MD_OBJECTIVE);
     msg_format("The attack of %s has wounded %s!", monap_ptr->m_name, m_name_self);
 #endif
@@ -466,7 +513,8 @@ bool make_attack_normal(player_type *target_ptr, MONSTER_IDX m_idx)
 {
     monap_type tmp_monap;
     monap_type *monap_ptr = initialize_monap_type(target_ptr, &tmp_monap, m_idx);
-    check_no_blow(target_ptr, monap_ptr);
+    if (!check_no_blow(target_ptr, monap_ptr))
+        return FALSE;
 
     monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
     monap_ptr->rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);