{
if ((n > 0) && cave_stop_disintegration(y, x)) break;
}
+ else if (flg & (PROJECT_LOS))
+ {
+ if ((n > 0) && !cave_los_bold(y, x)) break;
+ }
else if (!(flg & (PROJECT_PATH)))
{
/* Always stop at non-initial wall grids */
{
if ((n > 0) && cave_stop_disintegration(y, x)) break;
}
+ else if (flg & (PROJECT_LOS))
+ {
+ if ((n > 0) && !cave_los_bold(y, x)) break;
+ }
else if (!(flg & (PROJECT_PATH)))
{
/* Always stop at non-initial wall grids */
{
if ((n > 0) && cave_stop_disintegration(y, x)) break;
}
+ else if (flg & (PROJECT_LOS))
+ {
+ if ((n > 0) && !cave_los_bold(y, x)) break;
+ }
else if (!(flg & (PROJECT_PATH)))
{
/* Always stop at non-initial wall grids */
case GF_FORCE:
case GF_HOLY_FIRE:
case GF_HELL_FIRE:
- case GF_DISINTEGRATE:
case GF_PSI:
case GF_PSI_DRAIN:
case GF_TELEKINESIS:
if (have_flag(f_ptr->flags, FF_SPIKE))
{
s16b old_mimic = c_ptr->mimic;
+ feature_type *mimic_f_ptr = &f_info[get_feat_mimic(c_ptr)];
cave_alter_feat(y, x, FF_SPIKE);
lite_spot(y, x);
/* Check line of sight */
- if (known && !c_ptr->mimic)
+ if (known && have_flag(mimic_f_ptr->flags, FF_OPEN))
{
/* Message */
#ifdef JP
- msg_format("%s¤Ë²¿¤«¤¬¤Ä¤Ã¤«¤¨¤Æ³«¤«¤Ê¤¯¤Ê¤Ã¤¿¡£", f_name + f_ptr->name);
+ msg_format("%s¤Ë²¿¤«¤¬¤Ä¤Ã¤«¤¨¤Æ³«¤«¤Ê¤¯¤Ê¤Ã¤¿¡£", f_name + mimic_f_ptr->name);
#else
- msg_format("The %s seems stuck.", f_name + f_ptr->name);
+ msg_format("The %s seems stuck.", f_name + mimic_f_ptr->name);
#endif
obvious = TRUE;
{
if (have_flag(f_ptr->flags, FF_HURT_ROCK))
{
- cptr name = f_name + f_ptr->name;
-
/* Message */
if (known && (c_ptr->info & (CAVE_MARK)))
{
#ifdef JP
- msg_format("%s¤¬ÍϤ±¤ÆÅ¥¤Ë¤Ê¤Ã¤¿¡ª", name);
+ msg_format("%s¤¬ÍϤ±¤ÆÅ¥¤Ë¤Ê¤Ã¤¿¡ª", f_name + f_info[get_feat_mimic(c_ptr)].name);
#else
- msg_format("The %s turns into mud!", name);
+ msg_format("The %s turns into mud!", f_name + f_info[get_feat_mimic(c_ptr)].name);
#endif
obvious = TRUE;
/* Make traps */
case GF_MAKE_TRAP:
{
- /* Require a "naked" floor grid */
- if (!have_flag(f_ptr->flags, FF_FLOOR) || is_mirror_grid(c_ptr))
- break;
-
/* Place a trap */
place_trap(y, x);
case GF_LITE:
{
/* Turn on the light */
- if (!(d_info[dungeon_type].flags1 & DF1_DARKNESS)) c_ptr->info |= (CAVE_GLOW);
+ if (!(d_info[dungeon_type].flags1 & DF1_DARKNESS))
+ {
+ c_ptr->info |= (CAVE_GLOW);
- /* Notice */
- note_spot(y, x);
+ /* Notice */
+ note_spot(y, x);
- /* Redraw */
- lite_spot(y, x);
+ /* Redraw */
+ lite_spot(y, x);
- /* Observe */
- if (player_can_see_bold(y, x)) obvious = TRUE;
+ update_local_illumination(y, x);
- /* Mega-Hack -- Update the monster in the affected grid */
- /* This allows "spear of light" (etc) to work "correctly" */
- if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
+ /* Observe */
+ if (player_can_see_bold(y, x)) obvious = TRUE;
+
+ /* Mega-Hack -- Update the monster in the affected grid */
+ /* This allows "spear of light" (etc) to work "correctly" */
+ if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
+ }
break;
}
{
if (!p_ptr->inside_battle)
{
- /* Notice */
- if (player_can_see_bold(y, x)) obvious = TRUE;
-
/* Turn off the light. */
if (!is_mirror_grid(c_ptr))
{
/* Notice */
note_spot(y, x);
}
- }
- /* Redraw */
- lite_spot(y, x);
+ /* Redraw */
+ lite_spot(y, x);
- /* Mega-Hack -- Update the monster in the affected grid */
- /* This allows "spear of light" (etc) to work "correctly" */
- if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
+ update_local_illumination(y, x);
+
+ /* Notice */
+ if (player_can_see_bold(y, x)) obvious = TRUE;
+
+ /* Mega-Hack -- Update the monster in the affected grid */
+ /* This allows "spear of light" (etc) to work "correctly" */
+ if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
+ }
}
/* All done */
}
break;
}
+
+ case GF_DISINTEGRATE:
+ {
+ /* Destroy mirror */
+ if (is_mirror_grid(c_ptr)) remove_mirror(y, x);
+
+ /* Permanent features don't get effect */
+ /* But not protect monsters and other objects */
+ if (have_flag(f_ptr->flags, FF_HURT_DISI) && !have_flag(f_ptr->flags, FF_PERMANENT))
+ {
+ cave_alter_feat(y, x, FF_HURT_DISI);
+
+ /* Update some things -- similar to GF_KILL_WALL */
+ p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS | PU_MON_LITE);
+ }
+ break;
+ }
}
lite_spot(y, x);
t_x = m_list[who].fx - 1 + randint1(3);
max_attempts--;
}
- while (max_attempts && in_bounds2u(t_y, t_x) &&
- !(player_has_los_bold(t_y, t_x)));
+ while (max_attempts && in_bounds2u(t_y, t_x) && !projectable(py, px, t_y, t_x));
if (max_attempts < 1)
{
msg_print("Gravity warps around you.");
#endif
- teleport_player(5);
+ teleport_player(5, TRUE);
if (!p_ptr->ffall)
(void)set_slow(p_ptr->slow + randint0(4) + 4, FALSE);
if (!(p_ptr->resist_sound || p_ptr->ffall))
/*
- * Do disintegration effect on the terrain
- * before we decide the region of the effect.
- */
-static bool do_disintegration(int by, int bx, int y, int x)
-{
- feature_type *f_ptr;
-
- /* Disintegration balls explosions are stopped by perma-walls */
- if (!in_disintegration_range(by, bx, y, x)) return FALSE;
-
- /* Permanent walls and artifacts don't get effect */
- /* But not protect monsters and other objects */
- if (!cave_valid_bold(y, x)) return TRUE;
-
- /* Destroy mirror/glyph */
- remove_mirror(y, x);
-
- f_ptr = &f_info[cave[y][x].feat];
-
- if (have_flag(f_ptr->flags, FF_HURT_DISI))
- {
- cave_alter_feat(y, x, FF_HURT_DISI);
-
- /* Update some things -- similar to GF_KILL_WALL */
- p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS | PU_MON_LITE);
- }
-
- return TRUE;
-}
-
-
-/*
* breath shape
*/
-void breath_shape(u16b *path_g, int dist, int *pgrids, byte *gx, byte *gy, byte *gm, int *pgm_rad, int rad, int y1, int x1, int y2, int x2, bool disint_ball, bool real_breath)
+void breath_shape(u16b *path_g, int dist, int *pgrids, byte *gx, byte *gy, byte *gm, int *pgm_rad, int rad, int y1, int x1, int y2, int x2, int typ)
{
int by = y1;
int bx = x1;
int bdis = 0;
int cdis;
int path_n = 0;
- int tdis = distance(y1, x1, y2, x2);
- int mdis = tdis + rad;
+ int mdis = distance(y1, x1, y2, x2) + rad;
while (bdis <= mdis)
{
/* Enforce an arc */
if (distance(by, bx, y, x) != cdis) continue;
-
- if (disint_ball)
+ switch (typ)
{
- /* Disintegration are stopped only by perma-walls */
- if (real_breath)
- {
- /* Destroy terrains */
- if (!do_disintegration(by, bx, y, x)) continue;
- }
- else
- {
- /* No actual disintegration */
- if (!in_disintegration_range(by, bx, y, x)) continue;
- }
- }
- else
- {
- /* The blast is stopped by walls */
+ case GF_LITE:
+ case GF_LITE_WEAK:
+ /* Lights are stopped by opaque terrains */
if (!los(by, bx, y, x)) continue;
+ break;
+ case GF_DISINTEGRATE:
+ /* Disintegration are stopped only by perma-walls */
+ if (!in_disintegration_range(by, bx, y, x)) continue;
+ break;
+ default:
+ /* Ball explosions are stopped by walls */
+ if (!projectable(by, bx, y, x)) continue;
+ break;
}
/* Save this grid */
grids++;
}
- if (breath && typ == GF_DISINTEGRATE)
+ switch (typ)
{
- flg |= (PROJECT_DISI);
+ case GF_LITE:
+ case GF_LITE_WEAK:
+ if (breath || (flg & PROJECT_BEAM)) flg |= (PROJECT_LOS);
+ break;
+ case GF_DISINTEGRATE:
+ flg |= (PROJECT_GRID);
+ if (breath || (flg & PROJECT_BEAM)) flg |= (PROJECT_DISI);
+ break;
}
/* Calculate the projection path */
/* Hack -- Balls explode before reaching walls */
if (cave_stop_disintegration(ny, nx) && (rad > 0)) break;
}
+ else if (flg & PROJECT_LOS)
+ {
+ /* Hack -- Balls explode before reaching walls */
+ if (!cave_los_bold(ny, nx) && (rad > 0)) break;
+ }
else
{
/* Hack -- Balls explode before reaching walls */
}
}
+ path_n = i;
+
/* Save the "blast epicenter" */
by = y;
bx = x;
- if (breath && (y1 == by) && (x1 == bx))
+ if (breath && !path_n)
{
breath = FALSE;
- gm_rad = 1;
+ gm_rad = rad;
if (!old_hide)
{
flg &= ~(PROJECT_HIDE);
{
flg &= ~(PROJECT_HIDE);
- breath_shape(path_g, dist, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, by, bx, (bool)(typ == GF_DISINTEGRATE), TRUE);
+ breath_shape(path_g, dist, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, by, bx, typ);
}
else
{
/* Enforce a "circular" explosion */
if (distance(by, bx, y, x) != dist) continue;
- if (typ == GF_DISINTEGRATE)
+ switch (typ)
{
+ case GF_LITE:
+ case GF_LITE_WEAK:
+ /* Lights are stopped by opaque terrains */
+ if (!los(by, bx, y, x)) continue;
+ break;
+ case GF_DISINTEGRATE:
/* Disintegration are stopped only by perma-walls */
- if (!do_disintegration(by, bx, y, x)) continue;
- }
- else
- {
+ if (!in_disintegration_range(by, bx, y, x)) continue;
+ break;
+ default:
/* Ball explosions are stopped by walls */
- if (!los(by, bx, y, x)) continue;
+ if (!projectable(by, bx, y, x)) continue;
+ break;
}
/* Save this grid */
}
}
+ /* Update stuff if needed */
+ if (p_ptr->update) update_stuff();
/* Check objects */
if (flg & (PROJECT_ITEM))
t_x = x_saver - 1 + randint1(3);
max_attempts--;
}
- while (max_attempts && in_bounds2u(t_y, t_x) &&
- !(los(y, x, t_y, t_x)));
+ while (max_attempts && in_bounds2u(t_y, t_x) && !projectable(y, x, t_y, t_x));
if (max_attempts < 1)
{
if( is_mirror_grid(&cave[y][x]) &&
distance(py,px,y,x) <= MAX_RANGE &&
distance(py,px,y,x) != 0 &&
- player_has_los_bold(y,x)
+ player_has_los_bold(y,x) &&
+ projectable(py, px, y, x)
){
mirror_y[mirror_num]=y;
mirror_x[mirror_num]=x;
centersign*( (point_x[2]-x)*(point_y[0]-y)
-(point_y[2]-y)*(point_x[0]-x)) >=0 )
{
- if( player_has_los_bold(y,x)){
+ if (player_has_los_bold(y, x) && projectable(py, px, y, x)) {
/* Visual effects */
if(!(p_ptr->blind)
&& panel_contains(y,x)){
centersign*( (point_x[2]-x)*(point_y[0]-y)
-(point_y[2]-y)*(point_x[0]-x)) >=0 )
{
- if( player_has_los_bold(y,x)){
+ if (player_has_los_bold(y, x) && projectable(py, px, y, x)) {
(void)project_f(0,0,y,x,dam,GF_MANA);
}
}
centersign*( (point_x[2]-x)*(point_y[0]-y)
-(point_y[2]-y)*(point_x[0]-x)) >=0 )
{
- if( player_has_los_bold(y,x)){
+ if (player_has_los_bold(y, x) && projectable(py, px, y, x)) {
(void)project_o(0,0,y,x,dam,GF_MANA);
}
}
centersign*( (point_x[2]-x)*(point_y[0]-y)
-(point_y[2]-y)*(point_x[0]-x)) >=0 )
{
- if( player_has_los_bold(y,x) ){
+ if (player_has_los_bold(y, x) && projectable(py, px, y, x)) {
(void)project_m(0,0,y,x,dam,GF_MANA,
(PROJECT_GRID|PROJECT_ITEM|PROJECT_KILL|PROJECT_JUMP));
}