Called when a boulder is dropped, thrown, or pushed. If it ends up * in a pool, it either fills the pool up or sinks away. In either case, * it's gone for good... If the destination is not a pool, returns FALSE. */
| 47 | * it's gone for good... If the destination is not a pool, returns FALSE. |
| 48 | */ |
| 49 | boolean |
| 50 | boulder_hits_pool( |
| 51 | struct obj *otmp, /* the object falling into a pool or water or lava */ |
| 52 | coordxy rx, coordxy ry, /* coordinates of the pool */ |
| 53 | boolean pushing) /* for a boulder, whether or not it is being pushed */ |
| 54 | { |
| 55 | if (!otmp || otmp->otyp != BOULDER) { |
| 56 | impossible("Not a boulder?"); |
| 57 | } else if (is_pool_or_lava(rx, ry)) { |
| 58 | boolean lava = is_lava(rx, ry), fills_up; |
| 59 | const char *what = waterbody_name(rx, ry); |
| 60 | schar ltyp = levl[rx][ry].typ; |
| 61 | int chance = rn2(10); /* water: 90%; lava: 10% */ |
| 62 | struct monst *mtmp; |
| 63 | |
| 64 | /* chance for boulder to fill pool: Plane of Water==0%, |
| 65 | lava 10%, wall of water==50%, other water==90% */ |
| 66 | fills_up = Is_waterlevel(&u.uz) ? FALSE |
| 67 | : IS_WATERWALL(ltyp) ? (chance < 5) |
| 68 | : lava ? (chance == 0) : (chance != 0); |
| 69 | |
| 70 | if (fills_up) { |
| 71 | struct trap *ttmp = t_at(rx, ry); |
| 72 | |
| 73 | if (ltyp == DRAWBRIDGE_UP) { |
| 74 | levl[rx][ry].drawbridgemask &= ~DB_UNDER; /* clear lava */ |
| 75 | levl[rx][ry].drawbridgemask |= DB_FLOOR; |
| 76 | } else { |
| 77 | levl[rx][ry].typ = ROOM, levl[rx][ry].flags = 0; |
| 78 | recalc_block_point(rx, ry); |
| 79 | } |
| 80 | /* 5.0: normally DEADMONSTER() is used when traversing the fmon |
| 81 | list--dead monsters usually aren't still at specific map |
| 82 | locations; however, if ice melts causing a giant to drown, |
| 83 | that giant would still be on the map when it drops inventory; |
| 84 | if it was carrying a boulder which now fills the pool, 'mtmp' |
| 85 | will be dead here; killing it again would yield impossible |
| 86 | "dmonsfree: N removed doesn't match N+1 pending" when other |
| 87 | monsters have finished their current turn */ |
| 88 | if ((mtmp = m_at(rx, ry)) != 0 && !DEADMONSTER(mtmp) |
| 89 | && !m_in_air(mtmp)) |
| 90 | mondied(mtmp); |
| 91 | |
| 92 | if (ttmp) |
| 93 | (void) delfloortrap(ttmp); |
| 94 | bury_objs(rx, ry); |
| 95 | |
| 96 | newsym(rx, ry); |
| 97 | if (pushing) { |
| 98 | char whobuf[BUFSZ]; |
| 99 | |
| 100 | Strcpy(whobuf, "you"); |
| 101 | if (u.usteed) |
| 102 | Strcpy(whobuf, y_monnam(u.usteed)); |
| 103 | pline("%s %s %s into the %s.", upstart(whobuf), |
| 104 | vtense(whobuf, "push"), the(xname(otmp)), what); |
| 105 | if (flags.verbose && !Blind) |
| 106 | pline("Now you can cross it!"); |
no test coverage detected