| 3309 | } |
| 3310 | |
| 3311 | void |
| 3312 | spoteffects(boolean pick) |
| 3313 | { |
| 3314 | static int inspoteffects = 0; |
| 3315 | static coord spotloc; |
| 3316 | static int spotterrain; |
| 3317 | static struct trap *spottrap = (struct trap *) 0; |
| 3318 | static unsigned spottraptyp = NO_TRAP; |
| 3319 | |
| 3320 | struct monst *mtmp; |
| 3321 | struct trap *trap = t_at(u.ux, u.uy); |
| 3322 | int trapflag = iflags.failing_untrap ? FAILEDUNTRAP : 0; |
| 3323 | |
| 3324 | /* prevent recursion from affecting the hero all over again |
| 3325 | [hero poly'd to iron golem enters water here, drown() inflicts |
| 3326 | damage that triggers rehumanize() which calls spoteffects()...] */ |
| 3327 | if (inspoteffects && u_at(spotloc.x, spotloc.y) |
| 3328 | /* except when reason is transformed terrain (ice -> water) */ |
| 3329 | && spotterrain == levl[u.ux][u.uy].typ |
| 3330 | /* or transformed trap (land mine -> pit) */ |
| 3331 | && (!spottrap || !trap || trap->ttyp == spottraptyp)) |
| 3332 | return; |
| 3333 | /* when float_down() puts hero into lava and she teleports out, |
| 3334 | defer spoteffects() until after "you are back on solid <surface>" */ |
| 3335 | if (iflags.in_lava_effects) |
| 3336 | return; |
| 3337 | |
| 3338 | ++inspoteffects; |
| 3339 | spotterrain = levl[u.ux][u.uy].typ; |
| 3340 | spotloc.x = u.ux, spotloc.y = u.uy; |
| 3341 | |
| 3342 | /* moving onto different terrain might cause Lev or Fly to toggle; |
| 3343 | level change sets <ux0,uy0> to <ux,uy>, so this spotterrain |
| 3344 | check always fails then, but it also sets iflags.terrain_typ */ |
| 3345 | if (spotterrain != levl[u.ux0][u.uy0].typ |
| 3346 | || iflags.terrain_typ == MAX_TYPE) |
| 3347 | switch_terrain(); |
| 3348 | |
| 3349 | if (pooleffects(TRUE)) |
| 3350 | goto spotdone; |
| 3351 | |
| 3352 | check_special_room(FALSE); |
| 3353 | if (IS_SINK(levl[u.ux][u.uy].typ) && Levitation) |
| 3354 | dosinkfall(); |
| 3355 | if (!gi.in_steed_dismounting) { /* if dismounting, check again later */ |
| 3356 | boolean pit; |
| 3357 | |
| 3358 | /* if levitation is due to time out at the end of this |
| 3359 | turn, allowing it to do so could give the perception |
| 3360 | that a trap here is being triggered twice, so adjust |
| 3361 | the timeout to prevent that */ |
| 3362 | if (trap && (HLevitation & TIMEOUT) == 1L |
| 3363 | && !(ELevitation || (HLevitation & ~(I_SPECIAL | TIMEOUT)))) { |
| 3364 | if (rn2(2)) { /* defer timeout */ |
| 3365 | incr_itimeout(&HLevitation, 1L); |
| 3366 | } else { /* timeout early */ |
| 3367 | if (float_down(I_SPECIAL | TIMEOUT, 0L)) { |
| 3368 | /* levitation has ended; we've already triggered |
no test coverage detected