OSDN Git Service

[Refactor] #40414 Separated earthquake.c/h from spells-floor.c/h
authorHourier <hourier@users.sourceforge.jp>
Fri, 5 Jun 2020 13:49:13 +0000 (22:49 +0900)
committerHourier <hourier@users.sourceforge.jp>
Fri, 5 Jun 2020 13:55:55 +0000 (22:55 +0900)
22 files changed:
Hengband/Hengband/Hengband.vcxproj
Hengband/Hengband/Hengband.vcxproj.filters
src/Makefile.am
src/cmd-item/cmd-activate.c
src/cmd-item/cmd-usestaff.c
src/combat/melee-switcher.c
src/combat/monster-attack-switcher.c
src/combat/player-attack.c
src/mind/mind.c
src/mutation/mutation.c
src/realm/realm-hissatsu.c
src/realm/realm-nature.c
src/realm/realm-song.c
src/spell-kind/earthquake.c [new file with mode: 0644]
src/spell-kind/earthquake.h [new file with mode: 0644]
src/spell-kind/spells-floor.c
src/spell-kind/spells-floor.h
src/spell-kind/spells-neighbor.c
src/spell-kind/spells-random.c
src/spell-kind/spells-shuffle.c
src/spell/spells-summon.c
src/spell/spells3.c

index 15b6558..62a4dcb 100644 (file)
     <ClCompile Include="..\..\src\mspell\mspell-summon.c" />\r
     <ClCompile Include="..\..\src\mspell\mspell-util.c" />\r
     <ClCompile Include="..\..\src\mspell\mspell-ball.c" />\r
+    <ClCompile Include="..\..\src\spell-kind\earthquake.c" />\r
     <ClCompile Include="..\..\src\spell-kind\spells-beam.c" />\r
     <ClCompile Include="..\..\src\spell-kind\spells-grid.c" />\r
     <ClCompile Include="..\..\src\spell-kind\spells-random.c" />\r
     <ClInclude Include="..\..\src\object-enchant\special-object-flags.h" />\r
     <ClInclude Include="..\..\src\realm\realm-hex-numbers.h" />\r
     <ClInclude Include="..\..\src\realm\realm-song-numbers.h" />\r
+    <ClInclude Include="..\..\src\spell-kind\earthquake.h" />\r
     <ClInclude Include="..\..\src\spell-kind\spells-beam.h" />\r
     <ClInclude Include="..\..\src\spell-kind\spells-grid.h" />\r
     <ClInclude Include="..\..\src\spell-kind\spells-random.h" />\r
index e2b1a52..3f007a5 100644 (file)
     <ClCompile Include="..\..\src\spell-kind\spells-grid.c">
       <Filter>spell-kind</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\spell-kind\earthquake.c">
+      <Filter>spell-kind</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\cmd\cmd-basic.h">
     <ClInclude Include="..\..\src\spell-kind\spells-grid.h">
       <Filter>spell-kind</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\spell-kind\earthquake.h">
+      <Filter>spell-kind</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\src\wall.bmp" />
index 7a0ffd4..a612da4 100644 (file)
@@ -401,6 +401,7 @@ hengband_SOURCES = \
        spell/spells-util.h spell/spells-type.h \
        spell/technic-info-table.c spell/technic-info-table.h \
        \
+       spell-kind/earthquake.c spell-kind/earthquake.h \
        spell-kind/spells-beam.c spell-kind/spells-beam.h \
        spell-kind/spells-chaos.c spell-kind/spells-chaos.h \
        spell-kind/spells-charm.c spell-kind/spells-charm.h \
index 7fbb6d5..3fa025b 100644 (file)
@@ -28,8 +28,8 @@
 #include "player/player-effects.h"
 #include "player/player-races-table.h"
 #include "spell/process-effect.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-beam.h"
-#include "spell-kind/spells-random.h"
 #include "spell-kind/spells-charm.h"
 #include "spell-kind/spells-detection.h"
 #include "spell-kind/spells-floor.h"
@@ -39,6 +39,7 @@
 #include "spell-kind/spells-launcher.h"
 #include "spell-kind/spells-lite.h"
 #include "spell-kind/spells-neighbor.h"
+#include "spell-kind/spells-random.h"
 #include "spell/spells-object.h"
 #include "spell-kind/spells-sight.h"
 #include "spell-kind/spells-specific-bolt.h"
index 5b1686e..7246930 100644 (file)
@@ -26,6 +26,7 @@
 #include "spell/spells-staff-only.h"
 #include "spell/spells-status.h"
 #include "spell/spells-summon.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-teleport.h"
 #include "spell/spells3.h"
 #include "util/util.h"
index f22966a..cdc6cd9 100644 (file)
@@ -8,7 +8,7 @@
 #include "combat/monster-attack-effect.h"
 #include "monster/monster-status.h"
 #include "player/player-move.h"
-#include "spell-kind/spells-floor.h"
+#include "spell-kind/earthquake.h"
 
 void describe_melee_method(player_type *subject_ptr, mam_type *mam_ptr)
 {
index 3e044bb..3102eb8 100644 (file)
@@ -11,8 +11,8 @@
 #include "mind/mind-mirror-master.h"
 #include "player/player-damage.h"
 #include "player/player-effects.h"
+#include "spell-kind/earthquake.h"
 #include "spell/spells3.h"
-#include "spell-kind/spells-floor.h"
 
 void switch_monster_blow_to_player(player_type *target_ptr, monap_type *monap_ptr)
 {
index 0a2b097..dce3a68 100644 (file)
@@ -15,9 +15,9 @@
 #include "combat/vorpal-weapon.h"
 #include "floor/floor.h"
 #include "main/sound-definitions-table.h"
-#include "mind/monk-attack.h"
 #include "mind/mind-ninja.h"
 #include "mind/mind-samurai.h"
+#include "mind/monk-attack.h"
 #include "monster/monster-race-hook.h"
 #include "monster/monster-status.h"
 #include "object-enchant/artifact.h"
@@ -28,7 +28,7 @@
 #include "player/player-damage.h"
 #include "player/player-skill.h"
 #include "realm/realm-hex-numbers.h"
-#include "spell-kind/spells-floor.h"
+#include "spell-kind/earthquake.h"
 #include "spell-realm/spells-hex.h"
 #include "sv-definition/sv-weapon-types.h"
 #include "world/world.h"
index 6373f9a..aac79f5 100644 (file)
@@ -39,6 +39,7 @@
 #include "player/player-status.h"
 #include "realm/realm-song-numbers.h"
 #include "spell/process-effect.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-detection.h"
 #include "spell-kind/spells-floor.h"
 #include "spell-kind/spells-grid.h"
index c9ad384..e8529a8 100644 (file)
@@ -33,9 +33,9 @@
 #include "player/player-races-table.h"
 #include "player/player-status.h"
 #include "player/selfinfo.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-charm.h"
 #include "spell-kind/spells-detection.h"
-#include "spell-kind/spells-floor.h"
 #include "spell-kind/spells-launcher.h"
 #include "spell-kind/spells-lite.h"
 #include "spell-kind/spells-sight.h"
index 2e85bf7..686de97 100644 (file)
@@ -20,8 +20,8 @@
 #include "player/player-move.h"
 #include "player/player-status.h"
 #include "spell/process-effect.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-detection.h"
-#include "spell-kind/spells-floor.h"
 #include "spell-kind/spells-launcher.h"
 #include "spell-kind/spells-sight.h"
 #include "spell-kind/spells-teleport.h"
index 904a50f..aac7ceb 100644 (file)
@@ -10,6 +10,7 @@
 #include "player/player-damage.h"
 #include "player/player-effects.h"
 #include "player/player-races-table.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-beam.h"
 #include "spell-kind/spells-charm.h"
 #include "spell-kind/spells-detection.h"
index 2e203f8..8a9f6ac 100644 (file)
@@ -5,6 +5,7 @@
 #include "player/player-effects.h"
 #include "realm/realm-song-numbers.h"
 #include "spell/process-effect.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-detection.h"
 #include "spell-kind/spells-floor.h"
 #include "spell-kind/spells-grid.h"
diff --git a/src/spell-kind/earthquake.c b/src/spell-kind/earthquake.c
new file mode 100644 (file)
index 0000000..e2f9ad0
--- /dev/null
@@ -0,0 +1,421 @@
+#include "spell-kind/earthquake.h"
+#include "dungeon/dungeon.h"
+#include "dungeon/quest.h"
+#include "floor/floor-events.h"
+#include "floor/floor-object.h"
+#include "floor/floor.h"
+#include "io/write-diary.h"
+#include "monster/monster-status.h"
+#include "player/player-damage.h"
+#include "player/player-effects.h"
+#include "player/player-move.h"
+
+/*!
+ * @brief 地震処理(サブルーチン) /
+ * Induce an "earthquake" of the given radius at the given location.
+ * @param caster_ptrプレーヤーへの参照ポインタ
+ * @param cy 中心Y座標
+ * @param cx 中心X座標
+ * @param r 効果半径
+ * @param m_idx 地震を起こしたモンスターID(0ならばプレイヤー)
+ * @return 効力があった場合TRUEを返す
+ */
+bool earthquake(player_type *caster_ptr, POSITION cy, POSITION cx, POSITION r, MONSTER_IDX m_idx)
+{
+    /* Prevent destruction of quest levels and town */
+    floor_type *floor_ptr = caster_ptr->current_floor_ptr;
+    if ((floor_ptr->inside_quest && is_fixed_quest_idx(floor_ptr->inside_quest)) || !floor_ptr->dun_level) {
+        return FALSE;
+    }
+
+    /* Paranoia -- Enforce maximum range */
+    if (r > 12)
+        r = 12;
+
+    /* Clear the "maximal blast" area */
+    POSITION y, x;
+    bool map[32][32];
+    for (y = 0; y < 32; y++) {
+        for (x = 0; x < 32; x++) {
+            map[y][x] = FALSE;
+        }
+    }
+
+    /* Check around the epicenter */
+    POSITION yy, xx, dy, dx;
+    int damage = 0;
+    bool hurt = FALSE;
+    for (dy = -r; dy <= r; dy++) {
+        for (dx = -r; dx <= r; dx++) {
+            yy = cy + dy;
+            xx = cx + dx;
+
+            if (!in_bounds(floor_ptr, yy, xx))
+                continue;
+
+            /* Skip distant grids */
+            if (distance(cy, cx, yy, xx) > r)
+                continue;
+            grid_type *g_ptr;
+            g_ptr = &floor_ptr->grid_array[yy][xx];
+
+            /* Lose room and vault / Lose light and knowledge */
+            g_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY | CAVE_UNSAFE);
+            g_ptr->info &= ~(CAVE_GLOW | CAVE_MARK | CAVE_KNOWN);
+
+            /* Skip the epicenter */
+            if (!dx && !dy)
+                continue;
+
+            /* Skip most grids */
+            if (randint0(100) < 85)
+                continue;
+
+            /* Damage this grid */
+            map[16 + yy - cy][16 + xx - cx] = TRUE;
+
+            /* Hack -- Take note of player damage */
+            if (player_bold(caster_ptr, yy, xx))
+                hurt = TRUE;
+        }
+    }
+
+    /* First, affect the player (if necessary) */
+    int sn = 0;
+    POSITION sy = 0, sx = 0;
+    if (hurt && !caster_ptr->pass_wall && !caster_ptr->kill_wall) {
+        /* Check around the player */
+        for (DIRECTION i = 0; i < 8; i++) {
+            y = caster_ptr->y + ddy_ddd[i];
+            x = caster_ptr->x + ddx_ddd[i];
+
+            /* Skip non-empty grids */
+            if (!is_cave_empty_bold(caster_ptr, y, x))
+                continue;
+
+            /* Important -- Skip "quake" grids */
+            if (map[16 + y - cy][16 + x - cx])
+                continue;
+
+            if (floor_ptr->grid_array[y][x].m_idx)
+                continue;
+
+            /* Count "safe" grids */
+            sn++;
+
+            /* Randomize choice */
+            if (randint0(sn) > 0)
+                continue;
+
+            /* Save the safe location */
+            sy = y;
+            sx = x;
+        }
+
+        /* Random message */
+        switch (randint1(3)) {
+        case 1: {
+            msg_print(_("ダンジョンの壁が崩れた!", "The dungeon's ceiling collapses!"));
+            break;
+        }
+        case 2: {
+            msg_print(_("ダンジョンの床が不自然にねじ曲がった!", "The dungeon's floor twists in an unnatural way!"));
+            break;
+        }
+        default: {
+            msg_print(_("ダンジョンが揺れた!崩れた岩が頭に降ってきた!", "The dungeon quakes!  You are pummeled with debris!"));
+            break;
+        }
+        }
+
+        /* Hurt the player a lot */
+        if (!sn) {
+            /* Message and damage */
+            msg_print(_("あなたはひどい怪我を負った!", "You are severely crushed!"));
+            damage = 200;
+        }
+
+        /* Destroy the grid, and push the player to safety */
+        else {
+            /* Calculate results */
+            switch (randint1(3)) {
+            case 1: {
+                msg_print(_("降り注ぐ岩をうまく避けた!", "You nimbly dodge the blast!"));
+                damage = 0;
+                break;
+            }
+            case 2: {
+                msg_print(_("岩石があなたに直撃した!", "You are bashed by rubble!"));
+                damage = damroll(10, 4);
+                (void)set_stun(caster_ptr, caster_ptr->stun + randint1(50));
+                break;
+            }
+            case 3: {
+                msg_print(_("あなたは床と壁との間に挟まれてしまった!", "You are crushed between the floor and ceiling!"));
+                damage = damroll(10, 4);
+                (void)set_stun(caster_ptr, caster_ptr->stun + randint1(50));
+                break;
+            }
+            }
+
+            /* Move the player to the safe location */
+            (void)move_player_effect(caster_ptr, sy, sx, MPE_DONT_PICKUP);
+        }
+
+        /* Important -- no wall on player */
+        map[16 + caster_ptr->y - cy][16 + caster_ptr->x - cx] = FALSE;
+
+        if (damage) {
+            concptr killer;
+
+            if (m_idx) {
+                GAME_TEXT m_name[MAX_NLEN];
+                monster_type *m_ptr = &floor_ptr->m_list[m_idx];
+                monster_desc(caster_ptr, m_name, m_ptr, MD_WRONGDOER_NAME);
+                killer = format(_("%sの起こした地震", "an earthquake caused by %s"), m_name);
+            } else {
+                killer = _("地震", "an earthquake");
+            }
+
+            take_hit(caster_ptr, DAMAGE_ATTACK, damage, killer, -1);
+        }
+    }
+
+    /* Examine the quaked region */
+    for (dy = -r; dy <= r; dy++) {
+        for (dx = -r; dx <= r; dx++) {
+            yy = cy + dy;
+            xx = cx + dx;
+
+            /* Skip unaffected grids */
+            if (!map[16 + yy - cy][16 + xx - cx])
+                continue;
+
+            grid_type *g_ptr;
+            g_ptr = &floor_ptr->grid_array[yy][xx];
+
+            if (g_ptr->m_idx == caster_ptr->riding)
+                continue;
+
+            /* Process monsters */
+            if (!g_ptr->m_idx)
+                continue;
+
+            monster_type *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
+            monster_race *r_ptr = &r_info[m_ptr->r_idx];
+
+            /* Quest monsters */
+            if (r_ptr->flags1 & RF1_QUESTOR) {
+                /* No wall on quest monsters */
+                map[16 + yy - cy][16 + xx - cx] = FALSE;
+
+                continue;
+            }
+
+            /* Most monsters cannot co-exist with rock */
+            if ((r_ptr->flags2 & RF2_KILL_WALL) || (r_ptr->flags2 & RF2_PASS_WALL))
+                continue;
+
+            GAME_TEXT m_name[MAX_NLEN];
+
+            /* Assume not safe */
+            sn = 0;
+
+            /* Monster can move to escape the wall */
+            if (!(r_ptr->flags1 & RF1_NEVER_MOVE)) {
+                /* Look for safety */
+                for (DIRECTION i = 0; i < 8; i++) {
+                    y = yy + ddy_ddd[i];
+                    x = xx + ddx_ddd[i];
+
+                    /* Skip non-empty grids */
+                    if (!is_cave_empty_bold(caster_ptr, y, x))
+                        continue;
+
+                    /* Hack -- no safety on glyph of warding */
+                    if (is_glyph_grid(&floor_ptr->grid_array[y][x]))
+                        continue;
+                    if (is_explosive_rune_grid(&floor_ptr->grid_array[y][x]))
+                        continue;
+
+                    /* ... nor on the Pattern */
+                    if (pattern_tile(floor_ptr, y, x))
+                        continue;
+
+                    /* Important -- Skip "quake" grids */
+                    if (map[16 + y - cy][16 + x - cx])
+                        continue;
+
+                    if (floor_ptr->grid_array[y][x].m_idx)
+                        continue;
+                    if (player_bold(caster_ptr, y, x))
+                        continue;
+
+                    /* Count "safe" grids */
+                    sn++;
+
+                    /* Randomize choice */
+                    if (randint0(sn) > 0)
+                        continue;
+
+                    /* Save the safe grid */
+                    sy = y;
+                    sx = x;
+                }
+            }
+
+            monster_desc(caster_ptr, m_name, m_ptr, 0);
+
+            /* Scream in pain */
+            if (!ignore_unview || is_seen(m_ptr))
+                msg_format(_("%^sは苦痛で泣きわめいた!", "%^s wails out in pain!"), m_name);
+
+            /* Take damage from the quake */
+            damage = (sn ? damroll(4, 8) : (m_ptr->hp + 1));
+
+            /* Monster is certainly awake */
+            (void)set_monster_csleep(caster_ptr, g_ptr->m_idx, 0);
+
+            /* Apply damage directly */
+            m_ptr->hp -= damage;
+
+            /* Delete (not kill) "dead" monsters */
+            if (m_ptr->hp < 0) {
+                if (!ignore_unview || is_seen(m_ptr))
+                    msg_format(_("%^sは岩石に埋もれてしまった!", "%^s is embedded in the rock!"), m_name);
+
+                if (g_ptr->m_idx) {
+                    if (record_named_pet && is_pet(&floor_ptr->m_list[g_ptr->m_idx]) && floor_ptr->m_list[g_ptr->m_idx].nickname) {
+                        char m2_name[MAX_NLEN];
+
+                        monster_desc(caster_ptr, m2_name, m_ptr, MD_INDEF_VISIBLE);
+                        exe_write_diary(caster_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_EARTHQUAKE, m2_name);
+                    }
+                }
+
+                delete_monster(caster_ptr, yy, xx);
+
+                sn = 0;
+            }
+
+            /* Hack -- Escape from the rock */
+            if (sn == 0)
+                continue;
+
+            IDX m_idx_aux = floor_ptr->grid_array[yy][xx].m_idx;
+
+            /* Update the old location */
+            floor_ptr->grid_array[yy][xx].m_idx = 0;
+
+            /* Update the new location */
+            floor_ptr->grid_array[sy][sx].m_idx = m_idx_aux;
+
+            /* Move the monster */
+            m_ptr->fy = sy;
+            m_ptr->fx = sx;
+
+            update_monster(caster_ptr, m_idx, TRUE);
+            lite_spot(caster_ptr, yy, xx);
+            lite_spot(caster_ptr, sy, sx);
+        }
+    }
+
+    /* Lose monster light */
+    clear_mon_lite(floor_ptr);
+
+    /* Examine the quaked region */
+    for (dy = -r; dy <= r; dy++) {
+        for (dx = -r; dx <= r; dx++) {
+            yy = cy + dy;
+            xx = cx + dx;
+
+            /* Skip unaffected grids */
+            if (!map[16 + yy - cy][16 + xx - cx])
+                continue;
+
+            /* Destroy location (if valid) */
+            if (!cave_valid_bold(floor_ptr, yy, xx))
+                continue;
+
+            delete_all_items_from_floor(caster_ptr, yy, xx);
+
+            /* Wall (or floor) type */
+            int t = cave_have_flag_bold(floor_ptr, yy, xx, FF_PROJECT) ? randint0(100) : 200;
+
+            /* Create granite wall */
+            if (t < 20) {
+                cave_set_feat(caster_ptr, yy, xx, feat_granite);
+                continue;
+            }
+
+            /* Create quartz vein */
+            if (t < 70) {
+                cave_set_feat(caster_ptr, yy, xx, feat_quartz_vein);
+                continue;
+            }
+
+            /* Create magma vein */
+            if (t < 100) {
+                cave_set_feat(caster_ptr, yy, xx, feat_magma_vein);
+                continue;
+            }
+
+            /* Create floor */
+            cave_set_feat(caster_ptr, yy, xx, feat_ground_type[randint0(100)]);
+        }
+    }
+
+    /* Process "re-glowing" */
+    for (dy = -r; dy <= r; dy++) {
+        for (dx = -r; dx <= r; dx++) {
+            yy = cy + dy;
+            xx = cx + dx;
+
+            if (!in_bounds(floor_ptr, yy, xx))
+                continue;
+
+            /* Skip distant grids */
+            if (distance(cy, cx, yy, xx) > r)
+                continue;
+            grid_type *g_ptr;
+            g_ptr = &floor_ptr->grid_array[yy][xx];
+
+            if (is_mirror_grid(g_ptr)) {
+                g_ptr->info |= CAVE_GLOW;
+                continue;
+            }
+
+            if ((d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
+                continue;
+
+            DIRECTION ii;
+            POSITION yyy, xxx;
+            grid_type *cc_ptr;
+
+            for (ii = 0; ii < 9; ii++) {
+                yyy = yy + ddy_ddd[ii];
+                xxx = xx + ddx_ddd[ii];
+                if (!in_bounds2(floor_ptr, yyy, xxx))
+                    continue;
+                cc_ptr = &floor_ptr->grid_array[yyy][xxx];
+                if (have_flag(f_info[get_feat_mimic(cc_ptr)].flags, FF_GLOW)) {
+                    g_ptr->info |= CAVE_GLOW;
+                    break;
+                }
+            }
+        }
+    }
+
+    /* Mega-Hack -- Forget the view and lite */
+    caster_ptr->update |= (PU_UN_VIEW | PU_UN_LITE | PU_VIEW | PU_LITE | PU_FLOW | PU_MON_LITE | PU_MONSTERS);
+    caster_ptr->redraw |= (PR_HEALTH | PR_UHEALTH | PR_MAP);
+    caster_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
+
+    if (caster_ptr->special_defense & NINJA_S_STEALTH) {
+        if (floor_ptr->grid_array[caster_ptr->y][caster_ptr->x].info & CAVE_GLOW)
+            set_superstealth(caster_ptr, FALSE);
+    }
+
+    /* Success */
+    return TRUE;
+}
diff --git a/src/spell-kind/earthquake.h b/src/spell-kind/earthquake.h
new file mode 100644 (file)
index 0000000..5182867
--- /dev/null
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "system/angband.h"
+
+bool earthquake(player_type *caster_ptr, POSITION cy, POSITION cx, POSITION r, MONSTER_IDX m_idx);
index 80d18c8..39b6d54 100644 (file)
@@ -24,9 +24,7 @@
 #include "object/object-hook.h"
 #include "object/object-mark-types.h"
 #include "object-enchant/special-object-flags.h"
-#include "player/player-damage.h"
 #include "player/player-effects.h"
-#include "player/player-move.h"
 #include "spell-kind/spells-teleport.h"
 #include "spell/process-effect.h"
 #include "spell/spells-type.h"
@@ -500,441 +498,6 @@ bool destroy_area(player_type *caster_ptr, POSITION y1, POSITION x1, POSITION r,
 
 
 /*!
- * @brief 地震処理(サブルーチン) /
- * Induce an "earthquake" of the given radius at the given location.
- * @param caster_ptrプレーヤーへの参照ポインタ
- * @param cy 中心Y座標
- * @param cx 中心X座標
- * @param r 効果半径
- * @param m_idx 地震を起こしたモンスターID(0ならばプレイヤー)
- * @return 効力があった場合TRUEを返す
- * @details
- * <pre>
- *
- * This will turn some walls into floors and some floors into walls.
- *
- * The player will take damage and "jump" into a safe grid if possible,
- * otherwise, he will "tunnel" through the rubble instantaneously.
- *
- * Monsters will take damage, and "jump" into a safe grid if possible,
- * otherwise they will be "buried" in the rubble, disappearing from
- * the level in the same way that they do when genocided.
- *
- * Note that thus the player and monsters (except eaters of walls and
- * passers through walls) will never occupy the same grid as a wall.
- * Note that as of now (2.7.8) no monster may occupy a "wall" grid, even
- * for a single turn, unless that monster can pass_walls or kill_walls.
- * This has allowed massive simplification of the "monster" code.
- * </pre>
- */
-bool earthquake(player_type *caster_ptr, POSITION cy, POSITION cx, POSITION r, MONSTER_IDX m_idx)
-{
-       /* Prevent destruction of quest levels and town */
-       floor_type *floor_ptr = caster_ptr->current_floor_ptr;
-       if ((floor_ptr->inside_quest && is_fixed_quest_idx(floor_ptr->inside_quest)) || !floor_ptr->dun_level)
-       {
-               return FALSE;
-       }
-
-       /* Paranoia -- Enforce maximum range */
-       if (r > 12) r = 12;
-
-       /* Clear the "maximal blast" area */
-       POSITION y, x;
-       bool map[32][32];
-       for (y = 0; y < 32; y++)
-       {
-               for (x = 0; x < 32; x++)
-               {
-                       map[y][x] = FALSE;
-               }
-       }
-
-       /* Check around the epicenter */
-       POSITION yy, xx, dy, dx;
-       int damage = 0;
-       bool hurt = FALSE;
-       for (dy = -r; dy <= r; dy++)
-       {
-               for (dx = -r; dx <= r; dx++)
-               {
-                       yy = cy + dy;
-                       xx = cx + dx;
-
-                       if (!in_bounds(floor_ptr, yy, xx)) continue;
-
-                       /* Skip distant grids */
-                       if (distance(cy, cx, yy, xx) > r) continue;
-                       grid_type *g_ptr;
-                       g_ptr = &floor_ptr->grid_array[yy][xx];
-
-                       /* Lose room and vault / Lose light and knowledge */
-                       g_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY | CAVE_UNSAFE);
-                       g_ptr->info &= ~(CAVE_GLOW | CAVE_MARK | CAVE_KNOWN);
-
-                       /* Skip the epicenter */
-                       if (!dx && !dy) continue;
-
-                       /* Skip most grids */
-                       if (randint0(100) < 85) continue;
-
-                       /* Damage this grid */
-                       map[16 + yy - cy][16 + xx - cx] = TRUE;
-
-                       /* Hack -- Take note of player damage */
-                       if (player_bold(caster_ptr, yy, xx)) hurt = TRUE;
-               }
-       }
-
-       /* First, affect the player (if necessary) */
-       int sn = 0;
-       POSITION sy = 0, sx = 0;
-       if (hurt && !caster_ptr->pass_wall && !caster_ptr->kill_wall)
-       {
-               /* Check around the player */
-               for (DIRECTION i = 0; i < 8; i++)
-               {
-                       y = caster_ptr->y + ddy_ddd[i];
-                       x = caster_ptr->x + ddx_ddd[i];
-
-                       /* Skip non-empty grids */
-                       if (!is_cave_empty_bold(caster_ptr, y, x)) continue;
-
-                       /* Important -- Skip "quake" grids */
-                       if (map[16 + y - cy][16 + x - cx]) continue;
-
-                       if (floor_ptr->grid_array[y][x].m_idx) continue;
-
-                       /* Count "safe" grids */
-                       sn++;
-
-                       /* Randomize choice */
-                       if (randint0(sn) > 0) continue;
-
-                       /* Save the safe location */
-                       sy = y; sx = x;
-               }
-
-               /* Random message */
-               switch (randint1(3))
-               {
-               case 1:
-               {
-                       msg_print(_("ダンジョンの壁が崩れた!", "The dungeon's ceiling collapses!"));
-                       break;
-               }
-               case 2:
-               {
-                       msg_print(_("ダンジョンの床が不自然にねじ曲がった!", "The dungeon's floor twists in an unnatural way!"));
-                       break;
-               }
-               default:
-               {
-                       msg_print(_("ダンジョンが揺れた!崩れた岩が頭に降ってきた!", "The dungeon quakes!  You are pummeled with debris!"));
-                       break;
-               }
-               }
-
-               /* Hurt the player a lot */
-               if (!sn)
-               {
-                       /* Message and damage */
-                       msg_print(_("あなたはひどい怪我を負った!", "You are severely crushed!"));
-                       damage = 200;
-               }
-
-               /* Destroy the grid, and push the player to safety */
-               else
-               {
-                       /* Calculate results */
-                       switch (randint1(3))
-                       {
-                       case 1:
-                       {
-                               msg_print(_("降り注ぐ岩をうまく避けた!", "You nimbly dodge the blast!"));
-                               damage = 0;
-                               break;
-                       }
-                       case 2:
-                       {
-                               msg_print(_("岩石があなたに直撃した!", "You are bashed by rubble!"));
-                               damage = damroll(10, 4);
-                               (void)set_stun(caster_ptr, caster_ptr->stun + randint1(50));
-                               break;
-                       }
-                       case 3:
-                       {
-                               msg_print(_("あなたは床と壁との間に挟まれてしまった!", "You are crushed between the floor and ceiling!"));
-                               damage = damroll(10, 4);
-                               (void)set_stun(caster_ptr, caster_ptr->stun + randint1(50));
-                               break;
-                       }
-                       }
-
-                       /* Move the player to the safe location */
-                       (void)move_player_effect(caster_ptr, sy, sx, MPE_DONT_PICKUP);
-               }
-
-               /* Important -- no wall on player */
-               map[16 + caster_ptr->y - cy][16 + caster_ptr->x - cx] = FALSE;
-
-               if (damage)
-               {
-                       concptr killer;
-
-                       if (m_idx)
-                       {
-                               GAME_TEXT m_name[MAX_NLEN];
-                               monster_type *m_ptr = &floor_ptr->m_list[m_idx];
-                               monster_desc(caster_ptr, m_name, m_ptr, MD_WRONGDOER_NAME);
-                               killer = format(_("%sの起こした地震", "an earthquake caused by %s"), m_name);
-                       }
-                       else
-                       {
-                               killer = _("地震", "an earthquake");
-                       }
-
-                       take_hit(caster_ptr, DAMAGE_ATTACK, damage, killer, -1);
-               }
-       }
-
-       /* Examine the quaked region */
-       for (dy = -r; dy <= r; dy++)
-       {
-               for (dx = -r; dx <= r; dx++)
-               {
-                       yy = cy + dy;
-                       xx = cx + dx;
-
-                       /* Skip unaffected grids */
-                       if (!map[16 + yy - cy][16 + xx - cx]) continue;
-
-                       grid_type *g_ptr;
-                       g_ptr = &floor_ptr->grid_array[yy][xx];
-
-                       if (g_ptr->m_idx == caster_ptr->riding) continue;
-
-                       /* Process monsters */
-                       if (!g_ptr->m_idx) continue;
-
-                       monster_type *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
-                       monster_race *r_ptr = &r_info[m_ptr->r_idx];
-
-                       /* Quest monsters */
-                       if (r_ptr->flags1 & RF1_QUESTOR)
-                       {
-                               /* No wall on quest monsters */
-                               map[16 + yy - cy][16 + xx - cx] = FALSE;
-
-                               continue;
-                       }
-
-                       /* Most monsters cannot co-exist with rock */
-                       if ((r_ptr->flags2 & RF2_KILL_WALL) || (r_ptr->flags2 & RF2_PASS_WALL)) continue;
-
-                       GAME_TEXT m_name[MAX_NLEN];
-
-                       /* Assume not safe */
-                       sn = 0;
-
-                       /* Monster can move to escape the wall */
-                       if (!(r_ptr->flags1 & RF1_NEVER_MOVE))
-                       {
-                               /* Look for safety */
-                               for (DIRECTION i = 0; i < 8; i++)
-                               {
-                                       y = yy + ddy_ddd[i];
-                                       x = xx + ddx_ddd[i];
-
-                                       /* Skip non-empty grids */
-                                       if (!is_cave_empty_bold(caster_ptr, y, x)) continue;
-
-                                       /* Hack -- no safety on glyph of warding */
-                                       if (is_glyph_grid(&floor_ptr->grid_array[y][x])) continue;
-                                       if (is_explosive_rune_grid(&floor_ptr->grid_array[y][x])) continue;
-
-                                       /* ... nor on the Pattern */
-                                       if (pattern_tile(floor_ptr, y, x)) continue;
-
-                                       /* Important -- Skip "quake" grids */
-                                       if (map[16 + y - cy][16 + x - cx]) continue;
-
-                                       if (floor_ptr->grid_array[y][x].m_idx) continue;
-                                       if (player_bold(caster_ptr, y, x)) continue;
-
-                                       /* Count "safe" grids */
-                                       sn++;
-
-                                       /* Randomize choice */
-                                       if (randint0(sn) > 0) continue;
-
-                                       /* Save the safe grid */
-                                       sy = y; sx = x;
-                               }
-                       }
-
-                       monster_desc(caster_ptr, m_name, m_ptr, 0);
-
-                       /* Scream in pain */
-                       if (!ignore_unview || is_seen(m_ptr)) msg_format(_("%^sは苦痛で泣きわめいた!", "%^s wails out in pain!"), m_name);
-
-                       /* Take damage from the quake */
-                       damage = (sn ? damroll(4, 8) : (m_ptr->hp + 1));
-
-                       /* Monster is certainly awake */
-                       (void)set_monster_csleep(caster_ptr, g_ptr->m_idx, 0);
-
-                       /* Apply damage directly */
-                       m_ptr->hp -= damage;
-
-                       /* Delete (not kill) "dead" monsters */
-                       if (m_ptr->hp < 0)
-                       {
-                               if (!ignore_unview || is_seen(m_ptr))
-                                       msg_format(_("%^sは岩石に埋もれてしまった!", "%^s is embedded in the rock!"), m_name);
-
-                               if (g_ptr->m_idx)
-                               {
-                                       if (record_named_pet && is_pet(&floor_ptr->m_list[g_ptr->m_idx]) && floor_ptr->m_list[g_ptr->m_idx].nickname)
-                                       {
-                                               char m2_name[MAX_NLEN];
-
-                                               monster_desc(caster_ptr, m2_name, m_ptr, MD_INDEF_VISIBLE);
-                                               exe_write_diary(caster_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_EARTHQUAKE, m2_name);
-                                       }
-                               }
-
-                               delete_monster(caster_ptr, yy, xx);
-
-                               sn = 0;
-                       }
-
-                       /* Hack -- Escape from the rock */
-                       if (sn == 0) continue;
-
-                       IDX m_idx_aux = floor_ptr->grid_array[yy][xx].m_idx;
-
-                       /* Update the old location */
-                       floor_ptr->grid_array[yy][xx].m_idx = 0;
-
-                       /* Update the new location */
-                       floor_ptr->grid_array[sy][sx].m_idx = m_idx_aux;
-
-                       /* Move the monster */
-                       m_ptr->fy = sy;
-                       m_ptr->fx = sx;
-
-                       update_monster(caster_ptr, m_idx, TRUE);
-                       lite_spot(caster_ptr, yy, xx);
-                       lite_spot(caster_ptr, sy, sx);
-               }
-       }
-
-       /* Lose monster light */
-       clear_mon_lite(floor_ptr);
-
-       /* Examine the quaked region */
-       for (dy = -r; dy <= r; dy++)
-       {
-               for (dx = -r; dx <= r; dx++)
-               {
-                       yy = cy + dy;
-                       xx = cx + dx;
-
-                       /* Skip unaffected grids */
-                       if (!map[16 + yy - cy][16 + xx - cx]) continue;
-
-                       /* Destroy location (if valid) */
-                       if (!cave_valid_bold(floor_ptr, yy, xx)) continue;
-
-                       delete_all_items_from_floor(caster_ptr, yy, xx);
-
-                       /* Wall (or floor) type */
-                       int t = cave_have_flag_bold(floor_ptr, yy, xx, FF_PROJECT) ? randint0(100) : 200;
-
-                       /* Create granite wall */
-                       if (t < 20)
-                       {
-                               cave_set_feat(caster_ptr, yy, xx, feat_granite);
-                               continue;
-                       }
-
-                       /* Create quartz vein */
-                       if (t < 70)
-                       {
-                               cave_set_feat(caster_ptr, yy, xx, feat_quartz_vein);
-                               continue;
-                       }
-
-                       /* Create magma vein */
-                       if (t < 100)
-                       {
-                               cave_set_feat(caster_ptr, yy, xx, feat_magma_vein);
-                               continue;
-                       }
-
-                       /* Create floor */
-                       cave_set_feat(caster_ptr, yy, xx, feat_ground_type[randint0(100)]);
-               }
-       }
-
-       /* Process "re-glowing" */
-       for (dy = -r; dy <= r; dy++)
-       {
-               for (dx = -r; dx <= r; dx++)
-               {
-                       yy = cy + dy;
-                       xx = cx + dx;
-
-                       if (!in_bounds(floor_ptr, yy, xx)) continue;
-
-                       /* Skip distant grids */
-                       if (distance(cy, cx, yy, xx) > r) continue;
-                       grid_type *g_ptr;
-                       g_ptr = &floor_ptr->grid_array[yy][xx];
-
-                       if (is_mirror_grid(g_ptr))
-                       {
-                               g_ptr->info |= CAVE_GLOW;
-                               continue;
-                       }
-                       
-                       if ((d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)) continue;
-                       
-                       DIRECTION ii;
-                       POSITION yyy, xxx;
-                       grid_type *cc_ptr;
-
-                       for (ii = 0; ii < 9; ii++)
-                       {
-                               yyy = yy + ddy_ddd[ii];
-                               xxx = xx + ddx_ddd[ii];
-                               if (!in_bounds2(floor_ptr, yyy, xxx)) continue;
-                               cc_ptr = &floor_ptr->grid_array[yyy][xxx];
-                               if (have_flag(f_info[get_feat_mimic(cc_ptr)].flags, FF_GLOW))
-                               {
-                                       g_ptr->info |= CAVE_GLOW;
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       /* Mega-Hack -- Forget the view and lite */
-       caster_ptr->update |= (PU_UN_VIEW | PU_UN_LITE | PU_VIEW | PU_LITE | PU_FLOW | PU_MON_LITE | PU_MONSTERS);
-       caster_ptr->redraw |= (PR_HEALTH | PR_UHEALTH | PR_MAP);
-       caster_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
-
-       if (caster_ptr->special_defense & NINJA_S_STEALTH)
-       {
-               if (floor_ptr->grid_array[caster_ptr->y][caster_ptr->x].info & CAVE_GLOW) set_superstealth(caster_ptr, FALSE);
-       }
-
-       /* Success */
-       return TRUE;
-}
-
-/*!
  * @brief カオス魔法「流星群」の処理としてプレイヤーを中心に隕石落下処理を10+1d10回繰り返す。
  * / Drop 10+1d10 meteor ball at random places near the player
  * @param caster_ptr プレーヤーへの参照ポインタ
index 718fa96..95b72ce 100644 (file)
@@ -6,5 +6,4 @@ void wiz_lite(player_type *caster_ptr, bool ninja);
 void wiz_dark(player_type *caster_ptr);
 void map_area(player_type *caster_ptr, POSITION range);
 bool destroy_area(player_type *caster_ptr, POSITION y1, POSITION x1, POSITION r, bool in_generate);
-bool earthquake(player_type *caster_ptr, POSITION cy, POSITION cx, POSITION r, MONSTER_IDX m_idx);
 void cast_meteor(player_type *caster_ptr, HIT_POINT dam, POSITION rad);
index e6580a3..b5c4b97 100644 (file)
@@ -3,7 +3,7 @@
 #include "floor/floor.h"
 #include "grid/feature.h"
 #include "spell/process-effect.h"
-#include "spell-kind/spells-floor.h"
+#include "spell-kind/earthquake.h"
 #include "spell/spells-type.h"
 
 /*!
index 885636a..f2475a1 100644 (file)
@@ -14,6 +14,7 @@
 #include "player/player-damage.h"
 #include "player/player-effects.h"
 #include "spell/spells-type.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-floor.h"
 #include "spell-kind/spells-genocide.h"
 #include "spell-kind/spells-launcher.h"
index 3629527..4ec8bfc 100644 (file)
@@ -4,6 +4,7 @@
 #include "mutation/mutation.h"
 #include "player/avatar.h"
 #include "player/player-effects.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-random.h"
 #include "spell-kind/spells-charm.h"
 #include "spell-kind/spells-floor.h"
index 791902e..1daf481 100644 (file)
@@ -9,6 +9,7 @@
 #include "player/avatar.h"
 #include "player/player-effects.h"
 #include "spell/spells-diceroll.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-floor.h"
 #include "spell-kind/spells-genocide.h"
 #include "spell-kind/spells-launcher.h"
index 82e2827..42948bd 100644 (file)
 #include "player/player-skill.h"
 #include "player/player-status.h"
 #include "spell/process-effect.h"
-#include "spell/spells-execution.h"
+#include "spell-kind/earthquake.h"
 #include "spell-kind/spells-floor.h"
 #include "spell-kind/spells-launcher.h"
 #include "spell-kind/spells-sight.h"
-#include "spell/spells-summon.h"
 #include "spell-kind/spells-teleport.h"
+#include "spell/spells-execution.h"
+#include "spell/spells-summon.h"
 #include "spell/technic-info-table.h"
 #include "term/gameterm.h"
 #include "util/util.h"