OSDN Git Service

[WIP] [Refactor] #39963 Separated process-effect./h from spells.h/spells1.c
authorHourier <hourier@users.sourceforge.jp>
Mon, 4 May 2020 13:36:56 +0000 (22:36 +0900)
committerHourier <hourier@users.sourceforge.jp>
Mon, 4 May 2020 13:37:40 +0000 (22:37 +0900)
Hengband_vcs2017/Hengband/Hengband.vcxproj
Hengband_vcs2017/Hengband/Hengband.vcxproj.filters
src/Makefile.am
src/spell/process-effect.c [new file with mode: 0644]
src/spell/process-effect.h [new file with mode: 0644]
src/spells.h
src/spells1.c

index f4976c0..7bfa7e6 100644 (file)
     <ClCompile Include="..\..\src\realm\realm-nature.c" />\r
     <ClCompile Include="..\..\src\realm\realm-song.c" />\r
     <ClCompile Include="..\..\src\realm\realm-sorcery.c" />\r
+    <ClCompile Include="..\..\src\spell\process-effect.c" />\r
     <ClCompile Include="..\..\src\spell\spells-execution.c" />\r
     <ClCompile Include="..\..\src\spell\technic-info-table.c" />\r
     <ClInclude Include="..\..\src\artifact.h" />\r
     <ClInclude Include="..\..\src\room\pit-nest-kinds-table.h" />\r
     <ClInclude Include="..\..\src\io\signal-handlers.h" />\r
     <ClInclude Include="..\..\src\io\uid-checker.h" />\r
+    <ClInclude Include="..\..\src\spell\process-effect.h" />\r
     <ClInclude Include="..\..\src\spell\spells-type.h" />\r
     <ClInclude Include="..\..\src\spell\spells-util.h" />\r
     <ClInclude Include="..\..\src\spell\spells-execution.h" />\r
index d7d5e43..48ca90a 100644 (file)
     <ClCompile Include="..\..\src\effect\effect-player-spirit.c">
       <Filter>effect</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\spell\process-effect.c">
+      <Filter>spell</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\gamevalue.h" />
     <ClInclude Include="..\..\src\effect\effect-player-spirit.h">
       <Filter>effect</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\spell\process-effect.h">
+      <Filter>spell</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\src\wall.bmp" />
index 5e37084..b512d77 100644 (file)
@@ -190,6 +190,7 @@ hengband_SOURCES = \
        spell/technic-info-table.c spell/technic-info-table.h \
        spell/spells-execution.c spell/spells-execution.h \
        spell/spells-util.h spell/spells-type.h \
+       spell/process-effect.h spell/process-effect.h \
        spells.h \
        spells1.c spells2.c spells3.c \
        spells-diceroll.c spells-diceroll.h \
diff --git a/src/spell/process-effect.c b/src/spell/process-effect.c
new file mode 100644 (file)
index 0000000..c4c2a66
--- /dev/null
@@ -0,0 +1,844 @@
+#include "angband.h"
+#include "cmd-pet.h" // 暫定、後で消すかも.
+#include "core.h"    // 暫定、後で消す.
+#include "effect/effect-feature.h"
+#include "effect/effect-item.h"
+#include "effect/effect-monster.h"
+#include "effect/effect-player.h"
+#include "effect/spells-effect-util.h"
+#include "gameterm.h"
+#include "main/sound-definitions-table.h"
+#include "spell/process-effect.h"
+#include "spell/spells-type.h"
+#include "spells.h"
+#include "view/display-main-window.h" // 暫定、後で消すかも.
+
+/*!
+ * @brief 配置した鏡リストの次を取得する /
+ * Get another mirror. for SEEKER
+ * @param next_y 次の鏡のy座標を返す参照ポインタ
+ * @param next_x 次の鏡のx座標を返す参照ポインタ
+ * @param cury 現在の鏡のy座標
+ * @param curx 現在の鏡のx座標
+ */
+static void next_mirror(player_type *creature_ptr, POSITION *next_y,
+                        POSITION *next_x, POSITION cury, POSITION curx) {
+  POSITION mirror_x[10], mirror_y[10]; /* 鏡はもっと少ない */
+  int mirror_num = 0;                  /* 鏡の数 */
+  for (POSITION x = 0; x < creature_ptr->current_floor_ptr->width; x++) {
+    for (POSITION y = 0; y < creature_ptr->current_floor_ptr->height; y++) {
+      if (is_mirror_grid(&creature_ptr->current_floor_ptr->grid_array[y][x])) {
+        mirror_y[mirror_num] = y;
+        mirror_x[mirror_num] = x;
+        mirror_num++;
+      }
+    }
+  }
+
+  if (mirror_num) {
+    int num = randint0(mirror_num);
+    *next_y = mirror_y[num];
+    *next_x = mirror_x[num];
+    return;
+  }
+
+  *next_y = cury + randint0(5) - 2;
+  *next_x = curx + randint0(5) - 2;
+}
+
+/*!
+ * todo 似たような処理が山ほど並んでいる、何とかならないものか
+ * @brief 汎用的なビーム/ボルト/ボール系処理のルーチン Generic
+ * "beam"/"bolt"/"ball" projection routine.
+ * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source"
+ * monster (zero for "player")
+ * @param rad 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion
+ * (0 = beam/bolt, 1 to 9 = ball)
+ * @param y 目標Y座標 / Target y location (or location to travel "towards")
+ * @param x 目標X座標 / Target x location (or location to travel "towards")
+ * @param dam 基本威力 / Base damage roll to apply to affected monsters (or
+ * player)
+ * @param typ 効果属性 / Type of damage to apply to monsters (and objects)
+ * @param flag 効果フラグ / Extra bit flags (see PROJECT_xxxx)
+ * @param monspell 効果元のモンスター魔法ID
+ * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the
+ * projection were observed, else FALSE
+ */
+bool project(player_type *caster_ptr, MONSTER_IDX who, POSITION rad, POSITION y,
+             POSITION x, HIT_POINT dam, EFFECT_ID typ, BIT_FLAGS flag,
+             int monspell) {
+  int i, t, dist;
+  POSITION y1, x1;
+  POSITION y2, x2;
+  POSITION by, bx;
+  int dist_hack = 0;
+  POSITION y_saver, x_saver; /* For reflecting monsters */
+  int msec = delay_factor * delay_factor * delay_factor;
+  bool notice = FALSE;
+  bool visual = FALSE;
+  bool drawn = FALSE;
+  bool breath = FALSE;
+  bool blind = caster_ptr->blind != 0;
+  bool old_hide = FALSE;
+  int path_n = 0;
+  u16b path_g[512];
+  int grids = 0;
+  POSITION gx[1024], gy[1024];
+  POSITION gm[32];
+  POSITION gm_rad = rad;
+  bool jump = FALSE;
+  GAME_TEXT who_name[MAX_NLEN];
+  bool see_s_msg = TRUE;
+  who_name[0] = '\0';
+  rakubadam_p = 0;
+  rakubadam_m = 0;
+  monster_target_y = caster_ptr->y;
+  monster_target_x = caster_ptr->x;
+
+  if (flag & (PROJECT_JUMP)) {
+    x1 = x;
+    y1 = y;
+    flag &= ~(PROJECT_JUMP);
+    jump = TRUE;
+  } else if (who <= 0) {
+    x1 = caster_ptr->x;
+    y1 = caster_ptr->y;
+  } else if (who > 0) {
+    x1 = caster_ptr->current_floor_ptr->m_list[who].fx;
+    y1 = caster_ptr->current_floor_ptr->m_list[who].fy;
+    monster_desc(caster_ptr, who_name,
+                 &caster_ptr->current_floor_ptr->m_list[who],
+                 MD_WRONGDOER_NAME);
+  } else {
+    x1 = x;
+    y1 = y;
+  }
+
+  y_saver = y1;
+  x_saver = x1;
+  y2 = y;
+  x2 = x;
+
+  if (flag & (PROJECT_THRU)) {
+    if ((x1 == x2) && (y1 == y2)) {
+      flag &= ~(PROJECT_THRU);
+    }
+  }
+
+  if (rad < 0) {
+    rad = 0 - rad;
+    breath = TRUE;
+    if (flag & PROJECT_HIDE)
+      old_hide = TRUE;
+    flag |= PROJECT_HIDE;
+  }
+
+  for (dist = 0; dist < 32; dist++)
+    gm[dist] = 0;
+
+  y = y1;
+  x = x1;
+  dist = 0;
+  if (flag & (PROJECT_BEAM)) {
+    gy[grids] = y;
+    gx[grids] = x;
+    grids++;
+  }
+
+  switch (typ) {
+  case GF_LITE:
+  case GF_LITE_WEAK:
+    if (breath || (flag & PROJECT_BEAM))
+      flag |= (PROJECT_LOS);
+    break;
+  case GF_DISINTEGRATE:
+    flag |= (PROJECT_GRID);
+    if (breath || (flag & PROJECT_BEAM))
+      flag |= (PROJECT_DISI);
+    break;
+  }
+
+  /* Calculate the projection path */
+  path_n = project_path(caster_ptr, path_g,
+                        (project_length ? project_length : MAX_RANGE), y1, x1,
+                        y2, x2, flag);
+  handle_stuff(caster_ptr);
+
+  if (typ == GF_SEEKER) {
+    int j;
+    int last_i = 0;
+    project_m_n = 0;
+    project_m_x = 0;
+    project_m_y = 0;
+    for (i = 0; i < path_n; ++i) {
+      POSITION oy = y;
+      POSITION ox = x;
+      POSITION ny = GRID_Y(path_g[i]);
+      POSITION nx = GRID_X(path_g[i]);
+      y = ny;
+      x = nx;
+      gy[grids] = y;
+      gx[grids] = x;
+      grids++;
+
+      if (!blind && !(flag & (PROJECT_HIDE))) {
+        if (panel_contains(y, x) && player_has_los_bold(caster_ptr, y, x)) {
+          u16b p = bolt_pict(oy, ox, y, x, typ);
+          TERM_COLOR a = PICT_A(p);
+          SYMBOL_CODE c = PICT_C(p);
+          print_rel(caster_ptr, c, a, y, x);
+          move_cursor_relative(y, x);
+          Term_fresh();
+          Term_xtra(TERM_XTRA_DELAY, msec);
+          lite_spot(caster_ptr, y, x);
+          Term_fresh();
+          if (flag & (PROJECT_BEAM)) {
+            p = bolt_pict(y, x, y, x, typ);
+            a = PICT_A(p);
+            c = PICT_C(p);
+            print_rel(caster_ptr, c, a, y, x);
+          }
+
+          visual = TRUE;
+        } else if (visual) {
+          Term_xtra(TERM_XTRA_DELAY, msec);
+        }
+      }
+
+      if (affect_item(caster_ptr, 0, 0, y, x, dam, GF_SEEKER))
+        notice = TRUE;
+      if (!is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[y][x]))
+        continue;
+
+      monster_target_y = y;
+      monster_target_x = x;
+      remove_mirror(caster_ptr, y, x);
+      next_mirror(caster_ptr, &oy, &ox, y, x);
+      path_n = i + project_path(caster_ptr, &(path_g[i + 1]),
+                                (project_length ? project_length : MAX_RANGE),
+                                y, x, oy, ox, flag);
+      for (j = last_i; j <= i; j++) {
+        y = GRID_Y(path_g[j]);
+        x = GRID_X(path_g[j]);
+        if (affect_monster(caster_ptr, 0, 0, y, x, dam, GF_SEEKER, flag, TRUE))
+          notice = TRUE;
+        if (!who && (project_m_n == 1) && !jump &&
+            (caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x]
+                 .m_idx > 0)) {
+          monster_type *m_ptr =
+              &caster_ptr->current_floor_ptr
+                   ->m_list[caster_ptr->current_floor_ptr
+                                ->grid_array[project_m_y][project_m_x]
+                                .m_idx];
+          if (m_ptr->ml) {
+            if (!caster_ptr->image)
+              monster_race_track(caster_ptr, m_ptr->ap_r_idx);
+            health_track(caster_ptr, caster_ptr->current_floor_ptr
+                                         ->grid_array[project_m_y][project_m_x]
+                                         .m_idx);
+          }
+        }
+
+        (void)affect_feature(caster_ptr, 0, 0, y, x, dam, GF_SEEKER);
+      }
+
+      last_i = i;
+    }
+
+    for (i = last_i; i < path_n; i++) {
+      POSITION py, px;
+      py = GRID_Y(path_g[i]);
+      px = GRID_X(path_g[i]);
+      if (affect_monster(caster_ptr, 0, 0, py, px, dam, GF_SEEKER, flag, TRUE))
+        notice = TRUE;
+      if (!who && (project_m_n == 1) && !jump) {
+        if (caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x]
+                .m_idx > 0) {
+          monster_type *m_ptr =
+              &caster_ptr->current_floor_ptr
+                   ->m_list[caster_ptr->current_floor_ptr
+                                ->grid_array[project_m_y][project_m_x]
+                                .m_idx];
+
+          if (m_ptr->ml) {
+            if (!caster_ptr->image)
+              monster_race_track(caster_ptr, m_ptr->ap_r_idx);
+            health_track(caster_ptr, caster_ptr->current_floor_ptr
+                                         ->grid_array[project_m_y][project_m_x]
+                                         .m_idx);
+          }
+        }
+      }
+
+      (void)affect_feature(caster_ptr, 0, 0, py, px, dam, GF_SEEKER);
+    }
+
+    return notice;
+  } else if (typ == GF_SUPER_RAY) {
+    int j;
+    int second_step = 0;
+    project_m_n = 0;
+    project_m_x = 0;
+    project_m_y = 0;
+    for (i = 0; i < path_n; ++i) {
+      POSITION oy = y;
+      POSITION ox = x;
+      POSITION ny = GRID_Y(path_g[i]);
+      POSITION nx = GRID_X(path_g[i]);
+      y = ny;
+      x = nx;
+      gy[grids] = y;
+      gx[grids] = x;
+      grids++;
+      {
+        if (panel_contains(y, x) && player_has_los_bold(caster_ptr, y, x)) {
+          u16b p;
+          TERM_COLOR a;
+          SYMBOL_CODE c;
+          p = bolt_pict(oy, ox, y, x, typ);
+          a = PICT_A(p);
+          c = PICT_C(p);
+          print_rel(caster_ptr, c, a, y, x);
+          move_cursor_relative(y, x);
+          Term_fresh();
+          Term_xtra(TERM_XTRA_DELAY, msec);
+          lite_spot(caster_ptr, y, x);
+          Term_fresh();
+          if (flag & (PROJECT_BEAM)) {
+            p = bolt_pict(y, x, y, x, typ);
+            a = PICT_A(p);
+            c = PICT_C(p);
+            print_rel(caster_ptr, c, a, y, x);
+          }
+
+          visual = TRUE;
+        } else if (visual) {
+          Term_xtra(TERM_XTRA_DELAY, msec);
+        }
+      }
+
+      if (affect_item(caster_ptr, 0, 0, y, x, dam, GF_SUPER_RAY))
+        notice = TRUE;
+      if (!cave_have_flag_bold(caster_ptr->current_floor_ptr, y, x,
+                               FF_PROJECT)) {
+        if (second_step)
+          continue;
+        break;
+      }
+
+      if (is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[y][x]) &&
+          !second_step) {
+        monster_target_y = y;
+        monster_target_x = x;
+        remove_mirror(caster_ptr, y, x);
+        for (j = 0; j <= i; j++) {
+          y = GRID_Y(path_g[j]);
+          x = GRID_X(path_g[j]);
+          (void)affect_feature(caster_ptr, 0, 0, y, x, dam, GF_SUPER_RAY);
+        }
+
+        path_n = i;
+        second_step = i + 1;
+        path_n += project_path(caster_ptr, &(path_g[path_n + 1]),
+                               (project_length ? project_length : MAX_RANGE), y,
+                               x, y - 1, x - 1, flag);
+        path_n += project_path(caster_ptr, &(path_g[path_n + 1]),
+                               (project_length ? project_length : MAX_RANGE), y,
+                               x, y - 1, x, flag);
+        path_n += project_path(caster_ptr, &(path_g[path_n + 1]),
+                               (project_length ? project_length : MAX_RANGE), y,
+                               x, y - 1, x + 1, flag);
+        path_n += project_path(caster_ptr, &(path_g[path_n + 1]),
+                               (project_length ? project_length : MAX_RANGE), y,
+                               x, y, x - 1, flag);
+        path_n += project_path(caster_ptr, &(path_g[path_n + 1]),
+                               (project_length ? project_length : MAX_RANGE), y,
+                               x, y, x + 1, flag);
+        path_n += project_path(caster_ptr, &(path_g[path_n + 1]),
+                               (project_length ? project_length : MAX_RANGE), y,
+                               x, y + 1, x - 1, flag);
+        path_n += project_path(caster_ptr, &(path_g[path_n + 1]),
+                               (project_length ? project_length : MAX_RANGE), y,
+                               x, y + 1, x, flag);
+        path_n += project_path(caster_ptr, &(path_g[path_n + 1]),
+                               (project_length ? project_length : MAX_RANGE), y,
+                               x, y + 1, x + 1, flag);
+      }
+    }
+
+    for (i = 0; i < path_n; i++) {
+      POSITION py = GRID_Y(path_g[i]);
+      POSITION px = GRID_X(path_g[i]);
+      (void)affect_monster(caster_ptr, 0, 0, py, px, dam, GF_SUPER_RAY, flag,
+                           TRUE);
+      if (!who && (project_m_n == 1) && !jump) {
+        if (caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x]
+                .m_idx > 0) {
+          monster_type *m_ptr =
+              &caster_ptr->current_floor_ptr
+                   ->m_list[caster_ptr->current_floor_ptr
+                                ->grid_array[project_m_y][project_m_x]
+                                .m_idx];
+
+          if (m_ptr->ml) {
+            if (!caster_ptr->image)
+              monster_race_track(caster_ptr, m_ptr->ap_r_idx);
+            health_track(caster_ptr, caster_ptr->current_floor_ptr
+                                         ->grid_array[project_m_y][project_m_x]
+                                         .m_idx);
+          }
+        }
+      }
+
+      (void)affect_feature(caster_ptr, 0, 0, py, px, dam, GF_SUPER_RAY);
+    }
+
+    return notice;
+  }
+
+  for (i = 0; i < path_n; ++i) {
+    POSITION oy = y;
+    POSITION ox = x;
+    POSITION ny = GRID_Y(path_g[i]);
+    POSITION nx = GRID_X(path_g[i]);
+    if (flag & PROJECT_DISI) {
+      if (cave_stop_disintegration(caster_ptr->current_floor_ptr, ny, nx) &&
+          (rad > 0))
+        break;
+    } else if (flag & PROJECT_LOS) {
+      if (!cave_los_bold(caster_ptr->current_floor_ptr, ny, nx) && (rad > 0))
+        break;
+    } else {
+      if (!cave_have_flag_bold(caster_ptr->current_floor_ptr, ny, nx,
+                               FF_PROJECT) &&
+          (rad > 0))
+        break;
+    }
+
+    y = ny;
+    x = nx;
+    if (flag & (PROJECT_BEAM)) {
+      gy[grids] = y;
+      gx[grids] = x;
+      grids++;
+    }
+
+    if (!blind && !(flag & (PROJECT_HIDE | PROJECT_FAST))) {
+      if (panel_contains(y, x) && player_has_los_bold(caster_ptr, y, x)) {
+        u16b p;
+        TERM_COLOR a;
+        SYMBOL_CODE c;
+        p = bolt_pict(oy, ox, y, x, typ);
+        a = PICT_A(p);
+        c = PICT_C(p);
+        print_rel(caster_ptr, c, a, y, x);
+        move_cursor_relative(y, x);
+        Term_fresh();
+        Term_xtra(TERM_XTRA_DELAY, msec);
+        lite_spot(caster_ptr, y, x);
+        Term_fresh();
+        if (flag & (PROJECT_BEAM)) {
+          p = bolt_pict(y, x, y, x, typ);
+          a = PICT_A(p);
+          c = PICT_C(p);
+          print_rel(caster_ptr, c, a, y, x);
+        }
+
+        visual = TRUE;
+      } else if (visual) {
+        Term_xtra(TERM_XTRA_DELAY, msec);
+      }
+    }
+  }
+
+  path_n = i;
+  by = y;
+  bx = x;
+  if (breath && !path_n) {
+    breath = FALSE;
+    gm_rad = rad;
+    if (!old_hide) {
+      flag &= ~(PROJECT_HIDE);
+    }
+  }
+
+  gm[0] = 0;
+  gm[1] = grids;
+  dist = path_n;
+  dist_hack = dist;
+  project_length = 0;
+
+  /* If we found a "target", explode there */
+  if (dist <= MAX_RANGE) {
+    if ((flag & (PROJECT_BEAM)) && (grids > 0))
+      grids--;
+
+    /*
+     * Create a conical breath attack
+     *
+     *       ***
+     *   ********
+     * D********@**
+     *   ********
+     *       ***
+     */
+    if (breath) {
+      flag &= ~(PROJECT_HIDE);
+      breath_shape(caster_ptr, path_g, dist, &grids, gx, gy, gm, &gm_rad, rad,
+                   y1, x1, by, bx, typ);
+    } else {
+      for (dist = 0; dist <= rad; dist++) {
+        for (y = by - dist; y <= by + dist; y++) {
+          for (x = bx - dist; x <= bx + dist; x++) {
+            if (!in_bounds2(caster_ptr->current_floor_ptr, y, x))
+              continue;
+            if (distance(by, bx, y, x) != dist)
+              continue;
+
+            switch (typ) {
+            case GF_LITE:
+            case GF_LITE_WEAK:
+              if (!los(caster_ptr, by, bx, y, x))
+                continue;
+              break;
+            case GF_DISINTEGRATE:
+              if (!in_disintegration_range(caster_ptr->current_floor_ptr, by,
+                                           bx, y, x))
+                continue;
+              break;
+            default:
+              if (!projectable(caster_ptr, by, bx, y, x))
+                continue;
+              break;
+            }
+
+            gy[grids] = y;
+            gx[grids] = x;
+            grids++;
+          }
+        }
+
+        gm[dist + 1] = grids;
+      }
+    }
+  }
+
+  if (!grids)
+    return FALSE;
+
+  if (!blind && !(flag & (PROJECT_HIDE))) {
+    for (t = 0; t <= gm_rad; t++) {
+      for (i = gm[t]; i < gm[t + 1]; i++) {
+        y = gy[i];
+        x = gx[i];
+        if (panel_contains(y, x) && player_has_los_bold(caster_ptr, y, x)) {
+          u16b p;
+          TERM_COLOR a;
+          SYMBOL_CODE c;
+          drawn = TRUE;
+          p = bolt_pict(y, x, y, x, typ);
+          a = PICT_A(p);
+          c = PICT_C(p);
+          print_rel(caster_ptr, c, a, y, x);
+        }
+      }
+
+      move_cursor_relative(by, bx);
+      Term_fresh();
+      if (visual || drawn) {
+        Term_xtra(TERM_XTRA_DELAY, msec);
+      }
+    }
+
+    if (drawn) {
+      for (i = 0; i < grids; i++) {
+        y = gy[i];
+        x = gx[i];
+        if (panel_contains(y, x) && player_has_los_bold(caster_ptr, y, x)) {
+          lite_spot(caster_ptr, y, x);
+        }
+      }
+
+      move_cursor_relative(by, bx);
+      Term_fresh();
+    }
+  }
+
+  update_creature(caster_ptr);
+
+  if (flag & PROJECT_KILL) {
+    see_s_msg = (who > 0) ? is_seen(&caster_ptr->current_floor_ptr->m_list[who])
+                          : (!who ? TRUE
+                                  : (player_can_see_bold(caster_ptr, y1, x1) &&
+                                     projectable(caster_ptr, caster_ptr->y,
+                                                 caster_ptr->x, y1, x1)));
+  }
+
+  if (flag & (PROJECT_GRID)) {
+    dist = 0;
+    for (i = 0; i < grids; i++) {
+      if (gm[dist + 1] == i)
+        dist++;
+      y = gy[i];
+      x = gx[i];
+      if (breath) {
+        int d = dist_to_line(y, x, y1, x1, by, bx);
+        if (affect_feature(caster_ptr, who, d, y, x, dam, typ))
+          notice = TRUE;
+      } else {
+        if (affect_feature(caster_ptr, who, dist, y, x, dam, typ))
+          notice = TRUE;
+      }
+    }
+  }
+
+  update_creature(caster_ptr);
+  if (flag & (PROJECT_ITEM)) {
+    dist = 0;
+    for (i = 0; i < grids; i++) {
+      if (gm[dist + 1] == i)
+        dist++;
+
+      y = gy[i];
+      x = gx[i];
+      if (breath) {
+        int d = dist_to_line(y, x, y1, x1, by, bx);
+        if (affect_item(caster_ptr, who, d, y, x, dam, typ))
+          notice = TRUE;
+      } else {
+        if (affect_item(caster_ptr, who, dist, y, x, dam, typ))
+          notice = TRUE;
+      }
+    }
+  }
+
+  if (flag & (PROJECT_KILL)) {
+    project_m_n = 0;
+    project_m_x = 0;
+    project_m_y = 0;
+    dist = 0;
+    for (i = 0; i < grids; i++) {
+      int effective_dist;
+      if (gm[dist + 1] == i)
+        dist++;
+
+      y = gy[i];
+      x = gx[i];
+      if (grids <= 1) {
+        monster_type *m_ptr =
+            &caster_ptr->current_floor_ptr->m_list
+                 [caster_ptr->current_floor_ptr->grid_array[y][x].m_idx];
+        monster_race *ref_ptr = &r_info[m_ptr->r_idx];
+        if ((flag & PROJECT_REFLECTABLE) &&
+            caster_ptr->current_floor_ptr->grid_array[y][x].m_idx &&
+            (ref_ptr->flags2 & RF2_REFLECTING) &&
+            ((caster_ptr->current_floor_ptr->grid_array[y][x].m_idx !=
+              caster_ptr->riding) ||
+             !(flag & PROJECT_PLAYER)) &&
+            (!who || dist_hack > 1) && !one_in_(10)) {
+          POSITION t_y, t_x;
+          int max_attempts = 10;
+          do {
+            t_y = y_saver - 1 + randint1(3);
+            t_x = x_saver - 1 + randint1(3);
+            max_attempts--;
+          } while (max_attempts &&
+                   in_bounds2u(caster_ptr->current_floor_ptr, t_y, t_x) &&
+                   !projectable(caster_ptr, y, x, t_y, t_x));
+
+          if (max_attempts < 1) {
+            t_y = y_saver;
+            t_x = x_saver;
+          }
+
+          sound(SOUND_REFLECT);
+          if (is_seen(m_ptr)) {
+            if ((m_ptr->r_idx == MON_KENSHIROU) || (m_ptr->r_idx == MON_RAOU))
+              msg_print(
+                  _("「北斗神拳奥義・二指真空把!」", "The attack bounces!"));
+            else if (m_ptr->r_idx == MON_DIO)
+              msg_print(_("ディオ・ブランドーは指一本で攻撃を弾き返した!",
+                          "The attack bounces!"));
+            else
+              msg_print(_("攻撃は跳ね返った!", "The attack bounces!"));
+          }
+
+          if (is_original_ap_and_seen(caster_ptr, m_ptr))
+            ref_ptr->r_flags2 |= RF2_REFLECTING;
+
+          if (player_bold(caster_ptr, y, x) || one_in_(2))
+            flag &= ~(PROJECT_PLAYER);
+          else
+            flag |= PROJECT_PLAYER;
+
+          project(caster_ptr,
+                  caster_ptr->current_floor_ptr->grid_array[y][x].m_idx, 0, t_y,
+                  t_x, dam, typ, flag, monspell);
+          continue;
+        }
+      }
+
+      /* Find the closest point in the blast */
+      if (breath) {
+        effective_dist = dist_to_line(y, x, y1, x1, by, bx);
+      } else {
+        effective_dist = dist;
+      }
+
+      if (caster_ptr->riding && player_bold(caster_ptr, y, x)) {
+        if (flag & PROJECT_PLAYER) {
+          if (flag & (PROJECT_BEAM | PROJECT_REFLECTABLE | PROJECT_AIMED)) {
+            /*
+             * A beam or bolt is well aimed
+             * at the PLAYER!
+             * So don't affects the mount.
+             */
+            continue;
+          } else {
+            /*
+             * The spell is not well aimed,
+             * So partly affect the mount too.
+             */
+            effective_dist++;
+          }
+        }
+
+        /*
+         * This grid is the original target.
+         * Or aimed on your horse.
+         */
+        else if (((y == y2) && (x == x2)) || (flag & PROJECT_AIMED)) {
+          /* Hit the mount with full damage */
+        }
+
+        /*
+         * Otherwise this grid is not the
+         * original target, it means that line
+         * of fire is obstructed by this
+         * monster.
+         */
+        /*
+         * A beam or bolt will hit either
+         * player or mount.  Choose randomly.
+         */
+        else if (flag & (PROJECT_BEAM | PROJECT_REFLECTABLE)) {
+          if (one_in_(2)) {
+            /* Hit the mount with full damage */
+          } else {
+            flag |= PROJECT_PLAYER;
+            continue;
+          }
+        }
+
+        /*
+         * The spell is not well aimed, so
+         * partly affect both player and
+         * mount.
+         */
+        else {
+          effective_dist++;
+        }
+      }
+
+      if (affect_monster(caster_ptr, who, effective_dist, y, x, dam, typ, flag,
+                         see_s_msg))
+        notice = TRUE;
+    }
+
+    /* Player affected one monster (without "jumping") */
+    if (!who && (project_m_n == 1) && !jump) {
+      x = project_m_x;
+      y = project_m_y;
+      if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx > 0) {
+        monster_type *m_ptr =
+            &caster_ptr->current_floor_ptr->m_list
+                 [caster_ptr->current_floor_ptr->grid_array[y][x].m_idx];
+
+        if (m_ptr->ml) {
+          if (!caster_ptr->image)
+            monster_race_track(caster_ptr, m_ptr->ap_r_idx);
+          health_track(caster_ptr,
+                       caster_ptr->current_floor_ptr->grid_array[y][x].m_idx);
+        }
+      }
+    }
+  }
+
+  if (flag & (PROJECT_KILL)) {
+    dist = 0;
+    for (i = 0; i < grids; i++) {
+      int effective_dist;
+      if (gm[dist + 1] == i)
+        dist++;
+
+      y = gy[i];
+      x = gx[i];
+      if (!player_bold(caster_ptr, y, x))
+        continue;
+
+      /* Find the closest point in the blast */
+      if (breath) {
+        effective_dist = dist_to_line(y, x, y1, x1, by, bx);
+      } else {
+        effective_dist = dist;
+      }
+
+      if (caster_ptr->riding) {
+        if (flag & PROJECT_PLAYER) {
+          /* Hit the player with full damage */
+        }
+
+        /*
+         * Hack -- When this grid was not the
+         * original target, a beam or bolt
+         * would hit either player or mount,
+         * and should be choosen randomly.
+         *
+         * But already choosen to hit the
+         * mount at this point.
+         *
+         * Or aimed on your horse.
+         */
+        else if (flag & (PROJECT_BEAM | PROJECT_REFLECTABLE | PROJECT_AIMED)) {
+          /*
+           * A beam or bolt is well aimed
+           * at the mount!
+           * So don't affects the player.
+           */
+          continue;
+        } else {
+          /*
+           * The spell is not well aimed,
+           * So partly affect the player too.
+           */
+          effective_dist++;
+        }
+      }
+
+      if (affect_player(who, caster_ptr, who_name, effective_dist, y, x, dam,
+                        typ, flag, monspell, project))
+        notice = TRUE;
+    }
+  }
+
+  if (caster_ptr->riding) {
+    GAME_TEXT m_name[MAX_NLEN];
+    monster_desc(caster_ptr, m_name,
+                 &caster_ptr->current_floor_ptr->m_list[caster_ptr->riding], 0);
+    if (rakubadam_m > 0) {
+      if (rakuba(caster_ptr, rakubadam_m, FALSE)) {
+        msg_format(_("%^sに振り落とされた!", "%^s has thrown you off!"),
+                   m_name);
+      }
+    }
+
+    if (caster_ptr->riding && rakubadam_p > 0) {
+      if (rakuba(caster_ptr, rakubadam_p, FALSE)) {
+        msg_format(_("%^sから落ちてしまった!", "You have fallen from %s."),
+                   m_name);
+      }
+    }
+  }
+
+  return (notice);
+}
diff --git a/src/spell/process-effect.h b/src/spell/process-effect.h
new file mode 100644 (file)
index 0000000..58dbce1
--- /dev/null
@@ -0,0 +1,5 @@
+#pragma once
+
+bool project(player_type *caster_ptr, MONSTER_IDX who, POSITION rad, POSITION y,
+             POSITION x, HIT_POINT dam, EFFECT_ID typ, BIT_FLAGS flg,
+             int monspell);
index ed4ae81..26493ed 100644 (file)
@@ -5,7 +5,6 @@
 extern bool in_disintegration_range(floor_type *floor_ptr, POSITION y1, POSITION x1, POSITION y2, POSITION x2);
 extern void breath_shape(player_type *caster_ptr, u16b *path_g, int dist, int *pgrids, POSITION *gx, POSITION *gy, POSITION *gm, POSITION *pgm_rad, POSITION rad, POSITION y1, POSITION x1, POSITION y2, POSITION x2, EFFECT_ID typ);
 extern POSITION dist_to_line(POSITION y, POSITION x, POSITION y1, POSITION x1, POSITION y2, POSITION x2);
-extern bool project(player_type *caster_ptr, MONSTER_IDX who, POSITION rad, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ, BIT_FLAGS flg, int monspell);
 extern bool binding_field(player_type *caster_ptr, HIT_POINT dam);
 extern void seal_of_mirror(player_type *caster_ptr, HIT_POINT dam);
 extern concptr spell_category_name(OBJECT_TYPE_VALUE tval);
index e949728..344d17f 100644 (file)
 #include "spells.h"
 #include "gameterm.h"
 #include "view/display-main-window.h"
+#include "effect/spells-effect-util.h"
 #include "effect/effect-feature.h"
 #include "effect/effect-item.h"
-#include "effect/effect-player.h"
 #include "effect/effect-monster.h"
-#include "effect/spells-effect-util.h"
-
-/*!
- * @brief 配置した鏡リストの次を取得する /
- * Get another mirror. for SEEKER
- * @param next_y 次の鏡のy座標を返す参照ポインタ
- * @param next_x 次の鏡のx座標を返す参照ポインタ
- * @param cury 現在の鏡のy座標
- * @param curx 現在の鏡のx座標
- */
-static void next_mirror(player_type *creature_ptr, POSITION* next_y, POSITION* next_x, POSITION cury, POSITION curx)
-{
-       POSITION mirror_x[10], mirror_y[10]; /* 鏡はもっと少ない */
-       int mirror_num = 0;     /* 鏡の数 */
-       for (POSITION x = 0; x < creature_ptr->current_floor_ptr->width; x++)
-       {
-               for (POSITION y = 0; y < creature_ptr->current_floor_ptr->height; y++)
-               {
-                       if (is_mirror_grid(&creature_ptr->current_floor_ptr->grid_array[y][x])) {
-                               mirror_y[mirror_num] = y;
-                               mirror_x[mirror_num] = x;
-                               mirror_num++;
-                       }
-               }
-       }
-
-       if (mirror_num)
-       {
-               int num = randint0(mirror_num);
-               *next_y = mirror_y[num];
-               *next_x = mirror_x[num];
-               return;
-       }
-
-       *next_y = cury + randint0(5) - 2;
-       *next_x = curx + randint0(5) - 2;
-}
-
 
 /*
  * Find the distance from (x, y) to a line.
@@ -332,804 +294,6 @@ void breath_shape(player_type *caster_ptr, u16b *path_g, int dist, int *pgrids,
 
 
 /*!
- * todo 似たような処理が山ほど並んでいる、何とかならないものか
- * @brief 汎用的なビーム/ボルト/ボール系処理のルーチン Generic "beam"/"bolt"/"ball" projection routine.
- * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
- * @param rad 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
- * @param y 目標Y座標 / Target y location (or location to travel "towards")
- * @param x 目標X座標 / Target x location (or location to travel "towards")
- * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
- * @param typ 効果属性 / Type of damage to apply to monsters (and objects)
- * @param flag 効果フラグ / Extra bit flags (see PROJECT_xxxx)
- * @param monspell 効果元のモンスター魔法ID
- * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
- */
-bool project(player_type *caster_ptr, MONSTER_IDX who, POSITION rad, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ, BIT_FLAGS flag, int monspell)
-{
-       int i, t, dist;
-       POSITION y1, x1;
-       POSITION y2, x2;
-       POSITION by, bx;
-       int dist_hack = 0;
-       POSITION y_saver, x_saver; /* For reflecting monsters */
-       int msec = delay_factor * delay_factor * delay_factor;
-       bool notice = FALSE;
-       bool visual = FALSE;
-       bool drawn = FALSE;
-       bool breath = FALSE;
-       bool blind = caster_ptr->blind != 0;
-       bool old_hide = FALSE;
-       int path_n = 0;
-       u16b path_g[512];
-       int grids = 0;
-       POSITION gx[1024], gy[1024];
-       POSITION gm[32];
-       POSITION gm_rad = rad;
-       bool jump = FALSE;
-       GAME_TEXT who_name[MAX_NLEN];
-       bool see_s_msg = TRUE;
-       who_name[0] = '\0';
-       rakubadam_p = 0;
-       rakubadam_m = 0;
-       monster_target_y = caster_ptr->y;
-       monster_target_x = caster_ptr->x;
-
-       if (flag & (PROJECT_JUMP))
-       {
-               x1 = x;
-               y1 = y;
-               flag &= ~(PROJECT_JUMP);
-               jump = TRUE;
-       }
-       else if (who <= 0)
-       {
-               x1 = caster_ptr->x;
-               y1 = caster_ptr->y;
-       }
-       else if (who > 0)
-       {
-               x1 = caster_ptr->current_floor_ptr->m_list[who].fx;
-               y1 = caster_ptr->current_floor_ptr->m_list[who].fy;
-               monster_desc(caster_ptr, who_name, &caster_ptr->current_floor_ptr->m_list[who], MD_WRONGDOER_NAME);
-       }
-       else
-       {
-               x1 = x;
-               y1 = y;
-       }
-
-       y_saver = y1;
-       x_saver = x1;
-       y2 = y;
-       x2 = x;
-
-       if (flag & (PROJECT_THRU))
-       {
-               if ((x1 == x2) && (y1 == y2))
-               {
-                       flag &= ~(PROJECT_THRU);
-               }
-       }
-
-       if (rad < 0)
-       {
-               rad = 0 - rad;
-               breath = TRUE;
-               if (flag & PROJECT_HIDE) old_hide = TRUE;
-               flag |= PROJECT_HIDE;
-       }
-
-       for (dist = 0; dist < 32; dist++) gm[dist] = 0;
-
-       y = y1;
-       x = x1;
-       dist = 0;
-       if (flag & (PROJECT_BEAM))
-       {
-               gy[grids] = y;
-               gx[grids] = x;
-               grids++;
-       }
-
-       switch (typ)
-       {
-       case GF_LITE:
-       case GF_LITE_WEAK:
-               if (breath || (flag & PROJECT_BEAM)) flag |= (PROJECT_LOS);
-               break;
-       case GF_DISINTEGRATE:
-               flag |= (PROJECT_GRID);
-               if (breath || (flag & PROJECT_BEAM)) flag |= (PROJECT_DISI);
-               break;
-       }
-
-       /* Calculate the projection path */
-       path_n = project_path(caster_ptr, path_g, (project_length ? project_length : MAX_RANGE), y1, x1, y2, x2, flag);
-       handle_stuff(caster_ptr);
-
-       if (typ == GF_SEEKER)
-       {
-               int j;
-               int last_i = 0;
-               project_m_n = 0;
-               project_m_x = 0;
-               project_m_y = 0;
-               for (i = 0; i < path_n; ++i)
-               {
-                       POSITION oy = y;
-                       POSITION ox = x;
-                       POSITION ny = GRID_Y(path_g[i]);
-                       POSITION nx = GRID_X(path_g[i]);
-                       y = ny;
-                       x = nx;
-                       gy[grids] = y;
-                       gx[grids] = x;
-                       grids++;
-
-                       if (!blind && !(flag & (PROJECT_HIDE)))
-                       {
-                               if (panel_contains(y, x) && player_has_los_bold(caster_ptr, y, x))
-                               {
-                                       u16b p = bolt_pict(oy, ox, y, x, typ);
-                                       TERM_COLOR a = PICT_A(p);
-                                       SYMBOL_CODE c = PICT_C(p);
-                                       print_rel(caster_ptr, c, a, y, x);
-                                       move_cursor_relative(y, x);
-                                       Term_fresh();
-                                       Term_xtra(TERM_XTRA_DELAY, msec);
-                                       lite_spot(caster_ptr, y, x);
-                                       Term_fresh();
-                                       if (flag & (PROJECT_BEAM))
-                                       {
-                                               p = bolt_pict(y, x, y, x, typ);
-                                               a = PICT_A(p);
-                                               c = PICT_C(p);
-                                               print_rel(caster_ptr, c, a, y, x);
-                                       }
-
-                                       visual = TRUE;
-                               }
-                               else if (visual)
-                               {
-                                       Term_xtra(TERM_XTRA_DELAY, msec);
-                               }
-                       }
-
-                       if (affect_item(caster_ptr, 0, 0, y, x, dam, GF_SEEKER))notice = TRUE;
-                       if (!is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[y][x]))
-                               continue;
-
-                       monster_target_y = y;
-                       monster_target_x = x;
-                       remove_mirror(caster_ptr, y, x);
-                       next_mirror(caster_ptr, &oy, &ox, y, x);
-                       path_n = i + project_path(caster_ptr, &(path_g[i + 1]), (project_length ? project_length : MAX_RANGE), y, x, oy, ox, flag);
-                       for (j = last_i; j <= i; j++)
-                       {
-                               y = GRID_Y(path_g[j]);
-                               x = GRID_X(path_g[j]);
-                               if (affect_monster(caster_ptr, 0, 0, y, x, dam, GF_SEEKER, flag, TRUE)) notice = TRUE;
-                               if (!who && (project_m_n == 1) && !jump && (caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x].m_idx > 0))
-                               {
-                                       monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x].m_idx];
-                                       if (m_ptr->ml)
-                                       {
-                                               if (!caster_ptr->image) monster_race_track(caster_ptr, m_ptr->ap_r_idx);
-                                               health_track(caster_ptr, caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x].m_idx);
-                                       }
-                               }
-
-                               (void)affect_feature(caster_ptr, 0, 0, y, x, dam, GF_SEEKER);
-                       }
-
-                       last_i = i;
-               }
-
-               for (i = last_i; i < path_n; i++)
-               {
-                       POSITION py, px;
-                       py = GRID_Y(path_g[i]);
-                       px = GRID_X(path_g[i]);
-                       if (affect_monster(caster_ptr, 0, 0, py, px, dam, GF_SEEKER, flag, TRUE))
-                               notice = TRUE;
-                       if (!who && (project_m_n == 1) && !jump) {
-                               if (caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x].m_idx > 0)
-                               {
-                                       monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x].m_idx];
-
-                                       if (m_ptr->ml)
-                                       {
-                                               if (!caster_ptr->image) monster_race_track(caster_ptr, m_ptr->ap_r_idx);
-                                               health_track(caster_ptr, caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x].m_idx);
-                                       }
-                               }
-                       }
-
-                       (void)affect_feature(caster_ptr, 0, 0, py, px, dam, GF_SEEKER);
-               }
-
-               return notice;
-       }
-       else if (typ == GF_SUPER_RAY)
-       {
-               int j;
-               int second_step = 0;
-               project_m_n = 0;
-               project_m_x = 0;
-               project_m_y = 0;
-               for (i = 0; i < path_n; ++i)
-               {
-                       POSITION oy = y;
-                       POSITION ox = x;
-                       POSITION ny = GRID_Y(path_g[i]);
-                       POSITION nx = GRID_X(path_g[i]);
-                       y = ny;
-                       x = nx;
-                       gy[grids] = y;
-                       gx[grids] = x;
-                       grids++;
-                       {
-                               if (panel_contains(y, x) && player_has_los_bold(caster_ptr, y, x))
-                               {
-                                       u16b p;
-                                       TERM_COLOR a;
-                                       SYMBOL_CODE c;
-                                       p = bolt_pict(oy, ox, y, x, typ);
-                                       a = PICT_A(p);
-                                       c = PICT_C(p);
-                                       print_rel(caster_ptr, c, a, y, x);
-                                       move_cursor_relative(y, x);
-                                       Term_fresh();
-                                       Term_xtra(TERM_XTRA_DELAY, msec);
-                                       lite_spot(caster_ptr, y, x);
-                                       Term_fresh();
-                                       if (flag & (PROJECT_BEAM))
-                                       {
-                                               p = bolt_pict(y, x, y, x, typ);
-                                               a = PICT_A(p);
-                                               c = PICT_C(p);
-                                               print_rel(caster_ptr, c, a, y, x);
-                                       }
-
-                                       visual = TRUE;
-                               }
-                               else if (visual)
-                               {
-                                       Term_xtra(TERM_XTRA_DELAY, msec);
-                               }
-                       }
-
-                       if (affect_item(caster_ptr, 0, 0, y, x, dam, GF_SUPER_RAY))notice = TRUE;
-                       if (!cave_have_flag_bold(caster_ptr->current_floor_ptr, y, x, FF_PROJECT))
-                       {
-                               if (second_step)continue;
-                               break;
-                       }
-
-                       if (is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[y][x]) && !second_step)
-                       {
-                               monster_target_y = y;
-                               monster_target_x = x;
-                               remove_mirror(caster_ptr, y, x);
-                               for (j = 0; j <= i; j++)
-                               {
-                                       y = GRID_Y(path_g[j]);
-                                       x = GRID_X(path_g[j]);
-                                       (void)affect_feature(caster_ptr, 0, 0, y, x, dam, GF_SUPER_RAY);
-                               }
-
-                               path_n = i;
-                               second_step = i + 1;
-                               path_n += project_path(caster_ptr, &(path_g[path_n + 1]), (project_length ? project_length : MAX_RANGE), y, x, y - 1, x - 1, flag);
-                               path_n += project_path(caster_ptr, &(path_g[path_n + 1]), (project_length ? project_length : MAX_RANGE), y, x, y - 1, x, flag);
-                               path_n += project_path(caster_ptr, &(path_g[path_n + 1]), (project_length ? project_length : MAX_RANGE), y, x, y - 1, x + 1, flag);
-                               path_n += project_path(caster_ptr, &(path_g[path_n + 1]), (project_length ? project_length : MAX_RANGE), y, x, y, x - 1, flag);
-                               path_n += project_path(caster_ptr, &(path_g[path_n + 1]), (project_length ? project_length : MAX_RANGE), y, x, y, x + 1, flag);
-                               path_n += project_path(caster_ptr, &(path_g[path_n + 1]), (project_length ? project_length : MAX_RANGE), y, x, y + 1, x - 1, flag);
-                               path_n += project_path(caster_ptr, &(path_g[path_n + 1]), (project_length ? project_length : MAX_RANGE), y, x, y + 1, x, flag);
-                               path_n += project_path(caster_ptr, &(path_g[path_n + 1]), (project_length ? project_length : MAX_RANGE), y, x, y + 1, x + 1, flag);
-                       }
-               }
-
-               for (i = 0; i < path_n; i++)
-               {
-                       POSITION py = GRID_Y(path_g[i]);
-                       POSITION px = GRID_X(path_g[i]);
-                       (void)affect_monster(caster_ptr, 0, 0, py, px, dam, GF_SUPER_RAY, flag, TRUE);
-                       if (!who && (project_m_n == 1) && !jump) {
-                               if (caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x].m_idx > 0) {
-                                       monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x].m_idx];
-
-                                       if (m_ptr->ml)
-                                       {
-                                               if (!caster_ptr->image) monster_race_track(caster_ptr, m_ptr->ap_r_idx);
-                                               health_track(caster_ptr, caster_ptr->current_floor_ptr->grid_array[project_m_y][project_m_x].m_idx);
-                                       }
-                               }
-                       }
-
-                       (void)affect_feature(caster_ptr, 0, 0, py, px, dam, GF_SUPER_RAY);
-               }
-
-               return notice;
-       }
-
-       for (i = 0; i < path_n; ++i)
-       {
-               POSITION oy = y;
-               POSITION ox = x;
-               POSITION ny = GRID_Y(path_g[i]);
-               POSITION nx = GRID_X(path_g[i]);
-               if (flag & PROJECT_DISI)
-               {
-                       if (cave_stop_disintegration(caster_ptr->current_floor_ptr, ny, nx) && (rad > 0)) break;
-               }
-               else if (flag & PROJECT_LOS)
-               {
-                       if (!cave_los_bold(caster_ptr->current_floor_ptr, ny, nx) && (rad > 0)) break;
-               }
-               else
-               {
-                       if (!cave_have_flag_bold(caster_ptr->current_floor_ptr, ny, nx, FF_PROJECT) && (rad > 0)) break;
-               }
-
-               y = ny;
-               x = nx;
-               if (flag & (PROJECT_BEAM))
-               {
-                       gy[grids] = y;
-                       gx[grids] = x;
-                       grids++;
-               }
-
-               if (!blind && !(flag & (PROJECT_HIDE | PROJECT_FAST)))
-               {
-                       if (panel_contains(y, x) && player_has_los_bold(caster_ptr, y, x))
-                       {
-                               u16b p;
-                               TERM_COLOR a;
-                               SYMBOL_CODE c;
-                               p = bolt_pict(oy, ox, y, x, typ);
-                               a = PICT_A(p);
-                               c = PICT_C(p);
-                               print_rel(caster_ptr, c, a, y, x);
-                               move_cursor_relative(y, x);
-                               Term_fresh();
-                               Term_xtra(TERM_XTRA_DELAY, msec);
-                               lite_spot(caster_ptr, y, x);
-                               Term_fresh();
-                               if (flag & (PROJECT_BEAM))
-                               {
-                                       p = bolt_pict(y, x, y, x, typ);
-                                       a = PICT_A(p);
-                                       c = PICT_C(p);
-                                       print_rel(caster_ptr, c, a, y, x);
-                               }
-
-                               visual = TRUE;
-                       }
-                       else if (visual)
-                       {
-                               Term_xtra(TERM_XTRA_DELAY, msec);
-                       }
-               }
-       }
-
-       path_n = i;
-       by = y;
-       bx = x;
-       if (breath && !path_n)
-       {
-               breath = FALSE;
-               gm_rad = rad;
-               if (!old_hide)
-               {
-                       flag &= ~(PROJECT_HIDE);
-               }
-       }
-
-       gm[0] = 0;
-       gm[1] = grids;
-       dist = path_n;
-       dist_hack = dist;
-       project_length = 0;
-
-       /* If we found a "target", explode there */
-       if (dist <= MAX_RANGE)
-       {
-               if ((flag & (PROJECT_BEAM)) && (grids > 0)) grids--;
-
-               /*
-                * Create a conical breath attack
-                *
-                *       ***
-                *   ********
-                * D********@**
-                *   ********
-                *       ***
-                */
-               if (breath)
-               {
-                       flag &= ~(PROJECT_HIDE);
-                       breath_shape(caster_ptr, path_g, dist, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, by, bx, typ);
-               }
-               else
-               {
-                       for (dist = 0; dist <= rad; dist++)
-                       {
-                               for (y = by - dist; y <= by + dist; y++)
-                               {
-                                       for (x = bx - dist; x <= bx + dist; x++)
-                                       {
-                                               if (!in_bounds2(caster_ptr->current_floor_ptr, y, x)) continue;
-                                               if (distance(by, bx, y, x) != dist) continue;
-
-                                               switch (typ)
-                                               {
-                                               case GF_LITE:
-                                               case GF_LITE_WEAK:
-                                                       if (!los(caster_ptr, by, bx, y, x)) continue;
-                                                       break;
-                                               case GF_DISINTEGRATE:
-                                                       if (!in_disintegration_range(caster_ptr->current_floor_ptr, by, bx, y, x)) continue;
-                                                       break;
-                                               default:
-                                                       if (!projectable(caster_ptr, by, bx, y, x)) continue;
-                                                       break;
-                                               }
-
-                                               gy[grids] = y;
-                                               gx[grids] = x;
-                                               grids++;
-                                       }
-                               }
-
-                               gm[dist + 1] = grids;
-                       }
-               }
-       }
-
-       if (!grids) return FALSE;
-
-       if (!blind && !(flag & (PROJECT_HIDE)))
-       {
-               for (t = 0; t <= gm_rad; t++)
-               {
-                       for (i = gm[t]; i < gm[t + 1]; i++)
-                       {
-                               y = gy[i];
-                               x = gx[i];
-                               if (panel_contains(y, x) && player_has_los_bold(caster_ptr, y, x))
-                               {
-                                       u16b p;
-                                       TERM_COLOR a;
-                                       SYMBOL_CODE c;
-                                       drawn = TRUE;
-                                       p = bolt_pict(y, x, y, x, typ);
-                                       a = PICT_A(p);
-                                       c = PICT_C(p);
-                                       print_rel(caster_ptr, c, a, y, x);
-                               }
-                       }
-
-                       move_cursor_relative(by, bx);
-                       Term_fresh();
-                       if (visual || drawn)
-                       {
-                               Term_xtra(TERM_XTRA_DELAY, msec);
-                       }
-               }
-
-               if (drawn)
-               {
-                       for (i = 0; i < grids; i++)
-                       {
-                               y = gy[i];
-                               x = gx[i];
-                               if (panel_contains(y, x) && player_has_los_bold(caster_ptr, y, x))
-                               {
-                                       lite_spot(caster_ptr, y, x);
-                               }
-                       }
-
-                       move_cursor_relative(by, bx);
-                       Term_fresh();
-               }
-       }
-
-       update_creature(caster_ptr);
-
-       if (flag & PROJECT_KILL)
-       {
-               see_s_msg = (who > 0) ? is_seen(&caster_ptr->current_floor_ptr->m_list[who]) :
-                       (!who ? TRUE : (player_can_see_bold(caster_ptr, y1, x1) && projectable(caster_ptr, caster_ptr->y, caster_ptr->x, y1, x1)));
-       }
-
-       if (flag & (PROJECT_GRID))
-       {
-               dist = 0;
-               for (i = 0; i < grids; i++)
-               {
-                       if (gm[dist + 1] == i) dist++;
-                       y = gy[i];
-                       x = gx[i];
-                       if (breath)
-                       {
-                               int d = dist_to_line(y, x, y1, x1, by, bx);
-                               if (affect_feature(caster_ptr, who, d, y, x, dam, typ)) notice = TRUE;
-                       }
-                       else
-                       {
-                               if (affect_feature(caster_ptr, who, dist, y, x, dam, typ)) notice = TRUE;
-                       }
-               }
-       }
-
-       update_creature(caster_ptr);
-       if (flag & (PROJECT_ITEM))
-       {
-               dist = 0;
-               for (i = 0; i < grids; i++)
-               {
-                       if (gm[dist + 1] == i) dist++;
-
-                       y = gy[i];
-                       x = gx[i];
-                       if (breath)
-                       {
-                               int d = dist_to_line(y, x, y1, x1, by, bx);
-                               if (affect_item(caster_ptr, who, d, y, x, dam, typ)) notice = TRUE;
-                       }
-                       else
-                       {
-                               if (affect_item(caster_ptr, who, dist, y, x, dam, typ)) notice = TRUE;
-                       }
-               }
-       }
-
-       if (flag & (PROJECT_KILL))
-       {
-               project_m_n = 0;
-               project_m_x = 0;
-               project_m_y = 0;
-               dist = 0;
-               for (i = 0; i < grids; i++)
-               {
-                       int effective_dist;
-                       if (gm[dist + 1] == i) dist++;
-
-                       y = gy[i];
-                       x = gx[i];
-                       if (grids <= 1)
-                       {
-                               monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[caster_ptr->current_floor_ptr->grid_array[y][x].m_idx];
-                               monster_race *ref_ptr = &r_info[m_ptr->r_idx];
-                               if ((flag & PROJECT_REFLECTABLE) && caster_ptr->current_floor_ptr->grid_array[y][x].m_idx && (ref_ptr->flags2 & RF2_REFLECTING) &&
-                                       ((caster_ptr->current_floor_ptr->grid_array[y][x].m_idx != caster_ptr->riding) || !(flag & PROJECT_PLAYER)) &&
-                                       (!who || dist_hack > 1) && !one_in_(10))
-                               {
-                                       POSITION t_y, t_x;
-                                       int max_attempts = 10;
-                                       do
-                                       {
-                                               t_y = y_saver - 1 + randint1(3);
-                                               t_x = x_saver - 1 + randint1(3);
-                                               max_attempts--;
-                                       } while (max_attempts && in_bounds2u(caster_ptr->current_floor_ptr, t_y, t_x) && !projectable(caster_ptr, y, x, t_y, t_x));
-
-                                       if (max_attempts < 1)
-                                       {
-                                               t_y = y_saver;
-                                               t_x = x_saver;
-                                       }
-
-                                       sound(SOUND_REFLECT);
-                                       if (is_seen(m_ptr))
-                                       {
-                                               if ((m_ptr->r_idx == MON_KENSHIROU) || (m_ptr->r_idx == MON_RAOU))
-                                                       msg_print(_("「北斗神拳奥義・二指真空把!」", "The attack bounces!"));
-                                               else if (m_ptr->r_idx == MON_DIO)
-                                                       msg_print(_("ディオ・ブランドーは指一本で攻撃を弾き返した!", "The attack bounces!"));
-                                               else
-                                                       msg_print(_("攻撃は跳ね返った!", "The attack bounces!"));
-                                       }
-
-                                       if (is_original_ap_and_seen(caster_ptr, m_ptr)) ref_ptr->r_flags2 |= RF2_REFLECTING;
-
-                                       if (player_bold(caster_ptr, y, x) || one_in_(2)) flag &= ~(PROJECT_PLAYER);
-                                       else flag |= PROJECT_PLAYER;
-
-                                       project(caster_ptr, caster_ptr->current_floor_ptr->grid_array[y][x].m_idx, 0, t_y, t_x, dam, typ, flag, monspell);
-                                       continue;
-                               }
-                       }
-
-                       /* Find the closest point in the blast */
-                       if (breath)
-                       {
-                               effective_dist = dist_to_line(y, x, y1, x1, by, bx);
-                       }
-                       else
-                       {
-                               effective_dist = dist;
-                       }
-
-                       if (caster_ptr->riding && player_bold(caster_ptr, y, x))
-                       {
-                               if (flag & PROJECT_PLAYER)
-                               {
-                                       if (flag & (PROJECT_BEAM | PROJECT_REFLECTABLE | PROJECT_AIMED))
-                                       {
-                                               /*
-                                                * A beam or bolt is well aimed
-                                                * at the PLAYER!
-                                                * So don't affects the mount.
-                                                */
-                                               continue;
-                                       }
-                                       else
-                                       {
-                                               /*
-                                                * The spell is not well aimed,
-                                                * So partly affect the mount too.
-                                                */
-                                               effective_dist++;
-                                       }
-                               }
-
-                               /*
-                                * This grid is the original target.
-                                * Or aimed on your horse.
-                                */
-                               else if (((y == y2) && (x == x2)) || (flag & PROJECT_AIMED))
-                               {
-                                       /* Hit the mount with full damage */
-                               }
-
-                               /*
-                                * Otherwise this grid is not the
-                                * original target, it means that line
-                                * of fire is obstructed by this
-                                * monster.
-                                */
-                                /*
-                                 * A beam or bolt will hit either
-                                 * player or mount.  Choose randomly.
-                                 */
-                               else if (flag & (PROJECT_BEAM | PROJECT_REFLECTABLE))
-                               {
-                                       if (one_in_(2))
-                                       {
-                                               /* Hit the mount with full damage */
-                                       }
-                                       else
-                                       {
-                                               flag |= PROJECT_PLAYER;
-                                               continue;
-                                       }
-                               }
-
-                               /*
-                                * The spell is not well aimed, so
-                                * partly affect both player and
-                                * mount.
-                                */
-                               else
-                               {
-                                       effective_dist++;
-                               }
-                       }
-
-                       if (affect_monster(caster_ptr, who, effective_dist, y, x, dam, typ, flag, see_s_msg)) notice = TRUE;
-               }
-
-               /* Player affected one monster (without "jumping") */
-               if (!who && (project_m_n == 1) && !jump)
-               {
-                       x = project_m_x;
-                       y = project_m_y;
-                       if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx > 0)
-                       {
-                               monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[caster_ptr->current_floor_ptr->grid_array[y][x].m_idx];
-
-                               if (m_ptr->ml)
-                               {
-                                       if (!caster_ptr->image) monster_race_track(caster_ptr, m_ptr->ap_r_idx);
-                                       health_track(caster_ptr, caster_ptr->current_floor_ptr->grid_array[y][x].m_idx);
-                               }
-                       }
-               }
-       }
-
-       if (flag & (PROJECT_KILL))
-       {
-               dist = 0;
-               for (i = 0; i < grids; i++)
-               {
-                       int effective_dist;
-                       if (gm[dist + 1] == i) dist++;
-
-                       y = gy[i];
-                       x = gx[i];
-                       if (!player_bold(caster_ptr, y, x)) continue;
-
-                       /* Find the closest point in the blast */
-                       if (breath)
-                       {
-                               effective_dist = dist_to_line(y, x, y1, x1, by, bx);
-                       }
-                       else
-                       {
-                               effective_dist = dist;
-                       }
-
-                       if (caster_ptr->riding)
-                       {
-                               if (flag & PROJECT_PLAYER)
-                               {
-                                       /* Hit the player with full damage */
-                               }
-
-                               /*
-                                * Hack -- When this grid was not the
-                                * original target, a beam or bolt
-                                * would hit either player or mount,
-                                * and should be choosen randomly.
-                                *
-                                * But already choosen to hit the
-                                * mount at this point.
-                                *
-                                * Or aimed on your horse.
-                                */
-                               else if (flag & (PROJECT_BEAM | PROJECT_REFLECTABLE | PROJECT_AIMED))
-                               {
-                                       /*
-                                        * A beam or bolt is well aimed
-                                        * at the mount!
-                                        * So don't affects the player.
-                                        */
-                                       continue;
-                               }
-                               else
-                               {
-                                       /*
-                                        * The spell is not well aimed,
-                                        * So partly affect the player too.
-                                        */
-                                       effective_dist++;
-                               }
-                       }
-
-                       if (affect_player(who, caster_ptr, who_name, effective_dist, y, x, dam, typ, flag, monspell, project)) notice = TRUE;
-               }
-       }
-
-       if (caster_ptr->riding)
-       {
-               GAME_TEXT m_name[MAX_NLEN];
-               monster_desc(caster_ptr, m_name, &caster_ptr->current_floor_ptr->m_list[caster_ptr->riding], 0);
-               if (rakubadam_m > 0)
-               {
-                       if (rakuba(caster_ptr, rakubadam_m, FALSE))
-                       {
-                               msg_format(_("%^sに振り落とされた!", "%^s has thrown you off!"), m_name);
-                       }
-               }
-
-               if (caster_ptr->riding && rakubadam_p > 0)
-               {
-                       if (rakuba(caster_ptr, rakubadam_p, FALSE))
-                       {
-                               msg_format(_("%^sから落ちてしまった!", "You have fallen from %s."), m_name);
-                       }
-               }
-       }
-
-       return (notice);
-}
-
-
-/*!
  * @brief 鏡魔法「封魔結界」の効果処理
  * @param dam ダメージ量
  * @return 効果があったらTRUEを返す