OSDN Git Service

[Refactor] #39963 Changed inclusion for spells.h to process-effect.c
[hengband/hengband.git] / src / spells3.c
index 6349bb4..ad04abe 100644 (file)
  */
 
 #include "angband.h"
-#include "bldg.h"
+#include "market/building.h"
 #include "core.h"
-#include "term.h"
+#include "gameterm.h"
 #include "util.h"
+#include "main/sound-definitions-table.h"
 #include "object-ego.h"
 
 #include "creature.h"
 #include "avatar.h"
 #include "spells.h"
 #include "spells-floor.h"
+#include "spell/technic-info-table.h"
 #include "grid.h"
+#include "market/building-util.h"
 #include "monster-process.h"
 #include "monster-status.h"
 #include "monster-spell.h"
-#include "cmd-spell.h"
-#include "cmd-dump.h"
+#include "io/write-diary.h"
+#include "cmd/cmd-save.h"
+#include "cmd/cmd-spell.h"
+#include "cmd/cmd-dump.h"
 #include "snipe.h"
 #include "floor-save.h"
 #include "files.h"
 #include "player-effects.h"
 #include "player-skill.h"
 #include "player-personality.h"
-#include "view-mainwindow.h"
+#include "view/display-main-window.h"
 #include "mind.h"
 #include "wild.h"
 #include "world.h"
-#include "objectkind.h"
-#include "autopick.h"
+#include "object/object-kind.h"
+#include "autopick/autopick.h"
 #include "targeting.h"
+#include "effect/spells-effect-util.h"
+#include "spell/spells-util.h"
+#include "spell/spells-execution.h"
+#include "spell/process-effect.h"
 
 /*! テレポート先探索の試行数 / Maximum number of tries for teleporting */
 #define MAX_TRIES 100
@@ -77,7 +86,7 @@ static bool redraw_player(player_type *caster_ptr);
  * Attempt to move the monster at least "dis/2" grids away.
  * But allow variation to prevent infinite loops.
  */
-bool teleport_away(player_type *caster_ptr, MONSTER_IDX m_idx, POSITION dis, BIT_FLAGS mode)
+bool teleport_away(player_type *caster_ptr, MONSTER_IDX m_idx, POSITION dis, teleport_flags mode)
 {
        monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
        if (!monster_is_valid(m_ptr)) return FALSE;
@@ -154,7 +163,7 @@ bool teleport_away(player_type *caster_ptr, MONSTER_IDX m_idx, POSITION dis, BIT
  * @param mode オプション
  * @return なし
  */
-void teleport_monster_to(player_type *caster_ptr, MONSTER_IDX m_idx, POSITION ty, POSITION tx, int power, BIT_FLAGS mode)
+void teleport_monster_to(player_type *caster_ptr, MONSTER_IDX m_idx, POSITION ty, POSITION tx, int power, teleport_flags mode)
 {
        monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
        if(!m_ptr->r_idx) return;
@@ -217,6 +226,7 @@ void teleport_monster_to(player_type *caster_ptr, MONSTER_IDX m_idx, POSITION ty
  * Teleport the player to a location up to "dis" grids away.
  * @param creature_ptr プレーヤーへの参照ポインタ
  * @param dis 基本移動距離
+ * @param is_quantum_effect 量子的効果 (反テレポ無効)によるテレポートアウェイならばTRUE
  * @param mode オプション
  * @return 実際にテレポート処理が行われたらtrue
  * @details
@@ -235,10 +245,10 @@ void teleport_monster_to(player_type *caster_ptr, MONSTER_IDX m_idx, POSITION ty
  * of candidates has equal possibility to be choosen as a destination.
  * </pre>
  */
-bool teleport_player_aux(player_type *creature_ptr, POSITION dis, BIT_FLAGS mode)
+bool teleport_player_aux(player_type *creature_ptr, POSITION dis, bool is_quantum_effect, teleport_flags mode)
 {
        if (creature_ptr->wild_mode) return FALSE;
-       if (creature_ptr->anti_tele && !(mode & TELEPORT_NONMAGICAL))
+       if (!is_quantum_effect && creature_ptr->anti_tele && !(mode & TELEPORT_NONMAGICAL))
        {
                msg_print(_("不思議な力がテレポートを防いだ!", "A mysterious force prevents you from teleporting!"));
                return FALSE;
@@ -321,7 +331,7 @@ bool teleport_player_aux(player_type *creature_ptr, POSITION dis, BIT_FLAGS mode
  */
 void teleport_player(player_type *creature_ptr, POSITION dis, BIT_FLAGS mode)
 {
-       if (!teleport_player_aux(creature_ptr, dis, mode)) return;
+       if (!teleport_player_aux(creature_ptr, dis, FALSE, mode)) return;
 
        /* Monsters with teleport ability may follow the player */
        POSITION oy = creature_ptr->y;
@@ -344,7 +354,7 @@ void teleport_player(player_type *creature_ptr, POSITION dis, BIT_FLAGS mode)
                        is_resistible &= MON_CSLEEP(m_ptr) == 0;
                        if (is_resistible)
                        {
-                               teleport_monster_to(creature_ptr, tmp_m_idx, creature_ptr->y, creature_ptr->x, r_ptr->level, 0L);
+                               teleport_monster_to(creature_ptr, tmp_m_idx, creature_ptr->y, creature_ptr->x, r_ptr->level, TELEPORT_SPONTANEOUS);
                        }
                }
        }
@@ -356,11 +366,12 @@ void teleport_player(player_type *creature_ptr, POSITION dis, BIT_FLAGS mode)
  * @param m_idx アウェイを試みたモンスターID
  * @param target_ptr プレーヤーへの参照ポインタ
  * @param dis テレポート距離
+ * @param is_quantum_effect 量子的効果によるテレポートアウェイならばTRUE
  * @return なし
  */
-void teleport_player_away(MONSTER_IDX m_idx, player_type *target_ptr, POSITION dis)
+void teleport_player_away(MONSTER_IDX m_idx, player_type *target_ptr, POSITION dis, bool is_quantum_effect)
 {
-       if (!teleport_player_aux(target_ptr, dis, TELEPORT_PASSIVE)) return;
+       if (!teleport_player_aux(target_ptr, dis, TELEPORT_PASSIVE, is_quantum_effect)) return;
 
        /* Monsters with teleport ability may follow the player */
        POSITION oy = target_ptr->y;
@@ -386,7 +397,7 @@ void teleport_player_away(MONSTER_IDX m_idx, player_type *target_ptr, POSITION d
                        is_resistible &= MON_CSLEEP(m_ptr) == 0;
                        if (is_resistible)
                        {
-                               teleport_monster_to(target_ptr, tmp_m_idx, target_ptr->y, target_ptr->x, r_ptr->level, 0L);
+                               teleport_monster_to(target_ptr, tmp_m_idx, target_ptr->y, target_ptr->x, r_ptr->level, TELEPORT_SPONTANEOUS);
                        }
                }
        }
@@ -407,7 +418,7 @@ void teleport_player_away(MONSTER_IDX m_idx, player_type *target_ptr, POSITION d
  * This function allows teleporting into vaults (!)
  * </pre>
  */
-void teleport_player_to(player_type *creature_ptr, POSITION ny, POSITION nx, BIT_FLAGS mode)
+void teleport_player_to(player_type *creature_ptr, POSITION ny, POSITION nx, teleport_flags mode)
 {
        if (creature_ptr->anti_tele && !(mode & TELEPORT_NONMAGICAL))
        {
@@ -455,11 +466,11 @@ void teleport_away_followable(player_type *tracer_ptr, MONSTER_IDX m_idx)
        bool old_ml = m_ptr->ml;
        POSITION old_cdis = m_ptr->cdis;
 
-       teleport_away(tracer_ptr, m_idx, MAX_SIGHT * 2 + 5, 0L);
+       teleport_away(tracer_ptr, m_idx, MAX_SIGHT * 2 + 5, TELEPORT_SPONTANEOUS);
 
        bool is_followable = old_ml;
        is_followable &= old_cdis <= MAX_SIGHT;
-       is_followable &= !current_world_ptr->timewalk_m_idx > 0;
+       is_followable &= current_world_ptr->timewalk_m_idx == 0;
        is_followable &= !tracer_ptr->phase_out;
        is_followable &= los(tracer_ptr, tracer_ptr->y, tracer_ptr->x, oldfy, oldfx);
        if (!is_followable) return;
@@ -498,7 +509,7 @@ void teleport_away_followable(player_type *tracer_ptr, MONSTER_IDX m_idx)
        }
        else
        {
-               teleport_player_to(tracer_ptr, m_ptr->fy, m_ptr->fx, 0L);
+               teleport_player_to(tracer_ptr, m_ptr->fy, m_ptr->fx, TELEPORT_SPONTANEOUS);
        }
 
        tracer_ptr->energy_need += ENERGY_NEED();
@@ -536,6 +547,7 @@ bool teleport_level_other(player_type *caster_ptr)
 
 
 /*!
+ * todo cmd-save.h への依存あり。コールバックで何とかしたい
  * @brief プレイヤー及びモンスターをレベルテレポートさせる /
  * Teleport the player one level up or down (random when legal)
  * @param creature_ptr プレーヤーへの参照ポインタ
@@ -719,7 +731,7 @@ bool recall_player(player_type *creature_ptr, TIME_EFFECT turns)
                {
                        max_dlv[creature_ptr->dungeon_idx] = creature_ptr->current_floor_ptr->dun_level;
                        if (record_maxdepth)
-                               exe_write_diary(creature_ptr, DIARY_TRUMP, creature_ptr->dungeon_idx, _("帰還のときに", "when recall from dungeon"));
+                               exe_write_diary(creature_ptr, DIARY_TRUMP, creature_ptr->dungeon_idx, _("帰還のときに", "when recalled from dungeon"));
                }
 
        }
@@ -1488,7 +1500,7 @@ bool identify_item(player_type *owner_ptr, object_type *o_ptr)
        if (o_ptr->ident & IDENT_KNOWN)
                old_known = TRUE;
 
-       if (!(o_ptr->ident & (IDENT_MENTAL)))
+       if (!OBJECT_IS_FULL_KNOWN(o_ptr))
        {
                if (object_is_artifact(o_ptr) || one_in_(5))
                        chg_virtue(owner_ptr, V_KNOWLEDGE, 1);
@@ -1525,7 +1537,7 @@ bool identify_item(player_type *owner_ptr, object_type *o_ptr)
  * This routine does *not* automatically combine objects.
  * Returns TRUE if something was identified, else FALSE.
  */
-bool ident_spell(player_type *caster_ptr, bool only_equip)
+bool ident_spell(player_type *caster_ptr, bool only_equip, OBJECT_TYPE_VALUE item_tester_tval)
 {
        if (only_equip)
                item_tester_hook = item_tester_hook_identify_weapon_armour;
@@ -1632,7 +1644,7 @@ bool mundane_spell(player_type *owner_ptr, bool only_equip)
  * Fully "identify" an object in the inventory -BEN-
  * This routine returns TRUE if an item was identified.
  */
-bool identify_fully(player_type *caster_ptr, bool only_equip)
+bool identify_fully(player_type *caster_ptr, bool only_equip, OBJECT_TYPE_VALUE item_tester_tval)
 {
        if (only_equip)
                item_tester_hook = item_tester_hook_identify_fully_weapon_armour;
@@ -1663,7 +1675,7 @@ bool identify_fully(player_type *caster_ptr, bool only_equip)
 
        bool old_known = identify_item(caster_ptr, o_ptr);
 
-       o_ptr->ident |= (IDENT_MENTAL);
+       o_ptr->ident |= (IDENT_FULL_KNOWN);
        handle_stuff(caster_ptr);
 
        GAME_TEXT o_name[MAX_NLEN];
@@ -2390,7 +2402,7 @@ static MONRACE_IDX poly_r_idx(player_type *caster_ptr, MONRACE_IDX r_idx)
        MONRACE_IDX r;
        for (int i = 0; i < 1000; i++)
        {
-               r = get_mon_num(caster_ptr, (caster_ptr->current_floor_ptr->dun_level + r_ptr->level) / 2 + 5);
+               r = get_mon_num(caster_ptr, (caster_ptr->current_floor_ptr->dun_level + r_ptr->level) / 2 + 5, 0);
                if (!r) break;
 
                r_ptr = &r_info[r];
@@ -2496,7 +2508,7 @@ static bool dimension_door_aux(player_type *caster_ptr, POSITION x, POSITION y)
 
        caster_ptr->energy_need += (s16b)((s32b)(60 - plev) * ENERGY_NEED() / 100L);
 
-       if (!cave_player_teleportable_bold(caster_ptr, y, x, 0L) ||
+       if (!cave_player_teleportable_bold(caster_ptr, y, x, TELEPORT_SPONTANEOUS) ||
            (distance(y, x, caster_ptr->y, caster_ptr->x) > plev / 2 + 10) ||
            (!randint0(plev / 10 + 10)))
        {
@@ -2505,7 +2517,7 @@ static bool dimension_door_aux(player_type *caster_ptr, POSITION x, POSITION y)
                return FALSE;
        }
 
-       teleport_player_to(caster_ptr, y, x, 0L);
+       teleport_player_to(caster_ptr, y, x, TELEPORT_SPONTANEOUS);
        return TRUE;
 }
 
@@ -2888,6 +2900,71 @@ bool shock_power(player_type *caster_ptr)
        return TRUE;
 }
 
+bool fetch_monster(player_type *caster_ptr)
+{
+       monster_type *m_ptr;
+       MONSTER_IDX m_idx;
+       GAME_TEXT m_name[MAX_NLEN];
+       int i;
+       int path_n;
+       u16b path_g[512];
+       POSITION ty, tx;
+
+       if (!target_set(caster_ptr, TARGET_KILL)) return FALSE;
+       m_idx = caster_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx;
+       if (!m_idx) return FALSE;
+       if (m_idx == caster_ptr->riding) return FALSE;
+       if (!player_has_los_bold(caster_ptr, target_row, target_col)) return FALSE;
+       if (!projectable(caster_ptr, caster_ptr->y, caster_ptr->x, target_row, target_col)) return FALSE;
+       m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
+       monster_desc(caster_ptr, m_name, m_ptr, 0);
+       msg_format(_("%sを引き戻した。", "You pull back %s."), m_name);
+       path_n = project_path(caster_ptr, path_g, MAX_RANGE, target_row, target_col, caster_ptr->y, caster_ptr->x, 0);
+       ty = target_row, tx = target_col;
+       for (i = 1; i < path_n; i++)
+       {
+               POSITION ny = GRID_Y(path_g[i]);
+               POSITION nx = GRID_X(path_g[i]);
+               grid_type *g_ptr = &caster_ptr->current_floor_ptr->grid_array[ny][nx];
+
+               if (in_bounds(caster_ptr->current_floor_ptr, ny, nx) && is_cave_empty_bold(caster_ptr, ny, nx) &&
+                       !(g_ptr->info & CAVE_OBJECT) &&
+                       !pattern_tile(caster_ptr->current_floor_ptr, ny, nx))
+               {
+                       ty = ny;
+                       tx = nx;
+               }
+       }
+       /* Update the old location */
+       caster_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx = 0;
+
+       /* Update the new location */
+       caster_ptr->current_floor_ptr->grid_array[ty][tx].m_idx = m_idx;
+
+       /* Move the monster */
+       m_ptr->fy = ty;
+       m_ptr->fx = tx;
+
+       /* Wake the monster up */
+       (void)set_monster_csleep(caster_ptr, m_idx, 0);
+
+       update_monster(caster_ptr, m_idx, TRUE);
+       lite_spot(caster_ptr, target_row, target_col);
+       lite_spot(caster_ptr, ty, tx);
+
+       if (r_info[m_ptr->r_idx].flags7 & (RF7_LITE_MASK | RF7_DARK_MASK))
+               caster_ptr->update |= (PU_MON_LITE);
+
+       if (m_ptr->ml)
+       {
+               /* Auto-Recall if possible and visible */
+               if (!caster_ptr->image) monster_race_track(caster_ptr, m_ptr->ap_r_idx);
+               health_track(caster_ptr, m_idx);
+       }
+       return TRUE;
+
+}
+
 
 bool booze(player_type *creature_ptr)
 {
@@ -2914,7 +2991,7 @@ bool booze(player_type *creature_ptr)
                ident = TRUE;
                if (one_in_(3)) lose_all_info(creature_ptr);
                else wiz_dark(creature_ptr);
-               (void)teleport_player_aux(creature_ptr, 100, TELEPORT_NONMAGICAL | TELEPORT_PASSIVE);
+               (void)teleport_player_aux(creature_ptr, 100, FALSE, TELEPORT_NONMAGICAL | TELEPORT_PASSIVE);
                wiz_dark(creature_ptr);
                msg_print(_("知らない場所で目が醒めた。頭痛がする。", "You wake up somewhere with a sore head..."));
                msg_print(_("何も思い出せない。どうやってここへ来たのかも分からない!", "You can't remember a thing or how you got here!"));
@@ -2953,6 +3030,7 @@ void blood_curse_to_enemy(player_type *caster_ptr, MONSTER_IDX m_idx)
                                earthquake(caster_ptr, m_ptr->fy, m_ptr->fx, 4 + randint0(4), 0);
                                if (!one_in_(6)) break;
                        }
+                       /* Fall through */
                case 3: case 4: case 5: case 6:
                        if (!count)
                        {
@@ -2962,6 +3040,7 @@ void blood_curse_to_enemy(player_type *caster_ptr, MONSTER_IDX m_idx)
                                project(caster_ptr, 0, 8, m_ptr->fy, m_ptr->fx, extra_dam, GF_MANA, curse_flg, -1);
                                if (!one_in_(6)) break;
                        }
+                       /* Fall through */
                case 7: case 8:
                        if (!count)
                        {
@@ -2971,16 +3050,20 @@ void blood_curse_to_enemy(player_type *caster_ptr, MONSTER_IDX m_idx)
                                if (one_in_(13)) count += activate_hi_summon(caster_ptr, m_ptr->fy, m_ptr->fx, TRUE);
                                if (!one_in_(6)) break;
                        }
+                       /* Fall through */
                case 9: case 10: case 11:
                        msg_print(_("エネルギーのうねりを感じた!", "You feel a surge of energy!"));
                        project(caster_ptr, 0, 7, m_ptr->fy, m_ptr->fx, 50, GF_DISINTEGRATE, curse_flg, -1);
                        if (!one_in_(6)) break;
+                       /* Fall through */
                case 12: case 13: case 14: case 15: case 16:
                        aggravate_monsters(caster_ptr, 0);
                        if (!one_in_(6)) break;
+                       /* Fall through */
                case 17: case 18:
                        count += activate_hi_summon(caster_ptr, m_ptr->fy, m_ptr->fx, TRUE);
                        if (!one_in_(6)) break;
+                       /* Fall through */
                case 19: case 20: case 21: case 22:
                {
                        bool pet = !one_in_(3);
@@ -2992,6 +3075,7 @@ void blood_curse_to_enemy(player_type *caster_ptr, MONSTER_IDX m_idx)
                        count += summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, (pet ? caster_ptr->lev * 2 / 3 + randint1(caster_ptr->lev / 2) : caster_ptr->current_floor_ptr->dun_level), 0, mode);
                        if (!one_in_(6)) break;
                }
+                       /* Fall through */
                case 23: case 24: case 25:
                        if (caster_ptr->hold_exp && (randint0(100) < 75)) break;
                        msg_print(_("経験値が体から吸い取られた気がする!", "You feel your experience draining away..."));
@@ -2999,6 +3083,7 @@ void blood_curse_to_enemy(player_type *caster_ptr, MONSTER_IDX m_idx)
                        if (caster_ptr->hold_exp) lose_exp(caster_ptr, caster_ptr->exp / 160);
                        else lose_exp(caster_ptr, caster_ptr->exp / 16);
                        if (!one_in_(6)) break;
+                       /* Fall through */
                case 26: case 27: case 28:
                {
                        if (one_in_(13))