OSDN Git Service

[Refactor] #40416 Separated monster-attack-monster.c/h from melee.c/h
authorHourier <hourier@users.sourceforge.jp>
Sat, 23 May 2020 13:14:20 +0000 (22:14 +0900)
committerHourier <hourier@users.sourceforge.jp>
Sat, 23 May 2020 13:14:20 +0000 (22:14 +0900)
Hengband/Hengband/Hengband.vcxproj
Hengband/Hengband/Hengband.vcxproj.filters
src/Makefile.am
src/combat/melee.c
src/combat/melee.h
src/combat/monster-attack-monster.c [new file with mode: 0644]
src/combat/monster-attack-monster.h [new file with mode: 0644]
src/monster/monster-attack.c

index 1f53443..0a5ba3b 100644 (file)
     <ClCompile Include="..\..\src\combat\insults-moans.c" />\r
     <ClCompile Include="..\..\src\combat\martial-arts-table.c" />\r
     <ClCompile Include="..\..\src\combat\monster-attack-monster.c" />\r
+    <ClCompile Include="..\..\src\combat\monster-attack-player.c" />\r
     <ClCompile Include="..\..\src\combat\monster-attack-types.c" />\r
     <ClCompile Include="..\..\src\combat\attack-accuracy.c" />\r
     <ClCompile Include="..\..\src\combat\player-attack.c" />\r
     <ClInclude Include="..\..\src\combat\martial-arts-table.h" />\r
     <ClInclude Include="..\..\src\combat\monster-attack-effect.h" />\r
     <ClInclude Include="..\..\src\combat\monster-attack-monster.h" />\r
+    <ClInclude Include="..\..\src\combat\monster-attack-player.h" />\r
     <ClInclude Include="..\..\src\combat\monster-attack-types.h" />\r
     <ClInclude Include="..\..\src\combat\attack-accuracy.h" />\r
     <ClInclude Include="..\..\src\combat\player-attack-util.h" />\r
index c177433..d4986f4 100644 (file)
     <ClCompile Include="..\..\src\cmd\cmd-attack.c">
       <Filter>cmd</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\combat\monster-attack-player.c">
+      <Filter>combat</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\combat\monster-attack-monster.c">
       <Filter>combat</Filter>
     </ClCompile>
     <ClInclude Include="..\..\src\cmd\cmd-attack.h">
       <Filter>cmd</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\combat\monster-attack-player.h">
+      <Filter>combat</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\combat\monster-attack-monster.h">
       <Filter>combat</Filter>
     </ClInclude>
index 11817a1..e0a764a 100644 (file)
@@ -357,6 +357,7 @@ hengband_SOURCES = \
        combat/vorpal-weapon.c combat/vorpal-weapon.h \
        combat/attack-chaos-effect.c combat/attack-chaos-effect.h \
        combat/monster-attack-player.c combat/monster-attack-player.h \
+       combat/monster-attack-monster.c combat/monster-attack-monster.h \
        combat/shoot.c combat/shoot.h \
        combat/snipe.c combat/snipe.h \
        \
index de7e069..21199b9 100644 (file)
 #include "monster/monster.h"
 #include "monster/monster-status.h"
 #include "mspell/monster-spell.h"
-#include "realm/realm-hex.h"
 #include "realm/realm-song.h"
 #include "grid/grid.h"
-#include "dungeon/dungeon.h"
-#include "effect/effect-characteristics.h"
-#include "spell/process-effect.h"
-#include "spell/spells-type.h"
 #include "player/player-move.h"
-#include "player/player-status.h"
 #include "player/player-class.h"
 #include "player/player-personalities-table.h"
-#include "spell/spells-floor.h"
-#include "spell/spells3.h"
 #include "player/player-races-table.h"
-#include "combat/hallucination-attacks-table.h"
 #include "combat/monster-attack-types.h"
-#include "combat/monster-attack-effect.h"
-#include "combat/attack-accuracy.h"
 #include "mind/samurai-slaying.h"
 
-#define BLOW_EFFECT_TYPE_NONE  0
-#define BLOW_EFFECT_TYPE_FEAR  1
-#define BLOW_EFFECT_TYPE_SLEEP 2
-#define BLOW_EFFECT_TYPE_HEAL  3
-
-/*!
- * @brief モンスターから敵モンスターへの打撃攻撃処理
- * @param m_idx 攻撃側モンスターの参照ID
- * @param t_idx 目標側モンスターの参照ID
- * @return 実際に打撃処理が行われた場合TRUEを返す
- */
-bool monst_attack_monst(player_type *subject_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx)
-{
-       monster_type *m_ptr = &subject_ptr->current_floor_ptr->m_list[m_idx];
-       monster_type *t_ptr = &subject_ptr->current_floor_ptr->m_list[t_idx];
-
-       monster_race *r_ptr = &r_info[m_ptr->r_idx];
-       monster_race *tr_ptr = &r_info[t_ptr->r_idx];
-
-       int pt;
-       GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
-       char temp[MAX_NLEN];
-       bool explode = FALSE, touched = FALSE, fear = FALSE, dead = FALSE;
-       POSITION y_saver = t_ptr->fy;
-       POSITION x_saver = t_ptr->fx;
-       int effect_type;
-
-       bool see_m = is_seen(m_ptr);
-       bool see_t = is_seen(t_ptr);
-       bool see_either = see_m || see_t;
-
-       /* Can the player be aware of this attack? */
-       bool known = (m_ptr->cdis <= MAX_SIGHT) || (t_ptr->cdis <= MAX_SIGHT);
-       bool do_silly_attack = (one_in_(2) && subject_ptr->image);
-
-       if (m_idx == t_idx) return FALSE;
-       if (r_ptr->flags1 & RF1_NEVER_BLOW) return FALSE;
-       if (d_info[subject_ptr->dungeon_idx].flags1 & DF1_NO_MELEE) return FALSE;
-
-       /* Total armor */
-       ARMOUR_CLASS ac = tr_ptr->ac;
-
-       /* Extract the effective monster level */
-       DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
-
-       monster_desc(subject_ptr, m_name, m_ptr, 0);
-       monster_desc(subject_ptr, t_name, t_ptr, 0);
-
-       /* Assume no blink */
-       bool blinked = FALSE;
-
-       if (!see_either && known)
-       {
-               subject_ptr->current_floor_ptr->monster_noise = TRUE;
-       }
-
-       if (subject_ptr->riding && (m_idx == subject_ptr->riding)) disturb(subject_ptr, TRUE, TRUE);
-
-       /* Scan through all four blows */
-       for (ARMOUR_CLASS ap_cnt = 0; ap_cnt < 4; ap_cnt++)
-       {
-               bool obvious = FALSE;
-
-               HIT_POINT power = 0;
-               HIT_POINT damage = 0;
-
-               concptr act = NULL;
-
-               /* Extract the attack infomation */
-               int effect = r_ptr->blow[ap_cnt].effect;
-               rbm_type method = r_ptr->blow[ap_cnt].method;
-               int d_dice = r_ptr->blow[ap_cnt].d_dice;
-               int d_side = r_ptr->blow[ap_cnt].d_side;
-
-               if (!monster_is_valid(m_ptr)) break;
-
-               /* Stop attacking if the target dies! */
-               if (t_ptr->fx != x_saver || t_ptr->fy != y_saver)
-                       break;
-
-               /* Hack -- no more attacks */
-               if (!method) break;
-
-               if (method == RBM_SHOOT) continue;
-
-               /* Extract the attack "power" */
-               power = mbe_info[effect].power;
-
-               /* Monster hits */
-               if (!effect || check_hit_from_monster_to_monster(power, rlev, ac, MON_STUNNED(m_ptr)))
-               {
-                       (void)set_monster_csleep(subject_ptr, t_idx, 0);
-
-                       if (t_ptr->ml)
-                       {
-                               /* Redraw the health bar */
-                               if (subject_ptr->health_who == t_idx) subject_ptr->redraw |= (PR_HEALTH);
-                               if (subject_ptr->riding == t_idx) subject_ptr->redraw |= (PR_UHEALTH);
-                       }
-
-                       /* Describe the attack method */
-                       switch (method)
-                       {
-                       case RBM_HIT:
-                       {
-                               act = _("%sを殴った。", "hits %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_TOUCH:
-                       {
-                               act = _("%sを触った。", "touches %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_PUNCH:
-                       {
-                               act = _("%sをパンチした。", "punches %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_KICK:
-                       {
-                               act = _("%sを蹴った。", "kicks %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_CLAW:
-                       {
-                               act = _("%sをひっかいた。", "claws %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_BITE:
-                       {
-                               act = _("%sを噛んだ。", "bites %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_STING:
-                       {
-                               act = _("%sを刺した。", "stings %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_SLASH:
-                       {
-                               act = _("%sを斬った。", "slashes %s.");
-                               break;
-                       }
-
-                       case RBM_BUTT:
-                       {
-                               act = _("%sを角で突いた。", "butts %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_CRUSH:
-                       {
-                               act = _("%sに体当りした。", "crushes %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_ENGULF:
-                       {
-                               act = _("%sを飲み込んだ。", "engulfs %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_CHARGE:
-                       {
-                               act = _("%sに請求書をよこした。", "charges %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_CRAWL:
-                       {
-                               act = _("%sの体の上を這い回った。", "crawls on %s.");
-                               touched = TRUE;
-                               break;
-                       }
-
-                       case RBM_DROOL:
-                       {
-                               act = _("%sによだれをたらした。", "drools on %s.");
-                               touched = FALSE;
-                               break;
-                       }
-
-                       case RBM_SPIT:
-                       {
-                               act = _("%sに唾を吐いた。", "spits on %s.");
-                               touched = FALSE;
-                               break;
-                       }
-
-                       case RBM_EXPLODE:
-                       {
-                               if (see_either) disturb(subject_ptr, TRUE, TRUE);
-                               act = _("爆発した。", "explodes.");
-                               explode = TRUE;
-                               touched = FALSE;
-                               break;
-                       }
-
-                       case RBM_GAZE:
-                       {
-                               act = _("%sをにらんだ。", "gazes at %s.");
-                               touched = FALSE;
-                               break;
-                       }
-
-                       case RBM_WAIL:
-                       {
-                               act = _("%sに泣きついた。", "wails at %s.");
-                               touched = FALSE;
-                               break;
-                       }
-
-                       case RBM_SPORE:
-                       {
-                               act = _("%sに胞子を飛ばした。", "releases spores at %s.");
-                               touched = FALSE;
-                               break;
-                       }
-
-                       case RBM_XXX4:
-                       {
-                               act = _("%sにXXX4を飛ばした。", "projects XXX4's at %s.");
-                               touched = FALSE;
-                               break;
-                       }
-
-                       case RBM_BEG:
-                       {
-                               act = _("%sに金をせがんだ。", "begs %s for money.");
-                               touched = FALSE;
-                               break;
-                       }
-
-                       case RBM_INSULT:
-                       {
-                               act = _("%sを侮辱した。", "insults %s.");
-                               touched = FALSE;
-                               break;
-                       }
-
-                       case RBM_MOAN:
-                       {
-                               act = _("%sにむかってうめいた。", "moans at %s.");
-                               touched = FALSE;
-                               break;
-                       }
-
-                       case RBM_SHOW:
-                       {
-                               act = _("%sにむかって歌った。", "sings to %s.");
-                               touched = FALSE;
-                               break;
-                       }
-                       }
-
-                       if (act && see_either)
-                       {
-#ifdef JP
-                               if (do_silly_attack) act = silly_attacks2[randint0(MAX_SILLY_ATTACK)];
-                               strfmt(temp, act, t_name);
-                               msg_format("%^sは%s", m_name, temp);
-#else
-                               if (do_silly_attack)
-                               {
-                                       act = silly_attacks[randint0(MAX_SILLY_ATTACK)];
-                                       strfmt(temp, "%s %s.", act, t_name);
-                               }
-                               else strfmt(temp, act, t_name);
-                               msg_format("%^s %s", m_name, temp);
-#endif
-                       }
-
-                       /* Hack -- assume all attacks are obvious */
-                       obvious = TRUE;
-
-                       /* Roll out the damage */
-                       damage = damroll(d_dice, d_side);
-
-                       /* Assume no effect */
-                       effect_type = BLOW_EFFECT_TYPE_NONE;
-
-                       pt = GF_MISSILE;
-
-                       /* Apply appropriate damage */
-                       switch (effect)
-                       {
-                       case 0:
-                       case RBE_DR_MANA:
-                               damage = pt = 0;
-                               break;
-
-                       case RBE_SUPERHURT:
-                               if ((randint1(rlev * 2 + 250) > (ac + 200)) || one_in_(13))
-                               {
-                                       int tmp_damage = damage - (damage * ((ac < 150) ? ac : 150) / 250);
-                                       damage = MAX(damage, tmp_damage * 2);
-                                       break;
-                               }
-
-                               /* Fall through */
-
-                       case RBE_HURT:
-                               damage -= (damage * ((ac < 150) ? ac : 150) / 250);
-                               break;
-
-                       case RBE_POISON:
-                       case RBE_DISEASE:
-                               pt = GF_POIS;
-                               break;
-
-                       case RBE_UN_BONUS:
-                       case RBE_UN_POWER:
-                               pt = GF_DISENCHANT;
-                               break;
-
-                       case RBE_EAT_ITEM:
-                       case RBE_EAT_GOLD:
-                               if ((subject_ptr->riding != m_idx) && one_in_(2)) blinked = TRUE;
-                               break;
-
-                       case RBE_EAT_FOOD:
-                       case RBE_EAT_LITE:
-                       case RBE_BLIND:
-                       case RBE_LOSE_STR:
-                       case RBE_LOSE_INT:
-                       case RBE_LOSE_WIS:
-                       case RBE_LOSE_DEX:
-                       case RBE_LOSE_CON:
-                       case RBE_LOSE_CHR:
-                       case RBE_LOSE_ALL:
-                               break;
-
-                       case RBE_ACID:
-                               pt = GF_ACID;
-                               break;
-
-                       case RBE_ELEC:
-                               pt = GF_ELEC;
-                               break;
-
-                       case RBE_FIRE:
-                               pt = GF_FIRE;
-                               break;
-
-                       case RBE_COLD:
-                               pt = GF_COLD;
-                               break;
-
-                       case RBE_CONFUSE:
-                               pt = GF_CONFUSION;
-                               break;
-
-                       case RBE_TERRIFY:
-                               effect_type = BLOW_EFFECT_TYPE_FEAR;
-                               break;
-
-                       case RBE_PARALYZE:
-                               effect_type = BLOW_EFFECT_TYPE_SLEEP;
-                               break;
-
-                       case RBE_SHATTER:
-                               damage -= (damage * ((ac < 150) ? ac : 150) / 250);
-                               if (damage > 23) earthquake(subject_ptr, m_ptr->fy, m_ptr->fx, 8, m_idx);
-                               break;
-
-                       case RBE_EXP_10:
-                       case RBE_EXP_20:
-                       case RBE_EXP_40:
-                       case RBE_EXP_80:
-                               pt = GF_NETHER;
-                               break;
-
-                       case RBE_TIME:
-                               pt = GF_TIME;
-                               break;
-
-                       case RBE_DR_LIFE:
-                               pt = GF_HYPODYNAMIA;
-                               effect_type = BLOW_EFFECT_TYPE_HEAL;
-                               break;
-
-                       case RBE_INERTIA:
-                               pt = GF_INERTIAL;
-                               break;
-
-                       case RBE_STUN:
-                               pt = GF_SOUND;
-                               break;
-
-                       default:
-                               pt = 0;
-                               break;
-                       }
-
-                       if (pt)
-                       {
-                               /* Do damage if not exploding */
-                               if (!explode)
-                               {
-                                       project(subject_ptr, m_idx, 0, t_ptr->fy, t_ptr->fx,
-                                               damage, pt, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
-                               }
-
-                               switch (effect_type)
-                               {
-                               case BLOW_EFFECT_TYPE_FEAR:
-                                       project(subject_ptr, m_idx, 0, t_ptr->fy, t_ptr->fx,
-                                               damage, GF_TURN_ALL, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
-                                       break;
-
-                               case BLOW_EFFECT_TYPE_SLEEP:
-                                       project(subject_ptr, m_idx, 0, t_ptr->fy, t_ptr->fx,
-                                               r_ptr->level, GF_OLD_SLEEP, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
-                                       break;
-
-                               case BLOW_EFFECT_TYPE_HEAL:
-                                       if ((monster_living(m_idx)) && (damage > 2))
-                                       {
-                                               bool did_heal = FALSE;
-
-                                               if (m_ptr->hp < m_ptr->maxhp) did_heal = TRUE;
-
-                                               /* Heal */
-                                               m_ptr->hp += damroll(4, damage / 6);
-                                               if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
-
-                                               /* Redraw (later) if needed */
-                                               if (subject_ptr->health_who == m_idx) subject_ptr->redraw |= (PR_HEALTH);
-                                               if (subject_ptr->riding == m_idx) subject_ptr->redraw |= (PR_UHEALTH);
-
-                                               /* Special message */
-                                               if (see_m && did_heal)
-                                               {
-                                                       msg_format(_("%sは体力を回復したようだ。", "%^s appears healthier."), m_name);
-                                               }
-                                       }
-                                       break;
-                               }
-
-                               if (touched)
-                               {
-                                       /* Aura fire */
-                                       if ((tr_ptr->flags2 & RF2_AURA_FIRE) && m_ptr->r_idx)
-                                       {
-                                               if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK))
-                                               {
-                                                       if (see_either)
-                                                       {
-                                                               msg_format(_("%^sは突然熱くなった!", "%^s is suddenly very hot!"), m_name);
-                                                       }
-                                                       if (m_ptr->ml && is_original_ap_and_seen(subject_ptr, t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_FIRE;
-                                                       project(subject_ptr, t_idx, 0, m_ptr->fy, m_ptr->fx,
-                                                               damroll(1 + ((tr_ptr->level) / 26),
-                                                                       1 + ((tr_ptr->level) / 17)),
-                                                               GF_FIRE, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
-                                               }
-                                               else
-                                               {
-                                                       if (is_original_ap_and_seen(subject_ptr, m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
-                                               }
-                                       }
-
-                                       /* Aura cold */
-                                       if ((tr_ptr->flags3 & RF3_AURA_COLD) && m_ptr->r_idx)
-                                       {
-                                               if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK))
-                                               {
-                                                       if (see_either)
-                                                       {
-                                                               msg_format(_("%^sは突然寒くなった!", "%^s is suddenly very cold!"), m_name);
-                                                       }
-                                                       if (m_ptr->ml && is_original_ap_and_seen(subject_ptr, t_ptr)) tr_ptr->r_flags3 |= RF3_AURA_COLD;
-                                                       project(subject_ptr, t_idx, 0, m_ptr->fy, m_ptr->fx,
-                                                               damroll(1 + ((tr_ptr->level) / 26),
-                                                                       1 + ((tr_ptr->level) / 17)),
-                                                               GF_COLD, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
-                                               }
-                                               else
-                                               {
-                                                       if (is_original_ap_and_seen(subject_ptr, m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
-                                               }
-                                       }
-
-                                       /* Aura elec */
-                                       if ((tr_ptr->flags2 & RF2_AURA_ELEC) && m_ptr->r_idx)
-                                       {
-                                               if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK))
-                                               {
-                                                       if (see_either)
-                                                       {
-                                                               msg_format(_("%^sは電撃を食らった!", "%^s gets zapped!"), m_name);
-                                                       }
-                                                       if (m_ptr->ml && is_original_ap_and_seen(subject_ptr, t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_ELEC;
-                                                       project(subject_ptr, t_idx, 0, m_ptr->fy, m_ptr->fx,
-                                                               damroll(1 + ((tr_ptr->level) / 26),
-                                                                       1 + ((tr_ptr->level) / 17)),
-                                                               GF_ELEC, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
-                                               }
-                                               else
-                                               {
-                                                       if (is_original_ap_and_seen(subject_ptr, m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               /* Monster missed player */
-               else
-               {
-                       /* Analyze failed attacks */
-                       switch (method)
-                       {
-                       case RBM_HIT:
-                       case RBM_TOUCH:
-                       case RBM_PUNCH:
-                       case RBM_KICK:
-                       case RBM_CLAW:
-                       case RBM_BITE:
-                       case RBM_STING:
-                       case RBM_SLASH:
-                       case RBM_BUTT:
-                       case RBM_CRUSH:
-                       case RBM_ENGULF:
-                       case RBM_CHARGE:
-                       {
-                               (void)set_monster_csleep(subject_ptr, t_idx, 0);
-
-                               /* Visible monsters */
-                               if (see_m)
-                               {
-#ifdef JP
-                                       msg_format("%sは%^sの攻撃をかわした。", t_name, m_name);
-#else
-                                       msg_format("%^s misses %s.", m_name, t_name);
-#endif
-                               }
-
-                               break;
-                       }
-                       }
-               }
-
-
-               /* Analyze "visible" monsters only */
-               if (is_original_ap_and_seen(subject_ptr, m_ptr) && !do_silly_attack)
-               {
-                       /* Count "obvious" attacks (and ones that cause damage) */
-                       if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10))
-                       {
-                               /* Count attacks of this type */
-                               if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR)
-                               {
-                                       r_ptr->r_blows[ap_cnt]++;
-                               }
-                       }
-               }
-       }
-
-       if (explode)
-       {
-               sound(SOUND_EXPLODE);
-
-               /* Cancel Invulnerability */
-               (void)set_monster_invulner(subject_ptr, m_idx, 0, FALSE);
-               mon_take_hit_mon(subject_ptr, m_idx, m_ptr->hp + 1, &dead, &fear, _("は爆発して粉々になった。", " explodes into tiny shreds."), m_idx);
-               blinked = FALSE;
-       }
-
-       if (!blinked || m_ptr->r_idx == 0) return TRUE;
-
-       if (teleport_barrier(subject_ptr, m_idx))
-       {
-               if (see_m)
-               {
-                       msg_print(_("泥棒は笑って逃げ...ようとしたがバリアに防がれた。", "The thief flees laughing...? But a magic barrier obstructs it."));
-               }
-               else if (known)
-               {
-                       subject_ptr->current_floor_ptr->monster_noise = TRUE;
-               }
-       }
-       else
-       {
-               if (see_m)
-               {
-                       msg_print(_("泥棒は笑って逃げた!", "The thief flees laughing!"));
-               }
-               else if (known)
-               {
-                       subject_ptr->current_floor_ptr->monster_noise = TRUE;
-               }
-
-               teleport_away(subject_ptr, m_idx, MAX_SIGHT * 2 + 5, TELEPORT_SPONTANEOUS);
-       }
-
-       return TRUE;
-}
-
-
-
 /*!
+ * todo 打撃が当たった時の後処理 (爆発持ちのモンスターを爆発させる等)なので、関数名を変更する必要あり
  * @brief モンスターが敵モンスターに行う打撃処理 /
  * Hack, based on mon_take_hit... perhaps all monster attacks on other monsters should use this?
  * @param m_idx 目標となるモンスターの参照ID
index 6a74d10..068ad6c 100644 (file)
@@ -1,4 +1,3 @@
 #include "combat/combat-options-type.h"
 
 void mon_take_hit_mon(player_type *player_ptr, MONSTER_IDX m_idx, HIT_POINT dam, bool *dead, bool *fear, concptr note, MONSTER_IDX who);
-bool monst_attack_monst(player_type *subject_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx);
diff --git a/src/combat/monster-attack-monster.c b/src/combat/monster-attack-monster.c
new file mode 100644 (file)
index 0000000..aa16714
--- /dev/null
@@ -0,0 +1,576 @@
+#include "combat/monster-attack-monster.h"
+#include "dungeon/dungeon.h"
+#include "combat/monster-attack-effect.h"
+#include "combat/hallucination-attacks-table.h"
+#include "spell/spells-type.h"
+#include "effect/effect-characteristics.h"
+#include "main/sound-definitions-table.h"
+#include "player/player-move.h"
+#include "monster/monster-status.h"
+#include "combat/attack-accuracy.h"
+#include "spell/spells3.h"
+#include "spell/spells-floor.h"
+#include "spell/process-effect.h"
+#include "monster/monsterrace-hook.h"
+#include "realm/realm-hex.h"
+#include "combat/melee.h"
+
+#define BLOW_EFFECT_TYPE_NONE 0
+#define BLOW_EFFECT_TYPE_FEAR 1
+#define BLOW_EFFECT_TYPE_SLEEP 2
+#define BLOW_EFFECT_TYPE_HEAL 3
+
+/*!
+ * @brief モンスターから敵モンスターへの打撃攻撃処理
+ * @param m_idx 攻撃側モンスターの参照ID
+ * @param t_idx 目標側モンスターの参照ID
+ * @return 実際に打撃処理が行われた場合TRUEを返す
+ */
+bool monst_attack_monst(player_type *subject_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx)
+{
+    monster_type *m_ptr = &subject_ptr->current_floor_ptr->m_list[m_idx];
+    monster_type *t_ptr = &subject_ptr->current_floor_ptr->m_list[t_idx];
+
+    monster_race *r_ptr = &r_info[m_ptr->r_idx];
+    monster_race *tr_ptr = &r_info[t_ptr->r_idx];
+
+    int pt;
+    GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
+    char temp[MAX_NLEN];
+    bool explode = FALSE, touched = FALSE, fear = FALSE, dead = FALSE;
+    POSITION y_saver = t_ptr->fy;
+    POSITION x_saver = t_ptr->fx;
+    int effect_type;
+
+    bool see_m = is_seen(m_ptr);
+    bool see_t = is_seen(t_ptr);
+    bool see_either = see_m || see_t;
+
+    /* Can the player be aware of this attack? */
+    bool known = (m_ptr->cdis <= MAX_SIGHT) || (t_ptr->cdis <= MAX_SIGHT);
+    bool do_silly_attack = (one_in_(2) && subject_ptr->image);
+
+    if (m_idx == t_idx)
+        return FALSE;
+    if (r_ptr->flags1 & RF1_NEVER_BLOW)
+        return FALSE;
+    if (d_info[subject_ptr->dungeon_idx].flags1 & DF1_NO_MELEE)
+        return FALSE;
+
+    /* Total armor */
+    ARMOUR_CLASS ac = tr_ptr->ac;
+
+    /* Extract the effective monster level */
+    DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
+
+    monster_desc(subject_ptr, m_name, m_ptr, 0);
+    monster_desc(subject_ptr, t_name, t_ptr, 0);
+
+    /* Assume no blink */
+    bool blinked = FALSE;
+
+    if (!see_either && known) {
+        subject_ptr->current_floor_ptr->monster_noise = TRUE;
+    }
+
+    if (subject_ptr->riding && (m_idx == subject_ptr->riding))
+        disturb(subject_ptr, TRUE, TRUE);
+
+    /* Scan through all four blows */
+    for (ARMOUR_CLASS ap_cnt = 0; ap_cnt < 4; ap_cnt++) {
+        bool obvious = FALSE;
+
+        HIT_POINT power = 0;
+        HIT_POINT damage = 0;
+
+        concptr act = NULL;
+
+        /* Extract the attack infomation */
+        int effect = r_ptr->blow[ap_cnt].effect;
+        rbm_type method = r_ptr->blow[ap_cnt].method;
+        int d_dice = r_ptr->blow[ap_cnt].d_dice;
+        int d_side = r_ptr->blow[ap_cnt].d_side;
+
+        if (!monster_is_valid(m_ptr))
+            break;
+
+        /* Stop attacking if the target dies! */
+        if (t_ptr->fx != x_saver || t_ptr->fy != y_saver)
+            break;
+
+        /* Hack -- no more attacks */
+        if (!method)
+            break;
+
+        if (method == RBM_SHOOT)
+            continue;
+
+        /* Extract the attack "power" */
+        power = mbe_info[effect].power;
+
+        /* Monster hits */
+        if (!effect || check_hit_from_monster_to_monster(power, rlev, ac, MON_STUNNED(m_ptr))) {
+            (void)set_monster_csleep(subject_ptr, t_idx, 0);
+
+            if (t_ptr->ml) {
+                /* Redraw the health bar */
+                if (subject_ptr->health_who == t_idx)
+                    subject_ptr->redraw |= (PR_HEALTH);
+                if (subject_ptr->riding == t_idx)
+                    subject_ptr->redraw |= (PR_UHEALTH);
+            }
+
+            /* Describe the attack method */
+            switch (method) {
+            case RBM_HIT: {
+                act = _("%sを殴った。", "hits %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_TOUCH: {
+                act = _("%sを触った。", "touches %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_PUNCH: {
+                act = _("%sをパンチした。", "punches %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_KICK: {
+                act = _("%sを蹴った。", "kicks %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_CLAW: {
+                act = _("%sをひっかいた。", "claws %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_BITE: {
+                act = _("%sを噛んだ。", "bites %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_STING: {
+                act = _("%sを刺した。", "stings %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_SLASH: {
+                act = _("%sを斬った。", "slashes %s.");
+                break;
+            }
+
+            case RBM_BUTT: {
+                act = _("%sを角で突いた。", "butts %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_CRUSH: {
+                act = _("%sに体当りした。", "crushes %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_ENGULF: {
+                act = _("%sを飲み込んだ。", "engulfs %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_CHARGE: {
+                act = _("%sに請求書をよこした。", "charges %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_CRAWL: {
+                act = _("%sの体の上を這い回った。", "crawls on %s.");
+                touched = TRUE;
+                break;
+            }
+
+            case RBM_DROOL: {
+                act = _("%sによだれをたらした。", "drools on %s.");
+                touched = FALSE;
+                break;
+            }
+
+            case RBM_SPIT: {
+                act = _("%sに唾を吐いた。", "spits on %s.");
+                touched = FALSE;
+                break;
+            }
+
+            case RBM_EXPLODE: {
+                if (see_either)
+                    disturb(subject_ptr, TRUE, TRUE);
+                act = _("爆発した。", "explodes.");
+                explode = TRUE;
+                touched = FALSE;
+                break;
+            }
+
+            case RBM_GAZE: {
+                act = _("%sをにらんだ。", "gazes at %s.");
+                touched = FALSE;
+                break;
+            }
+
+            case RBM_WAIL: {
+                act = _("%sに泣きついた。", "wails at %s.");
+                touched = FALSE;
+                break;
+            }
+
+            case RBM_SPORE: {
+                act = _("%sに胞子を飛ばした。", "releases spores at %s.");
+                touched = FALSE;
+                break;
+            }
+
+            case RBM_XXX4: {
+                act = _("%sにXXX4を飛ばした。", "projects XXX4's at %s.");
+                touched = FALSE;
+                break;
+            }
+
+            case RBM_BEG: {
+                act = _("%sに金をせがんだ。", "begs %s for money.");
+                touched = FALSE;
+                break;
+            }
+
+            case RBM_INSULT: {
+                act = _("%sを侮辱した。", "insults %s.");
+                touched = FALSE;
+                break;
+            }
+
+            case RBM_MOAN: {
+                act = _("%sにむかってうめいた。", "moans at %s.");
+                touched = FALSE;
+                break;
+            }
+
+            case RBM_SHOW: {
+                act = _("%sにむかって歌った。", "sings to %s.");
+                touched = FALSE;
+                break;
+            }
+            }
+
+            if (act && see_either) {
+#ifdef JP
+                if (do_silly_attack)
+                    act = silly_attacks2[randint0(MAX_SILLY_ATTACK)];
+                strfmt(temp, act, t_name);
+                msg_format("%^sは%s", m_name, temp);
+#else
+                if (do_silly_attack) {
+                    act = silly_attacks[randint0(MAX_SILLY_ATTACK)];
+                    strfmt(temp, "%s %s.", act, t_name);
+                } else
+                    strfmt(temp, act, t_name);
+                msg_format("%^s %s", m_name, temp);
+#endif
+            }
+
+            /* Hack -- assume all attacks are obvious */
+            obvious = TRUE;
+
+            /* Roll out the damage */
+            damage = damroll(d_dice, d_side);
+
+            /* Assume no effect */
+            effect_type = BLOW_EFFECT_TYPE_NONE;
+
+            pt = GF_MISSILE;
+
+            /* Apply appropriate damage */
+            switch (effect) {
+            case 0:
+            case RBE_DR_MANA:
+                damage = pt = 0;
+                break;
+
+            case RBE_SUPERHURT:
+                if ((randint1(rlev * 2 + 250) > (ac + 200)) || one_in_(13)) {
+                    int tmp_damage = damage - (damage * ((ac < 150) ? ac : 150) / 250);
+                    damage = MAX(damage, tmp_damage * 2);
+                    break;
+                }
+
+                /* Fall through */
+
+            case RBE_HURT:
+                damage -= (damage * ((ac < 150) ? ac : 150) / 250);
+                break;
+
+            case RBE_POISON:
+            case RBE_DISEASE:
+                pt = GF_POIS;
+                break;
+
+            case RBE_UN_BONUS:
+            case RBE_UN_POWER:
+                pt = GF_DISENCHANT;
+                break;
+
+            case RBE_EAT_ITEM:
+            case RBE_EAT_GOLD:
+                if ((subject_ptr->riding != m_idx) && one_in_(2))
+                    blinked = TRUE;
+                break;
+
+            case RBE_EAT_FOOD:
+            case RBE_EAT_LITE:
+            case RBE_BLIND:
+            case RBE_LOSE_STR:
+            case RBE_LOSE_INT:
+            case RBE_LOSE_WIS:
+            case RBE_LOSE_DEX:
+            case RBE_LOSE_CON:
+            case RBE_LOSE_CHR:
+            case RBE_LOSE_ALL:
+                break;
+
+            case RBE_ACID:
+                pt = GF_ACID;
+                break;
+
+            case RBE_ELEC:
+                pt = GF_ELEC;
+                break;
+
+            case RBE_FIRE:
+                pt = GF_FIRE;
+                break;
+
+            case RBE_COLD:
+                pt = GF_COLD;
+                break;
+
+            case RBE_CONFUSE:
+                pt = GF_CONFUSION;
+                break;
+
+            case RBE_TERRIFY:
+                effect_type = BLOW_EFFECT_TYPE_FEAR;
+                break;
+
+            case RBE_PARALYZE:
+                effect_type = BLOW_EFFECT_TYPE_SLEEP;
+                break;
+
+            case RBE_SHATTER:
+                damage -= (damage * ((ac < 150) ? ac : 150) / 250);
+                if (damage > 23)
+                    earthquake(subject_ptr, m_ptr->fy, m_ptr->fx, 8, m_idx);
+                break;
+
+            case RBE_EXP_10:
+            case RBE_EXP_20:
+            case RBE_EXP_40:
+            case RBE_EXP_80:
+                pt = GF_NETHER;
+                break;
+
+            case RBE_TIME:
+                pt = GF_TIME;
+                break;
+
+            case RBE_DR_LIFE:
+                pt = GF_HYPODYNAMIA;
+                effect_type = BLOW_EFFECT_TYPE_HEAL;
+                break;
+
+            case RBE_INERTIA:
+                pt = GF_INERTIAL;
+                break;
+
+            case RBE_STUN:
+                pt = GF_SOUND;
+                break;
+
+            default:
+                pt = 0;
+                break;
+            }
+
+            if (pt) {
+                /* Do damage if not exploding */
+                if (!explode) {
+                    project(subject_ptr, m_idx, 0, t_ptr->fy, t_ptr->fx, damage, pt, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                }
+
+                switch (effect_type) {
+                case BLOW_EFFECT_TYPE_FEAR:
+                    project(subject_ptr, m_idx, 0, t_ptr->fy, t_ptr->fx, damage, GF_TURN_ALL, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                    break;
+
+                case BLOW_EFFECT_TYPE_SLEEP:
+                    project(subject_ptr, m_idx, 0, t_ptr->fy, t_ptr->fx, r_ptr->level, GF_OLD_SLEEP, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                    break;
+
+                case BLOW_EFFECT_TYPE_HEAL:
+                    if ((monster_living(m_idx)) && (damage > 2)) {
+                        bool did_heal = FALSE;
+
+                        if (m_ptr->hp < m_ptr->maxhp)
+                            did_heal = TRUE;
+
+                        /* Heal */
+                        m_ptr->hp += damroll(4, damage / 6);
+                        if (m_ptr->hp > m_ptr->maxhp)
+                            m_ptr->hp = m_ptr->maxhp;
+
+                        /* Redraw (later) if needed */
+                        if (subject_ptr->health_who == m_idx)
+                            subject_ptr->redraw |= (PR_HEALTH);
+                        if (subject_ptr->riding == m_idx)
+                            subject_ptr->redraw |= (PR_UHEALTH);
+
+                        /* Special message */
+                        if (see_m && did_heal) {
+                            msg_format(_("%sは体力を回復したようだ。", "%^s appears healthier."), m_name);
+                        }
+                    }
+                    break;
+                }
+
+                if (touched) {
+                    /* Aura fire */
+                    if ((tr_ptr->flags2 & RF2_AURA_FIRE) && m_ptr->r_idx) {
+                        if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK)) {
+                            if (see_either) {
+                                msg_format(_("%^sは突然熱くなった!", "%^s is suddenly very hot!"), m_name);
+                            }
+                            if (m_ptr->ml && is_original_ap_and_seen(subject_ptr, t_ptr))
+                                tr_ptr->r_flags2 |= RF2_AURA_FIRE;
+                            project(subject_ptr, t_idx, 0, m_ptr->fy, m_ptr->fx, damroll(1 + ((tr_ptr->level) / 26), 1 + ((tr_ptr->level) / 17)), GF_FIRE,
+                                PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                        } else {
+                            if (is_original_ap_and_seen(subject_ptr, m_ptr))
+                                r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
+                        }
+                    }
+
+                    /* Aura cold */
+                    if ((tr_ptr->flags3 & RF3_AURA_COLD) && m_ptr->r_idx) {
+                        if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)) {
+                            if (see_either) {
+                                msg_format(_("%^sは突然寒くなった!", "%^s is suddenly very cold!"), m_name);
+                            }
+                            if (m_ptr->ml && is_original_ap_and_seen(subject_ptr, t_ptr))
+                                tr_ptr->r_flags3 |= RF3_AURA_COLD;
+                            project(subject_ptr, t_idx, 0, m_ptr->fy, m_ptr->fx, damroll(1 + ((tr_ptr->level) / 26), 1 + ((tr_ptr->level) / 17)), GF_COLD,
+                                PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                        } else {
+                            if (is_original_ap_and_seen(subject_ptr, m_ptr))
+                                r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
+                        }
+                    }
+
+                    /* Aura elec */
+                    if ((tr_ptr->flags2 & RF2_AURA_ELEC) && m_ptr->r_idx) {
+                        if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK)) {
+                            if (see_either) {
+                                msg_format(_("%^sは電撃を食らった!", "%^s gets zapped!"), m_name);
+                            }
+                            if (m_ptr->ml && is_original_ap_and_seen(subject_ptr, t_ptr))
+                                tr_ptr->r_flags2 |= RF2_AURA_ELEC;
+                            project(subject_ptr, t_idx, 0, m_ptr->fy, m_ptr->fx, damroll(1 + ((tr_ptr->level) / 26), 1 + ((tr_ptr->level) / 17)), GF_ELEC,
+                                PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
+                        } else {
+                            if (is_original_ap_and_seen(subject_ptr, m_ptr))
+                                r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
+                        }
+                    }
+                }
+            }
+        }
+
+        /* Monster missed player */
+        else {
+            /* Analyze failed attacks */
+            switch (method) {
+            case RBM_HIT:
+            case RBM_TOUCH:
+            case RBM_PUNCH:
+            case RBM_KICK:
+            case RBM_CLAW:
+            case RBM_BITE:
+            case RBM_STING:
+            case RBM_SLASH:
+            case RBM_BUTT:
+            case RBM_CRUSH:
+            case RBM_ENGULF:
+            case RBM_CHARGE: {
+                (void)set_monster_csleep(subject_ptr, t_idx, 0);
+
+                /* Visible monsters */
+                if (see_m) {
+#ifdef JP
+                    msg_format("%sは%^sの攻撃をかわした。", t_name, m_name);
+#else
+                    msg_format("%^s misses %s.", m_name, t_name);
+#endif
+                }
+
+                break;
+            }
+            }
+        }
+
+        /* Analyze "visible" monsters only */
+        if (is_original_ap_and_seen(subject_ptr, m_ptr) && !do_silly_attack) {
+            /* Count "obvious" attacks (and ones that cause damage) */
+            if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10)) {
+                /* Count attacks of this type */
+                if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR) {
+                    r_ptr->r_blows[ap_cnt]++;
+                }
+            }
+        }
+    }
+
+    if (explode) {
+        sound(SOUND_EXPLODE);
+
+        /* Cancel Invulnerability */
+        (void)set_monster_invulner(subject_ptr, m_idx, 0, FALSE);
+        mon_take_hit_mon(subject_ptr, m_idx, m_ptr->hp + 1, &dead, &fear, _("は爆発して粉々になった。", " explodes into tiny shreds."), m_idx);
+        blinked = FALSE;
+    }
+
+    if (!blinked || m_ptr->r_idx == 0)
+        return TRUE;
+
+    if (teleport_barrier(subject_ptr, m_idx)) {
+        if (see_m) {
+            msg_print(_("泥棒は笑って逃げ...ようとしたがバリアに防がれた。", "The thief flees laughing...? But a magic barrier obstructs it."));
+        } else if (known) {
+            subject_ptr->current_floor_ptr->monster_noise = TRUE;
+        }
+    } else {
+        if (see_m) {
+            msg_print(_("泥棒は笑って逃げた!", "The thief flees laughing!"));
+        } else if (known) {
+            subject_ptr->current_floor_ptr->monster_noise = TRUE;
+        }
+
+        teleport_away(subject_ptr, m_idx, MAX_SIGHT * 2 + 5, TELEPORT_SPONTANEOUS);
+    }
+
+    return TRUE;
+}
diff --git a/src/combat/monster-attack-monster.h b/src/combat/monster-attack-monster.h
new file mode 100644 (file)
index 0000000..e475f05
--- /dev/null
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "system/angband.h"
+
+bool monst_attack_monst(player_type *subject_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx);
index 97c05ea..a17ddf8 100644 (file)
@@ -7,8 +7,8 @@
 #include "monster/monster-attack.h"
 #include "monster/monster-status.h"
 #include "dungeon/dungeon.h"
-#include "combat/melee.h" // 暫定。後で引っ越し.
 #include "combat/monster-attack-player.h"
+#include "combat/monster-attack-monster.h"
 
  /*!
   * @brief モンスターが移動した結果、そこにプレーヤーがいたら直接攻撃を行う