msg_format("%^s disappears!", m_name);
#endif
- teleport_away(c_ptr->m_idx, 50, FALSE);
+ teleport_away(c_ptr->m_idx, 50, FALSE, TRUE);
num = num_blow + 1; /* Can't hit it anymore! */
*mdeath = TRUE;
}
for (i = 0; i < max_pet; i++)
{
pet_ctr = who[i];
- teleport_monster_to(pet_ctr, py, px, 100);
+ teleport_monster_to(pet_ctr, py, px, 100, TRUE);
}
/* Free the "who" array */
extern void remove_all_mirrors(bool explode);
/* spells3.c */
-extern bool teleport_away(int m_idx, int dis, bool dec_valour);
-extern void teleport_monster_to(int m_idx, int ty, int tx, int power);
-extern bool cave_teleportable_bold(int y, int x, bool passive);
+extern bool teleport_away(int m_idx, int dis, bool dec_valour, bool passive);
+extern void teleport_monster_to(int m_idx, int ty, int tx, int power, bool passive);
+extern bool cave_player_teleportable_bold(int y, int x, bool passive);
extern void teleport_player(int dis, bool passive);
extern void teleport_player_to(int ny, int nx, bool no_tele, bool passive);
extern void teleport_level(int m_idx);
case 27:
{
if (!tgt_pt(&x, &y)) return FALSE;
- if (!cave_teleportable_bold(y, x, FALSE) ||
+ if (!cave_player_teleportable_bold(y, x, FALSE) ||
(distance(y, x, py, px) > MAX_SIGHT / 2) ||
!projectable(py, px, y, x))
{
msg_format("You command %s to return.", m_name);
#endif
- teleport_monster_to(cave[target_row][target_col].m_idx, py, px, 100);
+ teleport_monster_to(cave[target_row][target_col].m_idx, py, px, 100, TRUE);
break;
}
case MS_TELE_AWAY:
msg_print("The thief flees laughing!");
#endif
- teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE);
+ teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE, FALSE);
}
case RBE_EAT_GOLD:
{
pt = damage = 0;
- if (one_in_(2)) blinked = TRUE;
+ if ((p_ptr->riding != m_idx) && one_in_(2)) blinked = TRUE;
break;
}
mon_fight = TRUE;
}
- teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE);
+ teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE, FALSE);
}
return TRUE;
msg_format("%^s blinks away.", m_name);
#endif
- teleport_away(m_idx, 10, FALSE);
+ teleport_away(m_idx, 10, FALSE, FALSE);
p_ptr->update |= (PU_MONSTERS);
break;
}
msg_format("%^s teleports away.", m_name);
#endif
- teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE);
+ teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE, FALSE);
if (los(py, px, oldfy, oldfx) && !world_monster)
{
#else
msg_format("%^s suddenly go out of your sight!", m_name);
#endif
- teleport_away(m_idx, 10, FALSE);
+ teleport_away(m_idx, 10, FALSE, FALSE);
p_ptr->update |= (PU_MONSTERS);
}
else
}
- teleport_away(m_idx, 10, FALSE);
+ teleport_away(m_idx, 10, FALSE, FALSE);
break;
#endif
}
- teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE);
+ teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE, FALSE);
if (los(py, px, m_ptr->fy, m_ptr->fx) && !world_monster && see_m)
{
msg_format("%^s suddenly go out of your sight!", m_name);
#endif
}
- teleport_away(m_idx, 10, FALSE);
+ teleport_away(m_idx, 10, FALSE, FALSE);
p_ptr->update |= (PU_MONSTERS);
}
else
dam = damroll(4, 8);
if (t_idx == p_ptr->riding) teleport_player_to(m_ptr->fy, m_ptr->fx, FALSE, TRUE);
- else teleport_monster_to(t_idx, m_ptr->fy, m_ptr->fx, 100);
+ else teleport_monster_to(t_idx, m_ptr->fy, m_ptr->fx, 100, TRUE);
sound(SOUND_FALL);
if (!resists_tele)
{
if (t_idx == p_ptr->riding) teleport_player_to(m_ptr->fy, m_ptr->fx, TRUE, TRUE);
- else teleport_monster_to(t_idx, m_ptr->fy, m_ptr->fx, 100);
+ else teleport_monster_to(t_idx, m_ptr->fy, m_ptr->fx, 100, TRUE);
}
wake_up = TRUE;
if (!resists_tele)
{
if (t_idx == p_ptr->riding) teleport_player(MAX_SIGHT * 2 + 5, TRUE);
- else teleport_away(t_idx, MAX_SIGHT * 2 + 5, FALSE);
+ else teleport_away(t_idx, MAX_SIGHT * 2 + 5, FALSE, TRUE);
}
wake_up = TRUE;
msg_format("You command %s to return.", m_name);
#endif
- teleport_monster_to(cave[target_row][target_col].m_idx, py, px, 100);
+ teleport_monster_to(cave[target_row][target_col].m_idx, py, px, 100, TRUE);
break;
}
case MS_TELE_AWAY:
chg_virtue(V_VALOUR, -1);
/* Teleport */
- teleport_away(c_ptr->m_idx, do_dist, (bool)(!who));
+ teleport_away(c_ptr->m_idx, do_dist, (bool)(!who), TRUE);
/* Hack -- get new location */
y = m_ptr->fy;
msg_print("Space warps about you!");
#endif
- if (m_ptr->r_idx) teleport_away(c_ptr->m_idx, damroll(10, 10), FALSE);
+ if (m_ptr->r_idx) teleport_away(c_ptr->m_idx, damroll(10, 10), FALSE, TRUE);
if (one_in_(13)) count += activate_hi_summon(ty, tx, TRUE);
if (!one_in_(6)) break;
}
m_ptr->hp = m_ptr->maxhp;
/* Try to teleport away quest monsters */
- if (!teleport_away(c_ptr->m_idx, (r * 2) + 1, TRUE)) continue;
+ if (!teleport_away(c_ptr->m_idx, (r * 2) + 1, TRUE, FALSE)) continue;
}
else
{
#define HURT_CHANCE 16
+static bool cave_monster_teleportable_bold(int m_idx, int y, int x, bool passive)
+{
+ monster_type *m_ptr = &m_list[m_idx];
+ cave_type *c_ptr = &cave[y][x];
+ feature_type *f_ptr = &f_info[c_ptr->feat];
+
+ /* Require "teleportable" space */
+ if (!have_flag(f_ptr->flags, FF_TELEPORTABLE)) return FALSE;
+
+ if (c_ptr->m_idx && (c_ptr->m_idx != m_idx)) return FALSE;
+ if (player_bold(y, x)) return FALSE;
+
+ /* Hack -- no teleport onto glyph of warding */
+ if (is_glyph_grid(c_ptr)) return FALSE;
+ if (is_explosive_rune_grid(c_ptr)) return FALSE;
+
+ if (!passive)
+ {
+ if (!monster_can_cross_terrain(c_ptr->feat, &r_info[m_ptr->r_idx], 0)) return FALSE;
+ }
+
+ return TRUE;
+}
+
+
/*
* Teleport a monster, normally up to "dis" grids away.
*
*
* But allow variation to prevent infinite loops.
*/
-bool teleport_away(int m_idx, int dis, bool dec_valour)
+bool teleport_away(int m_idx, int dis, bool dec_valour, bool passive)
{
int oy, ox, d, i, min;
int tries = 0;
monster_type *m_ptr = &m_list[m_idx];
-
/* Paranoia */
if (!m_ptr->r_idx) return (FALSE);
if (dec_valour &&
(((p_ptr->chp * 10) / p_ptr->mhp) > 5) &&
(4+randint1(5) < ((p_ptr->chp * 10) / p_ptr->mhp)))
- {
+ {
chg_virtue(V_VALOUR, -1);
}
/* Ignore illegal locations */
if (!in_bounds(ny, nx)) continue;
- /* Require "empty" floor space */
- if (!cave_empty_bold(ny, nx)) continue;
-
- /* Hack -- no teleport onto glyph of warding */
- if (is_glyph_grid(&cave[ny][nx])) continue;
- if (is_explosive_rune_grid(&cave[ny][nx])) continue;
-
- /* ...nor onto the Pattern */
- if (pattern_tile(ny, nx)) continue;
+ if (!cave_monster_teleportable_bold(m_idx, ny, nx, passive)) continue;
/* No teleporting into vaults and such */
if (!(p_ptr->inside_quest || p_ptr->inside_arena))
/*
* Teleport monster next to a grid near the given location
*/
-void teleport_monster_to(int m_idx, int ty, int tx, int power)
+void teleport_monster_to(int m_idx, int ty, int tx, int power, bool passive)
{
int ny, nx, oy, ox, d, i, min;
int attempts = 500;
bool look = TRUE;
monster_type *m_ptr = &m_list[m_idx];
-
/* Paranoia */
if (!m_ptr->r_idx) return;
/* Try several locations */
for (i = 0; i < 500; i++)
{
- cave_type *c_ptr;
-
/* Pick a (possibly illegal) location */
while (1)
{
/* Ignore illegal locations */
if (!in_bounds(ny, nx)) continue;
- /* 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(c_ptr)) continue;
- if (is_explosive_rune_grid(c_ptr)) continue;
-
- /* ...nor onto the Pattern */
- if (pattern_tile(ny, nx)) continue;
+ if (!cave_monster_teleportable_bold(m_idx, ny, nx, passive)) continue;
/* No teleporting into vaults and such */
- /* if (c_ptr->info & (CAVE_ICKY)) continue; */
+ /* if (cave[ny][nx].info & (CAVE_ICKY)) continue; */
/* This grid looks good */
look = FALSE;
}
-bool cave_teleportable_bold(int y, int x, bool passive)
+bool cave_player_teleportable_bold(int y, int x, bool passive)
{
cave_type *c_ptr = &cave[y][x];
feature_type *f_ptr = &f_info[c_ptr->feat];
/* Ignore illegal locations */
if (!in_bounds(y, x)) continue;
- if (!cave_teleportable_bold(y, x, passive)) continue;
+ if (!cave_player_teleportable_bold(y, x, passive)) continue;
/* This grid looks good */
look = FALSE;
if ((r_ptr->flags6 & RF6_TPORT) &&
!(r_ptr->flagsr & RFR_RES_TELE))
{
- if (!m_ptr->csleep) teleport_monster_to(tmp_m_idx, y, x, r_ptr->level);
+ if (!m_ptr->csleep) teleport_monster_to(tmp_m_idx, y, x, r_ptr->level, FALSE);
}
}
}
if (p_ptr->wizard && !passive) break;
/* Accept teleportable floor grids */
- if (cave_teleportable_bold(y, x, passive)) break;
+ if (cave_player_teleportable_bold(y, x, passive)) break;
/* Occasionally advance the distance */
if (++ctr > (4 * dis * dis + 4 * dis + 1))
p_ptr->energy_need += (s16b)((s32b)(60 - plev) * ENERGY_NEED() / 100L);
- if (!cave_teleportable_bold(y, x, FALSE) ||
+ if (!cave_player_teleportable_bold(y, x, FALSE) ||
(distance(y, x, py, px) > plev / 2 + 10) ||
(!randint0(plev / 10 + 10)))
{