Returns an absolute depth */
| 2188 | |
| 2189 | /* Returns an absolute depth */ |
| 2190 | int |
| 2191 | random_teleport_level(void) |
| 2192 | { |
| 2193 | int nlev, max_depth, min_depth, cur_depth = (int) depth(&u.uz); |
| 2194 | |
| 2195 | /* [the endgame case can only occur in wizard mode] */ |
| 2196 | if (!rn2(5) || single_level_branch(&u.uz) || In_endgame(&u.uz)) |
| 2197 | return cur_depth; |
| 2198 | |
| 2199 | /* What I really want to do is as follows: |
| 2200 | * -- If in a dungeon that goes down, the new level is to be restricted |
| 2201 | * to [top of parent, bottom of current dungeon] |
| 2202 | * -- If in a dungeon that goes up, the new level is to be restricted |
| 2203 | * to [top of current dungeon, bottom of parent] |
| 2204 | * -- If in a quest dungeon or similar dungeon entered by portals, |
| 2205 | * the new level is to be restricted to [top of current dungeon, |
| 2206 | * bottom of current dungeon] |
| 2207 | * The current behavior is not as sophisticated as that ideal, but is |
| 2208 | * still better what we used to do, which was like this for players |
| 2209 | * but different for monsters for no obvious reason. Currently, we |
| 2210 | * must explicitly check for special dungeons. We check for Knox |
| 2211 | * above; endgame is handled in the caller due to its different |
| 2212 | * message ("disoriented"). |
| 2213 | * --KAA |
| 2214 | * 3.4.2: explicitly handle quest here too, to fix the problem of |
| 2215 | * monsters sometimes level teleporting out of it into main dungeon. |
| 2216 | * Also prevent monsters reaching the Sanctum prior to invocation. |
| 2217 | */ |
| 2218 | if (In_quest(&u.uz)) { |
| 2219 | int bottom = dunlevs_in_dungeon(&u.uz), |
| 2220 | qlocate_depth = qlocate_level.dlevel; |
| 2221 | |
| 2222 | /* if hero hasn't reached the middle locate level yet, |
| 2223 | no one can randomly teleport past it */ |
| 2224 | if (dunlev_reached(&u.uz) < qlocate_depth) |
| 2225 | bottom = qlocate_depth; |
| 2226 | min_depth = svd.dungeons[u.uz.dnum].depth_start; |
| 2227 | max_depth = bottom + (svd.dungeons[u.uz.dnum].depth_start - 1); |
| 2228 | } else { |
| 2229 | min_depth = 1; |
| 2230 | max_depth = dunlevs_in_dungeon(&u.uz) |
| 2231 | + (svd.dungeons[u.uz.dnum].depth_start - 1); |
| 2232 | /* can't reach Sanctum if the invocation hasn't been performed */ |
| 2233 | if (Inhell && !u.uevent.invoked) |
| 2234 | max_depth -= 1; |
| 2235 | } |
| 2236 | |
| 2237 | /* Get a random value relative to the current dungeon */ |
| 2238 | /* Range is 1 to current+3, current not counting */ |
| 2239 | nlev = rn2(cur_depth + 3 - min_depth) + min_depth; |
| 2240 | if (nlev >= cur_depth) |
| 2241 | nlev++; |
| 2242 | |
| 2243 | if (nlev > max_depth) { |
| 2244 | nlev = max_depth; |
| 2245 | /* teleport up if already on bottom */ |
| 2246 | if (Is_botlevel(&u.uz)) |
| 2247 | nlev -= rnd(3); |
no test coverage detected