OSDN Git Service

[feature] ソースファイルをC++に対応
[hengbandforosx/hengbandosx.git] / src / spell-kind / spells-teleport.c
index 11b398d..8b4dc57 100644 (file)
@@ -1,31 +1,42 @@
 /*!
- * todo 少し長いかも
  * @brief テレポート魔法全般
  * @date 2020/06/04
  * @author Hourier
  */
 
 #include "spell-kind/spells-teleport.h"
-#include "art-definition/art-bow-types.h"
-#include "cmd-io/cmd-save.h"
-#include "dungeon/dungeon.h"
-#include "dungeon/quest.h"
+#include "core/asking-player.h"
+#include "core/player-update-types.h"
+#include "core/speed-table.h"
 #include "effect/effect-characteristics.h"
-#include "io/targeting.h"
-#include "io/write-diary.h"
+#include "floor/cave.h"
+#include "floor/line-of-sight.h"
+#include "grid/grid.h"
+#include "inventory/inventory-slot-types.h"
 #include "main/sound-definitions-table.h"
-#include "core/speed-table.h"
-#include "monster/monster-description-types.h"
+#include "main/sound-of-music.h"
+#include "monster-floor/monster-move.h"
+#include "monster-race/monster-race.h"
+#include "monster-race/race-flags-ability2.h"
+#include "monster-race/race-flags-resistance.h"
+#include "monster-race/race-flags7.h"
+#include "monster/monster-info.h"
+#include "monster/monster-status-setter.h"
 #include "monster/monster-status.h"
-#include "monster/monster2.h"
-#include "monster/smart-learn-types.h"
+#include "monster/monster-update.h"
+#include "mutation/mutation-flag-types.h"
 #include "object-enchant/tr-types.h"
+#include "object-hook/hook-checker.h"
 #include "object/object-flags.h"
-#include "object/object-hook.h"
-#include "player/avatar.h"
+#include "player-info/avatar.h"
 #include "player/player-move.h"
 #include "spell-kind/spells-launcher.h"
-#include "spell/spells-type.h"
+#include "spell/spell-types.h"
+#include "system/floor-type-definition.h"
+#include "target/grid-selector.h"
+#include "target/target-checker.h"
+#include "util/bit-flags-calculator.h"
+#include "view/display-messages.h"
 #include "world/world.h"
 
 /*!
@@ -344,7 +355,7 @@ bool teleport_player_aux(player_type *creature_ptr, POSITION dis, bool is_quantu
 
     sound(SOUND_TELEPORT);
 #ifdef JP
-    if (IS_ECHIZEN(creature_ptr))
+    if (is_echizen(creature_ptr))
         msg_format("『こっちだぁ、%s』", creature_ptr->name);
 #endif
     (void)move_player_effect(creature_ptr, yy, xx, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
@@ -360,7 +371,7 @@ bool teleport_player_aux(player_type *creature_ptr, POSITION dis, bool is_quantu
  */
 void teleport_player(player_type *creature_ptr, POSITION dis, BIT_FLAGS mode)
 {
-    if (!teleport_player_aux(creature_ptr, dis, FALSE, mode))
+    if (!teleport_player_aux(creature_ptr, dis, FALSE, static_cast<teleport_flags>(mode)))
         return;
 
     /* Monsters with teleport ability may follow the player */
@@ -370,17 +381,15 @@ void teleport_player(player_type *creature_ptr, POSITION dis, BIT_FLAGS mode)
         for (POSITION yy = -1; yy < 2; yy++) {
             MONSTER_IDX tmp_m_idx = creature_ptr->current_floor_ptr->grid_array[oy + yy][ox + xx].m_idx;
             if (tmp_m_idx && (creature_ptr->riding != tmp_m_idx)) {
-                continue;
-            }
-
-            monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[tmp_m_idx];
-            monster_race *r_ptr = &r_info[m_ptr->r_idx];
-
-            bool is_resistible = (r_ptr->a_ability_flags2 & RF6_TPORT) != 0;
-            is_resistible &= (r_ptr->flagsr & RFR_RES_TELE) == 0;
-            is_resistible &= monster_csleep_remaining(m_ptr) == 0;
-            if (is_resistible) {
-                teleport_monster_to(creature_ptr, tmp_m_idx, creature_ptr->y, creature_ptr->x, r_ptr->level, TELEPORT_SPONTANEOUS);
+                monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[tmp_m_idx];
+                monster_race *r_ptr = &r_info[m_ptr->r_idx];
+
+                bool is_resistible = (r_ptr->a_ability_flags2 & RF6_TPORT) != 0;
+                is_resistible &= (r_ptr->flagsr & RFR_RES_TELE) == 0;
+                is_resistible &= monster_csleep_remaining(m_ptr) == 0;
+                if (is_resistible) {
+                    teleport_monster_to(creature_ptr, tmp_m_idx, creature_ptr->y, creature_ptr->x, r_ptr->level, TELEPORT_SPONTANEOUS);
+                }
             }
         }
     }
@@ -396,7 +405,7 @@ void teleport_player(player_type *creature_ptr, POSITION dis, BIT_FLAGS mode)
  */
 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, is_quantum_effect))
+    if (!teleport_player_aux(target_ptr, dis, is_quantum_effect, TELEPORT_PASSIVE))
         return;
 
     /* Monsters with teleport ability may follow the player */
@@ -503,11 +512,11 @@ void teleport_away_followable(player_type *tracer_ptr, MONSTER_IDX m_idx)
         object_type *o_ptr;
         INVENTORY_IDX i;
 
-        for (i = INVEN_RARM; i < INVEN_TOTAL; i++) {
+        for (i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
             o_ptr = &tracer_ptr->inventory_list[i];
             if (o_ptr->k_idx && !object_is_cursed(o_ptr)) {
-                object_flags(o_ptr, flgs);
-                if (have_flag(flgs, TR_TELEPORT)) {
+                object_flags(tracer_ptr, o_ptr, flgs);
+                if (has_flag(flgs, TR_TELEPORT)) {
                     follow = TRUE;
                     break;
                 }
@@ -517,7 +526,7 @@ void teleport_away_followable(player_type *tracer_ptr, MONSTER_IDX m_idx)
 
     if (!follow)
         return;
-    if (!get_check_strict(_("ついていきますか?", "Do you follow it? "), CHECK_OKAY_CANCEL))
+    if (!get_check_strict(tracer_ptr, _("ついていきますか?", "Do you follow it? "), CHECK_OKAY_CANCEL))
         return;
 
     if (one_in_(3)) {
@@ -530,208 +539,6 @@ void teleport_away_followable(player_type *tracer_ptr, MONSTER_IDX m_idx)
     tracer_ptr->energy_need += ENERGY_NEED();
 }
 
-bool teleport_level_other(player_type *caster_ptr)
-{
-    if (!target_set(caster_ptr, TARGET_KILL))
-        return FALSE;
-    MONSTER_IDX target_m_idx = caster_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx;
-    if (!target_m_idx)
-        return TRUE;
-    if (!player_has_los_bold(caster_ptr, target_row, target_col))
-        return TRUE;
-    if (!projectable(caster_ptr, caster_ptr->y, caster_ptr->x, target_row, target_col))
-        return TRUE;
-
-    monster_type *m_ptr;
-    monster_race *r_ptr;
-    m_ptr = &caster_ptr->current_floor_ptr->m_list[target_m_idx];
-    r_ptr = &r_info[m_ptr->r_idx];
-    GAME_TEXT m_name[MAX_NLEN];
-    monster_desc(caster_ptr, m_name, m_ptr, 0);
-    msg_format(_("%^sの足を指さした。", "You gesture at %^s's feet."), m_name);
-
-    if ((r_ptr->flagsr & (RFR_EFF_RES_NEXU_MASK | RFR_RES_TELE)) || (r_ptr->flags1 & RF1_QUESTOR)
-        || (r_ptr->level + randint1(50) > caster_ptr->lev + randint1(60))) {
-        msg_format(_("しかし効果がなかった!", "%^s is unaffected!"), m_name);
-    } else {
-        teleport_level(caster_ptr, target_m_idx);
-    }
-
-    return TRUE;
-}
-
-/*!
- * todo cmd-save.h への依存あり。コールバックで何とかしたい
- * @brief プレイヤー及びモンスターをレベルテレポートさせる /
- * Teleport the player one level up or down (random when legal)
- * @param creature_ptr プレーヤーへの参照ポインタ
- * @param m_idx テレポートの対象となるモンスターID(0ならばプレイヤー) / If m_idx <= 0, target is player.
- * @return なし
- */
-void teleport_level(player_type *creature_ptr, MONSTER_IDX m_idx)
-{
-    GAME_TEXT m_name[160];
-    bool see_m = TRUE;
-    if (m_idx <= 0) {
-        strcpy(m_name, _("あなた", "you"));
-    } else {
-        monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[m_idx];
-        monster_desc(creature_ptr, m_name, m_ptr, 0);
-        see_m = is_seen(m_ptr);
-    }
-
-    if (is_teleport_level_ineffective(creature_ptr, m_idx)) {
-        if (see_m)
-            msg_print(_("効果がなかった。", "There is no effect."));
-        return;
-    }
-
-    if ((m_idx <= 0) && creature_ptr->anti_tele) {
-        msg_print(_("不思議な力がテレポートを防いだ!", "A mysterious force prevents you from teleporting!"));
-        return;
-    }
-
-    bool go_up;
-    if (randint0(100) < 50)
-        go_up = TRUE;
-    else
-        go_up = FALSE;
-
-    if ((m_idx <= 0) && current_world_ptr->wizard) {
-        if (get_check("Force to go up? "))
-            go_up = TRUE;
-        else if (get_check("Force to go down? "))
-            go_up = FALSE;
-    }
-
-    if ((ironman_downward && (m_idx <= 0)) || (creature_ptr->current_floor_ptr->dun_level <= d_info[creature_ptr->dungeon_idx].mindepth)) {
-#ifdef JP
-        if (see_m)
-            msg_format("%^sは床を突き破って沈んでいく。", m_name);
-#else
-        if (see_m)
-            msg_format("%^s sink%s through the floor.", m_name, (m_idx <= 0) ? "" : "s");
-#endif
-        if (m_idx <= 0) {
-            if (!creature_ptr->current_floor_ptr->dun_level) {
-                creature_ptr->dungeon_idx = ironman_downward ? DUNGEON_ANGBAND : creature_ptr->recall_dungeon;
-                creature_ptr->oldpy = creature_ptr->y;
-                creature_ptr->oldpx = creature_ptr->x;
-            }
-
-            if (record_stair)
-                exe_write_diary(creature_ptr, DIARY_TELEPORT_LEVEL, 1, NULL);
-
-            if (autosave_l)
-                do_cmd_save_game(creature_ptr, TRUE);
-
-            if (!creature_ptr->current_floor_ptr->dun_level) {
-                creature_ptr->current_floor_ptr->dun_level = d_info[creature_ptr->dungeon_idx].mindepth;
-                prepare_change_floor_mode(creature_ptr, CFM_RAND_PLACE);
-            } else {
-                prepare_change_floor_mode(creature_ptr, CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
-            }
-
-            creature_ptr->leaving = TRUE;
-        }
-    } else if (quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level)
-        || (creature_ptr->current_floor_ptr->dun_level >= d_info[creature_ptr->dungeon_idx].maxdepth)) {
-#ifdef JP
-        if (see_m)
-            msg_format("%^sは天井を突き破って宙へ浮いていく。", m_name);
-#else
-        if (see_m)
-            msg_format("%^s rise%s up through the ceiling.", m_name, (m_idx <= 0) ? "" : "s");
-#endif
-
-        if (m_idx <= 0) {
-            if (record_stair)
-                exe_write_diary(creature_ptr, DIARY_TELEPORT_LEVEL, -1, NULL);
-
-            if (autosave_l)
-                do_cmd_save_game(creature_ptr, TRUE);
-
-            prepare_change_floor_mode(creature_ptr, CFM_SAVE_FLOORS | CFM_UP | CFM_RAND_PLACE | CFM_RAND_CONNECT);
-
-            leave_quest_check(creature_ptr);
-            creature_ptr->current_floor_ptr->inside_quest = 0;
-            creature_ptr->leaving = TRUE;
-        }
-    } else if (go_up) {
-#ifdef JP
-        if (see_m)
-            msg_format("%^sは天井を突き破って宙へ浮いていく。", m_name);
-#else
-        if (see_m)
-            msg_format("%^s rise%s up through the ceiling.", m_name, (m_idx <= 0) ? "" : "s");
-#endif
-
-        if (m_idx <= 0) {
-            if (record_stair)
-                exe_write_diary(creature_ptr, DIARY_TELEPORT_LEVEL, -1, NULL);
-
-            if (autosave_l)
-                do_cmd_save_game(creature_ptr, TRUE);
-
-            prepare_change_floor_mode(creature_ptr, CFM_SAVE_FLOORS | CFM_UP | CFM_RAND_PLACE | CFM_RAND_CONNECT);
-            creature_ptr->leaving = TRUE;
-        }
-    } else {
-#ifdef JP
-        if (see_m)
-            msg_format("%^sは床を突き破って沈んでいく。", m_name);
-#else
-        if (see_m)
-            msg_format("%^s sink%s through the floor.", m_name, (m_idx <= 0) ? "" : "s");
-#endif
-
-        if (m_idx <= 0) {
-            if (record_stair)
-                exe_write_diary(creature_ptr, DIARY_TELEPORT_LEVEL, 1, NULL);
-            if (autosave_l)
-                do_cmd_save_game(creature_ptr, TRUE);
-
-            prepare_change_floor_mode(creature_ptr, CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
-            creature_ptr->leaving = TRUE;
-        }
-    }
-
-    if (m_idx <= 0) {
-        sound(SOUND_TPLEVEL);
-        return;
-    }
-
-    monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[m_idx];
-    check_quest_completion(creature_ptr, m_ptr);
-    if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname) {
-        char m2_name[MAX_NLEN];
-
-        monster_desc(creature_ptr, m2_name, m_ptr, MD_INDEF_VISIBLE);
-        exe_write_diary(creature_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_TELE_LEVEL, m2_name);
-    }
-
-    delete_monster_idx(creature_ptr, m_idx);
-    sound(SOUND_TPLEVEL);
-}
-
-/*!
- * todo 変数名が実態と合っているかどうかは要確認
- * テレポート・レベルが効かないモンスターであるかどうかを判定する
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param idx テレポート・レベル対象のモンスター
- */
-bool is_teleport_level_ineffective(player_type *caster_ptr, MONSTER_IDX idx)
-{
-    floor_type *floor_ptr = caster_ptr->current_floor_ptr;
-    bool is_special_floor
-        = floor_ptr->inside_arena || caster_ptr->phase_out || (floor_ptr->inside_quest && !random_quest_number(caster_ptr, floor_ptr->dun_level));
-    bool is_invalid_floor = idx <= 0;
-    is_invalid_floor &= quest_number(caster_ptr, floor_ptr->dun_level) || (floor_ptr->dun_level >= d_info[caster_ptr->dungeon_idx].maxdepth);
-    is_invalid_floor &= caster_ptr->current_floor_ptr->dun_level >= 1;
-    is_invalid_floor &= ironman_downward;
-    return is_special_floor || is_invalid_floor;
-}
-
 /*!
  * @brief 次元の扉処理 /
  * Dimension Door