MCPcopy Create free account
hub / github.com/NetHack/NetHack / random_teleport_level

Function random_teleport_level

src/teleport.c:2190–2258  ·  view source on GitHub ↗

Returns an absolute depth */

Source from the content-addressed store, hash-verified

2188
2189/* Returns an absolute depth */
2190int
2191random_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);

Callers 5

level_teleFunction · 0.85
mlevel_tele_trapFunction · 0.85
moverock_coreFunction · 0.85
launch_objFunction · 0.85
use_defensiveFunction · 0.85

Calls 7

depthFunction · 0.85
rn2Function · 0.85
single_level_branchFunction · 0.85
In_questFunction · 0.85
dunlevs_in_dungeonFunction · 0.85
Is_botlevelFunction · 0.85
rndFunction · 0.85

Tested by

no test coverage detected