OSDN Git Service

通常のセーブ/ロード時以外でc_ptr->mimicに0以外の値を代入する際に, 最
[hengband/hengband.git] / src / spells3.c
index 6ccdd6a..87fd6f4 100644 (file)
@@ -140,9 +140,9 @@ bool teleport_away(int m_idx, int dis, bool dec_valour)
 
 
 /*
- * Teleport monster next to the player
+ * Teleport monster next to a grid near the given location
  */
-void teleport_to_player(int m_idx, int power)
+void teleport_monster_to(int m_idx, int ty, int tx, int power)
 {
        int ny, nx, oy, ox, d, i, min;
        int attempts = 500;
@@ -177,12 +177,14 @@ void teleport_to_player(int m_idx, int power)
                /* Try several locations */
                for (i = 0; i < 500; i++)
                {
+                       cave_type    *c_ptr;
+
                        /* Pick a (possibly illegal) location */
                        while (1)
                        {
-                               ny = rand_spread(py, dis);
-                               nx = rand_spread(px, dis);
-                               d = distance(py, px, ny, nx);
+                               ny = rand_spread(ty, dis);
+                               nx = rand_spread(tx, dis);
+                               d = distance(ty, tx, ny, nx);
                                if ((d >= min) && (d <= dis)) break;
                        }
 
@@ -192,16 +194,18 @@ void teleport_to_player(int m_idx, int power)
                        /* Require "empty" floor space */
                        if (!cave_empty_bold(ny, nx)) continue;
 
+                       c_ptr = &cave[ny][nx];
+
                        /* Hack -- no teleport onto glyph of warding */
-                       if (is_glyph_grid(&cave[ny][nx])) continue;
-                       if (is_explosive_rune_grid(&cave[ny][nx])) continue;
+                       if (is_glyph_grid(c_ptr)) continue;
+                       if (is_explosive_rune_grid(c_ptr)) continue;
 
                        /* ...nor onto the Pattern */
-                       if ((cave[ny][nx].feat >= FEAT_PATTERN_START) &&
-                           (cave[ny][nx].feat <= FEAT_PATTERN_XTRA2)) continue;
+                       if ((c_ptr->feat >= FEAT_PATTERN_START) &&
+                           (c_ptr->feat <= FEAT_PATTERN_XTRA2)) continue;
 
                        /* No teleporting into vaults and such */
-                       /* if (cave[ny][nx].info & (CAVE_ICKY)) continue; */
+                       /* if (c_ptr->info & (CAVE_ICKY)) continue; */
 
                        /* This grid looks good */
                        look = FALSE;
@@ -386,7 +390,7 @@ msg_print("
                                if ((r_ptr->flags6 & RF6_TPORT) &&
                                    !(r_ptr->flagsr & RFR_RES_TELE))
                                {
-                                       if (!m_ptr->csleep) teleport_to_player(tmp_m_idx, r_ptr->level);
+                                       if (!m_ptr->csleep) teleport_monster_to(tmp_m_idx, py, px, r_ptr->level);
                                }
                        }
                }
@@ -512,32 +516,51 @@ msg_print("
 
 /*
  * Teleport the player one level up or down (random when legal)
+ * Note: If m_idx <= 0, target is player.
  */
-void teleport_player_level(void)
+void teleport_level(int m_idx)
 {
-       bool go_up;
+       bool         go_up;
+       char         m_name[160];
+       bool         see_m = TRUE;
 
-       /* No effect in arena or quest */
-       if (p_ptr->inside_arena || (p_ptr->inside_quest && !random_quest_number(dun_level)) ||
-           ((quest_number(dun_level) || (dun_level >= d_info[dungeon_type].maxdepth)) && (dun_level > 1) && ironman_downward))
+       if (m_idx <= 0) /* To player */
        {
 #ifdef JP
-msg_print("¸ú²Ì¤¬¤Ê¤«¤Ã¤¿¡£");
+               strcpy(m_name, "¤¢¤Ê¤¿");
 #else
-               msg_print("There is no effect.");
+               strcpy(m_name, "you");
+#endif
+       }
+       else /* To monster */
+       {
+               monster_type *m_ptr = &m_list[m_idx];
+
+               /* Get the monster name (or "it") */
+               monster_desc(m_name, m_ptr, 0);
+
+               see_m = m_ptr->ml;
+       }
+
+       /* No effect in some case */
+       if (TELE_LEVEL_IS_INEFF(m_idx))
+       {
+#ifdef JP
+               if (see_m) msg_print("¸ú²Ì¤¬¤Ê¤«¤Ã¤¿¡£");
+#else
+               if (see_m) msg_print("There is no effect.");
 #endif
 
                return;
        }
 
-       if (p_ptr->anti_tele)
+       if ((m_idx <= 0) && p_ptr->anti_tele) /* To player */
        {
 #ifdef JP
-msg_print("ÉԻ׵ĤÊÎϤ¬¥Æ¥ì¥Ý¡¼¥È¤òËɤ¤¤À¡ª");
+               msg_print("ÉԻ׵ĤÊÎϤ¬¥Æ¥ì¥Ý¡¼¥È¤òËɤ¤¤À¡ª");
 #else
                msg_print("A mysterious force prevents you from teleporting!");
 #endif
-
                return;
        }
 
@@ -545,104 +568,127 @@ msg_print("
        if (randint0(100) < 50) go_up = TRUE;
        else go_up = FALSE;
 
-       if (p_ptr->wizard)
+       if ((m_idx <= 0) && p_ptr->wizard)
        {
                if (get_check("Force to go up? ")) go_up = TRUE;
                else if (get_check("Force to go down? ")) go_up = FALSE;
        }
 
        /* Down only */ 
-       if (ironman_downward || (dun_level <= d_info[dungeon_type].mindepth))
+       if ((ironman_downward && (m_idx <= 0)) || (dun_level <= d_info[dungeon_type].mindepth))
        {
 #ifdef JP
-msg_print("¤¢¤Ê¤¿¤Ï¾²¤òÆͤ­ÇˤäÆÄÀ¤ó¤Ç¤¤¤¯¡£");
+               if (see_m) msg_format("%^s¤Ï¾²¤òÆͤ­ÇˤäÆÄÀ¤ó¤Ç¤¤¤¯¡£", m_name);
 #else
-               msg_print("You sink through the floor.");
+               if (see_m) msg_format("%^s sink%s through the floor.", m_name, (m_idx <= 0) ? "" : "s");
 #endif
-               if (!dun_level)
+               if (m_idx <= 0) /* To player */
                {
-                       dungeon_type = p_ptr->recall_dungeon;
-                       p_ptr->oldpy = py;
-                       p_ptr->oldpx = px;
-               }
+                       if (!dun_level)
+                       {
+                               dungeon_type = p_ptr->recall_dungeon;
+                               p_ptr->oldpy = py;
+                               p_ptr->oldpx = px;
+                       }
 
-               if (record_stair) do_cmd_write_nikki(NIKKI_TELE_LEV, 1, NULL);
+                       if (record_stair) do_cmd_write_nikki(NIKKI_TELE_LEV, 1, NULL);
 
-               if (autosave_l) do_cmd_save_game(TRUE);
+                       if (autosave_l) do_cmd_save_game(TRUE);
 
-               if (!dun_level)
-               {
-                       dun_level = d_info[dungeon_type].mindepth;
-                       prepare_change_floor_mode(CFM_RAND_PLACE | CFM_CLEAR_ALL);
-               }
-               else
-               {
-                       prepare_change_floor_mode(CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
-               }
+                       if (!dun_level)
+                       {
+                               dun_level = d_info[dungeon_type].mindepth;
+                               prepare_change_floor_mode(CFM_RAND_PLACE | CFM_CLEAR_ALL);
+                       }
+                       else
+                       {
+                               prepare_change_floor_mode(CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
+                       }
 
-               /* Leaving */
-               p_ptr->leaving = TRUE;
+                       /* Leaving */
+                       p_ptr->leaving = TRUE;
+               }
        }
 
        /* Up only */
        else if (quest_number(dun_level) || (dun_level >= d_info[dungeon_type].maxdepth))
        {
 #ifdef JP
-msg_print("¤¢¤Ê¤¿¤ÏÅ·°æ¤òÆͤ­ÇˤäÆÃè¤ØÉ⤤¤Æ¤¤¤¯¡£");
+               if (see_m) msg_format("%^s¤ÏÅ·°æ¤òÆͤ­ÇˤäÆÃè¤ØÉ⤤¤Æ¤¤¤¯¡£", m_name);
 #else
-               msg_print("You rise up through the ceiling.");
+               if (see_m) msg_format("%^s rise%s up through the ceiling.", m_name, (m_idx <= 0) ? "" : "s");
 #endif
 
 
-               if (record_stair) do_cmd_write_nikki(NIKKI_TELE_LEV, -1, NULL);
+               if (m_idx <= 0) /* To player */
+               {
+                       if (record_stair) do_cmd_write_nikki(NIKKI_TELE_LEV, -1, NULL);
 
-               if (autosave_l) do_cmd_save_game(TRUE);
+                       if (autosave_l) do_cmd_save_game(TRUE);
 
-               prepare_change_floor_mode(CFM_UP | CFM_RAND_PLACE | CFM_RAND_CONNECT);
+                       prepare_change_floor_mode(CFM_UP | CFM_RAND_PLACE | CFM_RAND_CONNECT);
 
-               leave_quest_check();
+                       leave_quest_check();
 
-               /* Leaving */
-               p_ptr->inside_quest = 0;
-               p_ptr->leaving = TRUE;
+                       /* Leaving */
+                       p_ptr->inside_quest = 0;
+                       p_ptr->leaving = TRUE;
+               }
        }
        else if (go_up)
        {
 #ifdef JP
-msg_print("¤¢¤Ê¤¿¤ÏÅ·°æ¤òÆͤ­ÇˤäÆÃè¤ØÉ⤤¤Æ¤¤¤¯¡£");
+               if (see_m) msg_format("%^s¤ÏÅ·°æ¤òÆͤ­ÇˤäÆÃè¤ØÉ⤤¤Æ¤¤¤¯¡£", m_name);
 #else
-               msg_print("You rise up through the ceiling.");
+               if (see_m) msg_format("%^s rise%s up through the ceiling.", m_name, (m_idx <= 0) ? "" : "s");
 #endif
 
 
-               if (record_stair) do_cmd_write_nikki(NIKKI_TELE_LEV, -1, NULL);
+               if (m_idx <= 0) /* To player */
+               {
+                       if (record_stair) do_cmd_write_nikki(NIKKI_TELE_LEV, -1, NULL);
 
-               if (autosave_l) do_cmd_save_game(TRUE);
+                       if (autosave_l) do_cmd_save_game(TRUE);
 
-               prepare_change_floor_mode(CFM_UP | CFM_RAND_PLACE | CFM_RAND_CONNECT);
+                       prepare_change_floor_mode(CFM_UP | CFM_RAND_PLACE | CFM_RAND_CONNECT);
 
-               /* Leaving */
-               p_ptr->leaving = TRUE;
+                       /* Leaving */
+                       p_ptr->leaving = TRUE;
+               }
        }
        else
        {
 #ifdef JP
-msg_print("¤¢¤Ê¤¿¤Ï¾²¤òÆͤ­ÇˤäÆÄÀ¤ó¤Ç¤¤¤¯¡£");
+               if (see_m) msg_format("%^s¤Ï¾²¤òÆͤ­ÇˤäÆÄÀ¤ó¤Ç¤¤¤¯¡£", m_name);
 #else
-               msg_print("You sink through the floor.");
+               if (see_m) msg_format("%^s sink%s through the floor.", m_name, (m_idx <= 0) ? "" : "s");
 #endif
 
-               /* Never reach this code on the surface */
-               /* if (!dun_level) dungeon_type = p_ptr->recall_dungeon; */
+               if (m_idx <= 0) /* To player */
+               {
+                       /* Never reach this code on the surface */
+                       /* if (!dun_level) dungeon_type = p_ptr->recall_dungeon; */
+
+                       if (record_stair) do_cmd_write_nikki(NIKKI_TELE_LEV, 1, NULL);
+
+                       if (autosave_l) do_cmd_save_game(TRUE);
+
+                       prepare_change_floor_mode(CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
 
-               if (record_stair) do_cmd_write_nikki(NIKKI_TELE_LEV, 1, NULL);
+                       /* Leaving */
+                       p_ptr->leaving = TRUE;
+               }
+       }
 
-               if (autosave_l) do_cmd_save_game(TRUE);
+       /* Monster level teleportation is simple deleting now */
+       if (m_idx > 0)
+       {
+               monster_type *m_ptr = &m_list[m_idx];
 
-               prepare_change_floor_mode(CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
+               /* Check for quest completion */
+               check_quest_completion(m_ptr);
 
-               /* Leaving */
-               p_ptr->leaving = TRUE;
+               delete_monster_idx(m_idx);
        }
 
        /* Sound */
@@ -1047,7 +1093,7 @@ msg_print("
                        }
 
                        /* Teleport Level */
-                       teleport_player_level();
+                       teleport_level(0);
                        break;
                }
 
@@ -1476,6 +1522,8 @@ static bool vanish_dungeon(void)
                                /* Reset sleep counter */
                                m_ptr->csleep = 0;
 
+                               if (r_info[m_ptr->r_idx].flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE);
+
                                /* Notice the "waking up" */
                                if (m_ptr->ml)
                                {
@@ -1513,7 +1561,7 @@ static bool vanish_dungeon(void)
                c_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY);
 
                /* Set boundary mimic if needed */
-               if (c_ptr->mimic && vanishable_feat(c_ptr->mimic)) c_ptr->mimic = floor_type[randint0(100)];
+               if (c_ptr->mimic && vanishable_feat(c_ptr->mimic)) c_ptr->mimic = f_info[floor_type[randint0(100)]].mimic;
 
                c_ptr = &cave[cur_hgt - 1][x];
 
@@ -1521,7 +1569,7 @@ static bool vanish_dungeon(void)
                c_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY);
 
                /* Set boundary mimic if needed */
-               if (c_ptr->mimic && vanishable_feat(c_ptr->mimic)) c_ptr->mimic = floor_type[randint0(100)];
+               if (c_ptr->mimic && vanishable_feat(c_ptr->mimic)) c_ptr->mimic = f_info[floor_type[randint0(100)]].mimic;
        }
 
        /* Special boundary walls -- Left and right */
@@ -1533,7 +1581,7 @@ static bool vanish_dungeon(void)
                c_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY);
 
                /* Set boundary mimic if needed */
-               if (c_ptr->mimic && vanishable_feat(c_ptr->mimic)) c_ptr->mimic = floor_type[randint0(100)];
+               if (c_ptr->mimic && vanishable_feat(c_ptr->mimic)) c_ptr->mimic = f_info[floor_type[randint0(100)]].mimic;
 
                c_ptr = &cave[y][cur_wid - 1];
 
@@ -1541,7 +1589,7 @@ static bool vanish_dungeon(void)
                c_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY);
 
                /* Set boundary mimic if needed */
-               if (c_ptr->mimic && vanishable_feat(c_ptr->mimic)) c_ptr->mimic = floor_type[randint0(100)];
+               if (c_ptr->mimic && vanishable_feat(c_ptr->mimic)) c_ptr->mimic = f_info[floor_type[randint0(100)]].mimic;
        }
 
        /* Mega-Hack -- Forget the view and lite */
@@ -1845,7 +1893,7 @@ msg_print("
 
        /* Create a glyph */
        cave[py][px].info |= CAVE_OBJECT;
-       cave[py][px].mimic = FEAT_GLYPH;
+       cave[py][px].mimic = f_info[FEAT_GLYPH].mimic;
 
        /* Notice */
        note_spot(py, px);
@@ -1872,7 +1920,7 @@ msg_print("
 
        /* Create a mirror */
        cave[py][px].info |= CAVE_OBJECT;
-       cave[py][px].mimic = FEAT_MIRROR;
+       cave[py][px].mimic = f_info[FEAT_MIRROR].mimic;
 
        /* Turn on the light */
        cave[py][px].info |= CAVE_GLOW;
@@ -1906,7 +1954,7 @@ msg_print("
 
        /* Create a glyph */
        cave[py][px].info |= CAVE_OBJECT;
-       cave[py][px].mimic = FEAT_MINOR_GLYPH;
+       cave[py][px].mimic = f_info[FEAT_MINOR_GLYPH].mimic;
 
        /* Notice */
        note_spot(py, px);
@@ -6090,6 +6138,9 @@ msg_format("
                p_ptr->csp = p_ptr->msp;
        }
 
+       /* Redraw mana and hp */
+       p_ptr->redraw |= (PR_MANA);
+
        p_ptr->notice |= (PN_COMBINE | PN_REORDER);
        p_ptr->window |= (PW_INVEN);