Apply the new ground_level method.
[crawl.git] / crawl-ref / source / stairs.cc
blob074b221d53884b05854d6e6369b79383b027907c
1 #include "AppHdr.h"
3 #include "stairs.h"
5 #include <sstream>
7 #include "abyss.h"
8 #include "areas.h"
9 #include "branch.h"
10 #include "chardump.h"
11 #include "delay.h"
12 #include "dgn-overview.h"
13 #include "directn.h"
14 #include "env.h"
15 #include "files.h"
16 #include "hints.h"
17 #include "hiscores.h"
18 #include "itemname.h"
19 #include "items.h"
20 #include "lev-pand.h"
21 #include "libutil.h"
22 #include "mapmark.h"
23 #include "message.h"
24 #include "misc.h"
25 #include "notes.h"
26 #include "options.h"
27 #include "ouch.h"
28 #include "output.h"
29 #include "place.h"
30 #include "random.h"
31 #include "spl-clouds.h"
32 #include "spl-damage.h"
33 #include "spl-transloc.h"
34 #include "stash.h"
35 #include "state.h"
36 #include "stuff.h"
37 #include "tagstring.h"
38 #include "terrain.h"
39 #ifdef USE_TILE
40 #include "tilepick.h"
41 #endif
42 #include "traps.h"
43 #include "travel.h"
44 #include "view.h"
45 #include "xom.h"
47 bool check_annotation_exclusion_warning()
49 // Players might not realise the implications of teleport mutations
50 // in the labyrinth.
51 if (grd(you.pos()) == DNGN_ENTER_LABYRINTH
52 && player_mutation_level(MUT_TELEPORT))
54 mpr("Within the labyrinth you'll only be able to teleport away from "
55 "the exit!");
56 if (!yesno("Continue anyway?", false, 'N', true, false))
58 canned_msg(MSG_OK);
59 interrupt_activity(AI_FORCE_INTERRUPT);
60 return (false);
62 return (true);
65 level_id next_level_id = level_id::get_next_level_id(you.pos());
67 crawl_state.level_annotation_shown = false;
68 bool might_be_dangerous = false;
70 if (level_annotation_has("!", next_level_id)
71 && next_level_id != level_id::current()
72 && next_level_id.level_type == LEVEL_DUNGEON)
74 mpr("Warning, next level annotated: " +
75 colour_string(get_level_annotation(next_level_id), YELLOW),
76 MSGCH_PROMPT);
77 might_be_dangerous = true;
78 crawl_state.level_annotation_shown = true;
80 else if (is_exclude_root(you.pos())
81 && feat_is_travelable_stair(grd(you.pos()))
82 && !strstr(get_exclusion_desc(you.pos()).c_str(), "cloud"))
84 mpr("This staircase is marked as excluded!", MSGCH_WARN);
85 might_be_dangerous = true;
88 if (might_be_dangerous
89 && !yesno("Enter next level anyway?", true, 'n', true, false))
91 canned_msg(MSG_OK);
92 interrupt_activity(AI_FORCE_INTERRUPT);
93 crawl_state.level_annotation_shown = false;
94 return (false);
96 return (true);
99 static void _player_change_level_reset()
101 you.prev_targ = MHITNOT;
102 if (you.pet_target != MHITYOU)
103 you.pet_target = MHITNOT;
105 you.prev_grd_targ.reset();
108 static level_id _stair_destination_override()
110 const std::string force_place =
111 env.markers.property_at(you.pos(), MAT_ANY, "dstplace");
112 if (!force_place.empty())
116 const level_id place = level_id::parse_level_id(force_place);
117 return (place);
119 catch (const std::string &err)
121 end(1, false, "Marker set with invalid level name: %s",
122 force_place.c_str());
126 const level_id invalid;
127 return (invalid);
130 static bool _stair_force_destination(const level_id &override)
132 if (override.is_valid())
134 if (override.level_type == LEVEL_DUNGEON)
136 you.where_are_you = override.branch;
137 you.absdepth0 = override.absdepth();
138 you.level_type = override.level_type;
140 else
142 you.level_type = override.level_type;
144 return (true);
146 return (false);
149 static void _player_change_level_upstairs(dungeon_feature_type stair_find,
150 const level_id &place_override)
152 if (_stair_force_destination(place_override))
153 return;
155 if (you.level_type == LEVEL_DUNGEON)
156 you.absdepth0--;
158 // Make sure we return to our main dungeon level... labyrinth entrances
159 // in the abyss or pandemonium are a bit trouble (well the labyrinth does
160 // provide a way out of those places, its really not that bad I suppose).
161 if (level_type_exits_up(you.level_type))
162 you.level_type = LEVEL_DUNGEON;
164 if (player_in_branch(BRANCH_VESTIBULE_OF_HELL))
166 you.where_are_you = you.hell_branch;
167 you.absdepth0 = you.hell_exit;
170 if (player_in_hell())
172 you.where_are_you = BRANCH_VESTIBULE_OF_HELL;
173 you.absdepth0 = 27;
176 // Did we take a branch stair?
177 for (int i = 0; i < NUM_BRANCHES; ++i)
179 if (branches[i].exit_stairs == stair_find
180 && you.where_are_you == i)
182 you.where_are_you = branches[i].parent_branch;
184 // If leaving a branch which wasn't generated in this
185 // particular game (like the Swamp or Shoals), then
186 // its startdepth is set to -1; compensate for that,
187 // so we don't end up on "level -1".
188 if (branches[i].startdepth == -1)
189 you.absdepth0 += 2;
190 break;
195 static bool _marker_vetoes_level_change()
197 return (marker_vetoes_operation("veto_level_change"));
200 static bool _stair_moves_pre(dungeon_feature_type stair)
202 if (crawl_state.prev_cmd == CMD_WIZARD)
203 return (false);
205 if (stair != grd(you.pos()))
206 return (false);
208 if (feat_stair_direction(stair) == CMD_NO_CMD)
209 return (false);
211 if (!you.duration[DUR_REPEL_STAIRS_CLIMB])
212 return (false);
214 int pct;
215 if (you.duration[DUR_REPEL_STAIRS_MOVE])
216 pct = 29;
217 else
218 pct = 50;
220 // When the effect is still strong, the chance to actually catch a stair
221 // is smaller. (Assuming the duration starts out at 500.)
222 const int dur = std::max(0, you.duration[DUR_REPEL_STAIRS_CLIMB] - 200);
223 pct += dur/20;
225 if (!x_chance_in_y(pct, 100))
226 return (false);
228 // Get feature name before sliding stair over.
229 std::string stair_str =
230 feature_description(you.pos(), false, DESC_CAP_THE, false);
232 if (!slide_feature_over(you.pos(), coord_def(-1, -1), false))
233 return (false);
235 std::string verb = stair_climb_verb(stair);
237 mprf("%s moves away as you attempt to %s it!", stair_str.c_str(),
238 verb.c_str());
240 you.turn_is_over = true;
242 return (true);
245 static bool _check_carrying_orb()
247 // We never picked up the Orb, no problem.
248 if (you.char_direction != GDT_ASCENDING)
249 return (true);
251 // So we did pick up the Orb. Now check whether we're carrying it.
252 for (int i = 0; i < ENDOFPACK; i++)
254 if (you.inv[i].defined()
255 && you.inv[i].base_type == OBJ_ORBS
256 && you.inv[i].sub_type == ORB_ZOT)
258 return (true);
261 return (yes_or_no("You're not carrying the Orb! Leave anyway"));
264 // Adds a dungeon marker at the point of the level where returning from
265 // a labyrinth or portal vault should drop the player.
266 static void _mark_portal_return_point(const coord_def &pos)
268 // First toss all markers of this type. Stale markers are possible
269 // if the player goes to the Abyss from a portal vault /
270 // labyrinth, thus returning to this level without activating a
271 // previous portal vault exit marker.
272 const std::vector<map_marker*> markers = env.markers.get_all(MAT_FEATURE);
273 for (int i = 0, size = markers.size(); i < size; ++i)
275 if (dynamic_cast<map_feature_marker*>(markers[i])->feat ==
276 DNGN_EXIT_PORTAL_VAULT)
278 env.markers.remove(markers[i]);
282 if (!env.markers.find(pos, MAT_FEATURE))
284 map_feature_marker *mfeat =
285 new map_feature_marker(pos, DNGN_EXIT_PORTAL_VAULT);
286 env.markers.add(mfeat);
290 static void _exit_stair_message(dungeon_feature_type stair, bool /* going_up */)
292 if (feat_is_escape_hatch(stair))
293 mpr("The hatch slams shut behind you.");
296 static void _climb_message(dungeon_feature_type stair, bool going_up,
297 level_area_type old_level_type)
299 if (old_level_type != LEVEL_DUNGEON)
300 return;
302 if (feat_is_portal(stair))
303 mpr("The world spins around you as you enter the gateway.");
304 else if (feat_is_escape_hatch(stair))
306 if (going_up)
307 mpr("A mysterious force pulls you upwards.");
308 else
310 mprf("You %s downwards.",
311 you.flight_mode() == FL_FLY ? "fly" :
312 (you.airborne() ? "float" : "slide"));
315 else if (feat_is_gate(stair))
317 mprf("You %s %s through the gate.",
318 you.flight_mode() == FL_FLY ? "fly" :
319 (you.airborne() ? "float" : "go"),
320 going_up ? "up" : "down");
322 else
324 mprf("You %s %swards.",
325 you.flight_mode() == FL_FLY ? "fly" :
326 (you.airborne() ? "float" : "climb"),
327 going_up ? "up" : "down");
331 static void _clear_golubria_traps()
333 std::vector<coord_def> traps = find_golubria_on_level();
334 for (std::vector<coord_def>::const_iterator it = traps.begin(); it != traps.end(); ++it)
336 trap_def *trap = find_trap(*it);
337 if (trap && trap->type == TRAP_GOLUBRIA)
339 trap->destroy();
344 static void _leaving_level_now()
346 // Note the name ahead of time because the events may cause markers
347 // to be discarded.
348 const std::string newtype =
349 env.markers.property_at(you.pos(), MAT_ANY, "dst");
351 // Extension to use for bones files.
352 const std::string newext =
353 env.markers.property_at(you.pos(), MAT_ANY, "dstext");
355 const std::string oldname = you.level_type_name;
356 std::string newname =
357 env.markers.property_at(you.pos(), MAT_ANY, "dstname");
359 std::string neworigin =
360 env.markers.property_at(you.pos(), MAT_ANY, "dstorigin");
362 const std::string oldname_abbrev = you.level_type_name_abbrev;
363 std::string newname_abbrev =
364 env.markers.property_at(you.pos(), MAT_ANY, "dstname_abbrev");
366 dungeon_events.fire_position_event(DET_PLAYER_CLIMBS, you.pos());
367 dungeon_events.fire_event(DET_LEAVING_LEVEL);
369 // Lua scripts explicitly set level_type_name, so use that.
370 if (you.level_type_name != oldname)
371 newname = you.level_type_name;
373 // Lua scripts explicitly set level_type_name_abbrev, so use that.
374 if (you.level_type_name_abbrev != oldname_abbrev)
375 newname_abbrev = you.level_type_name_abbrev;
377 if (newname_abbrev.length() > MAX_NOTE_PLACE_LEN)
379 mprf(MSGCH_ERROR, "'%s' is too long for a portal vault name "
380 "abbreviation, truncating");
381 newname_abbrev = newname_abbrev.substr(0, MAX_NOTE_PLACE_LEN);
384 you.level_type_origin = "";
385 // Lua scripts explicitly set level_type_origin, so use that.
386 if (!you.level_type_origin.empty())
387 neworigin = you.level_type_origin;
389 // Don't clobber level_type_name for stairs in portal vaults.
390 if (you.level_type_name.empty() || !newname.empty()
391 || you.level_type != LEVEL_PORTAL_VAULT)
393 you.level_type_name = newname;
396 // Don't clobber level_type_name_abbrev for stairs in portal vaults.
397 if (you.level_type_name_abbrev.empty() || !newname_abbrev.empty()
398 || you.level_type != LEVEL_PORTAL_VAULT)
400 you.level_type_name_abbrev = newname_abbrev;
403 if (you.level_type_tag.empty() || !newtype.empty()
404 || you.level_type != LEVEL_PORTAL_VAULT)
406 you.level_type_tag = newtype;
409 const std::string spaced_tag = replace_all(you.level_type_tag, "_", " ");
411 if (!you.level_type_tag.empty() && you.level_type_name.empty())
412 you.level_type_name = spaced_tag;
414 if (!you.level_type_name.empty() && you.level_type_name_abbrev.empty())
416 if (you.level_type_name.length() <= MAX_NOTE_PLACE_LEN)
417 you.level_type_name_abbrev = you.level_type_name;
418 else if (you.level_type_tag.length() <= MAX_NOTE_PLACE_LEN)
419 you.level_type_name_abbrev = spaced_tag;
420 else
422 const std::string shorter =
423 you.level_type_name.length() < you.level_type_tag.length() ?
424 you.level_type_name : spaced_tag;
426 you.level_type_name_abbrev = shorter.substr(0, MAX_NOTE_PLACE_LEN);
430 if (!newext.empty())
431 you.level_type_ext = newext;
432 else if (!you.level_type_tag.empty())
433 you.level_type_ext = lowercase_string(you.level_type_tag);
435 if (you.level_type_ext.length() > 3)
436 you.level_type_ext = you.level_type_ext.substr(0, 3);
438 if (!neworigin.empty())
439 you.level_type_origin = neworigin;
440 else if (!you.level_type_name.empty())
442 std::string lname = lowercase_string(you.level_type_name);
443 std::string article, prep;
445 if (starts_with(lname, "level ")
446 || lname.find(":") != std::string::npos)
448 prep = "on ";
450 else
451 prep = "in ";
453 if (starts_with(lname, "a ") || starts_with(lname, "an ")
454 || starts_with(lname, "the ") || starts_with(lname, "level ")
455 || lname.find(":") != std::string::npos)
457 ; // Doesn't need an article
459 else
461 char letter = you.level_type_name[0];
462 if (isupper(letter))
463 article = "the ";
464 else if (is_vowel(letter))
465 article = "an ";
466 else
467 article = "a ";
470 you.level_type_origin = prep + article + you.level_type_name;
473 _clear_golubria_traps();
476 static void _set_entry_cause(entry_cause_type default_cause,
477 level_area_type old_level_type)
479 ASSERT(default_cause != NUM_ENTRY_CAUSE_TYPES);
481 if (old_level_type == you.level_type && you.entry_cause != EC_UNKNOWN)
482 return;
484 if (crawl_state.is_god_acting())
486 if (crawl_state.is_god_retribution())
487 you.entry_cause = EC_GOD_RETRIBUTION;
488 else
489 you.entry_cause = EC_GOD_ACT;
491 you.entry_cause_god = crawl_state.which_god_acting();
493 else if (default_cause != EC_UNKNOWN)
495 you.entry_cause = default_cause;
496 you.entry_cause_god = GOD_NO_GOD;
498 else
500 you.entry_cause = EC_SELF_EXPLICIT;
501 you.entry_cause_god = GOD_NO_GOD;
505 static void _update_travel_cache(bool collect_travel_data,
506 const level_id& old_level,
507 const coord_def& stair_pos)
509 if (collect_travel_data)
511 // Update stair information for the stairs we just ascended, and the
512 // down stairs we're currently on.
513 level_id new_level_id = level_id::current();
515 if (can_travel_interlevel())
517 LevelInfo &old_level_info =
518 travel_cache.get_level_info(old_level);
519 LevelInfo &new_level_info =
520 travel_cache.get_level_info(new_level_id);
521 new_level_info.update();
523 // First we update the old level's stair.
524 level_pos lp;
525 lp.id = new_level_id;
526 lp.pos = you.pos();
528 bool guess = false;
529 // Ugly hack warning:
530 // The stairs in the Vestibule of Hell exhibit special behaviour:
531 // they always lead back to the dungeon level that the player
532 // entered the Vestibule from. This means that we need to pretend
533 // we don't know where the upstairs from the Vestibule go each time
534 // we take it. If we don't, interlevel travel may try to use portals
535 // to Hell as shortcuts between dungeon levels, which won't work,
536 // and will confuse the dickens out of the player (well, it confused
537 // the dickens out of me when it happened).
538 if (new_level_id == BRANCH_MAIN_DUNGEON
539 && old_level == BRANCH_VESTIBULE_OF_HELL)
541 old_level_info.clear_stairs(DNGN_EXIT_HELL);
543 else
545 old_level_info.update_stair(stair_pos, lp, guess);
548 // We *guess* that going up a staircase lands us on a downstair,
549 // and that we can descend that downstair and get back to where we
550 // came from. This assumption is guaranteed false when climbing out
551 // of one of the branches of Hell.
552 if (new_level_id != BRANCH_VESTIBULE_OF_HELL
553 || !is_hell_subbranch(old_level.branch))
555 // Set the new level's stair, assuming arbitrarily that going
556 // downstairs will land you on the same upstairs you took to
557 // begin with (not necessarily true).
558 lp.id = old_level;
559 lp.pos = stair_pos;
560 new_level_info.update_stair(you.pos(), lp, true);
564 else // !collect_travel_data
566 travel_cache.erase_level_info(old_level);
570 void up_stairs(dungeon_feature_type force_stair,
571 entry_cause_type entry_cause)
573 dungeon_feature_type stair_find = (force_stair ? force_stair
574 : grd(you.pos()));
575 const level_id old_level = level_id::current();
577 // Up and down both work for shops.
578 if (stair_find == DNGN_ENTER_SHOP)
580 shop();
581 return;
584 // Up and down both work for portals.
585 if (feat_is_bidirectional_portal(stair_find))
587 if (!(stair_find == DNGN_ENTER_HELL && player_in_hell())) {
588 down_stairs(force_stair, entry_cause);
589 return;
592 // Probably still need this check here (teleportation) -- bwr
593 else if (feat_stair_direction(stair_find) != CMD_GO_UPSTAIRS)
595 if (stair_find == DNGN_STONE_ARCH)
596 mpr("There is nothing on the other side of the stone arch.");
597 else if (stair_find == DNGN_ABANDONED_SHOP)
598 mpr("This shop appears to be closed.");
599 else
600 mpr("You can't go up here.");
601 return;
604 if (_stair_moves_pre(stair_find))
605 return;
607 // Since the overloaded message set turn_is_over, I'm assuming that
608 // the overloaded character makes an attempt... so we're doing this
609 // check before that one. -- bwr
610 if (!you.airborne()
611 && you.confused()
612 && old_level.level_type == LEVEL_DUNGEON
613 && !feat_is_escape_hatch(stair_find)
614 && coinflip())
616 const char* fall_where = "down the stairs";
617 if (!feat_is_staircase(stair_find))
618 fall_where = "through the gate";
620 mprf("In your confused state, you trip and fall back %s.", fall_where);
621 if (!feat_is_staircase(stair_find))
622 ouch(1, NON_MONSTER, KILLED_BY_FALLING_THROUGH_GATE);
623 else
624 ouch(1, NON_MONSTER, KILLED_BY_FALLING_DOWN_STAIRS);
625 you.turn_is_over = true;
626 return;
629 if (you.burden_state == BS_OVERLOADED && !feat_is_escape_hatch(stair_find)
630 && !feat_is_gate(stair_find))
632 mpr("You are carrying too much to climb upwards.");
633 you.turn_is_over = true;
634 return;
637 const level_id destination_override(_stair_destination_override());
638 const bool leaving_dungeon =
639 level_id::current() == level_id(BRANCH_MAIN_DUNGEON, 1)
640 && !destination_override.is_valid();
642 if (leaving_dungeon)
644 bool stay = (!yesno("Are you sure you want to leave the Dungeon?",
645 false, 'n') || !_check_carrying_orb());
647 if (!stay && crawl_state.game_is_hints())
649 if (!yesno("Are you *sure*? Doing so will end the game!", false,
650 'n'))
652 stay = true;
656 if (stay)
658 mpr("Alright, then stay!");
659 return;
663 // Bail if any markers veto the move.
664 if (_marker_vetoes_level_change())
665 return;
667 // Magical level changes (don't exist yet in this direction)
668 // need this.
669 clear_trapping_net();
671 // Checks are done, the character is committed to moving between levels.
672 _leaving_level_now();
674 // Interlevel travel data.
675 const bool collect_travel_data = can_travel_interlevel();
676 if (collect_travel_data)
678 LevelInfo &old_level_info = travel_cache.get_level_info(old_level);
679 old_level_info.update();
682 _player_change_level_reset();
683 _player_change_level_upstairs(stair_find, destination_override);
685 if (you.absdepth0 < 0)
687 mpr("You have escaped!");
689 for (int i = 0; i < ENDOFPACK; i++)
691 if (you.inv[i].defined()
692 && you.inv[i].base_type == OBJ_ORBS)
694 ouch(INSTANT_DEATH, NON_MONSTER, KILLED_BY_WINNING);
698 ouch(INSTANT_DEATH, NON_MONSTER, KILLED_BY_LEAVING);
701 if (old_level.branch == BRANCH_VESTIBULE_OF_HELL
702 && !player_in_branch(BRANCH_VESTIBULE_OF_HELL))
704 mpr("Thank you for visiting Hell. Please come again soon.");
707 // Fixup exits from the Hell branches.
708 if (player_in_branch(BRANCH_VESTIBULE_OF_HELL))
710 switch (old_level.branch)
712 case BRANCH_COCYTUS: stair_find = DNGN_ENTER_COCYTUS; break;
713 case BRANCH_DIS: stair_find = DNGN_ENTER_DIS; break;
714 case BRANCH_GEHENNA: stair_find = DNGN_ENTER_GEHENNA; break;
715 case BRANCH_TARTARUS: stair_find = DNGN_ENTER_TARTARUS; break;
716 default: break;
720 const dungeon_feature_type stair_taken = stair_find;
722 if (you.flight_mode() == FL_LEVITATE && !feat_is_gate(stair_find))
723 mpr("You float upwards... And bob straight up to the ceiling!");
724 else if (you.flight_mode() == FL_FLY && !feat_is_gate(stair_find))
725 mpr("You fly upwards.");
726 else
727 _climb_message(stair_find, true, old_level.level_type);
729 _exit_stair_message(stair_find, true);
731 if (old_level.branch != you.where_are_you && you.level_type == LEVEL_DUNGEON)
733 mprf("Welcome back to %s!",
734 branches[you.where_are_you].longname);
737 const coord_def stair_pos = you.pos();
739 load(stair_taken, LOAD_ENTER_LEVEL, old_level);
741 _set_entry_cause(entry_cause, old_level.level_type);
742 entry_cause = you.entry_cause;
744 you.turn_is_over = true;
746 save_game_state();
748 new_level();
750 _update_travel_cache(collect_travel_data, old_level, stair_pos);
752 env.map_shadow = env.map_knowledge;
753 // Preventing obvious finding of stairs at your position.
754 env.map_shadow(you.pos()).flags |= MAP_SEEN_FLAG;
756 viewwindow();
758 // Checking new squares for interesting features.
759 if (!you.running)
760 check_for_interesting_features();
762 seen_monsters_react();
764 // Left Zot without enough runes to get back in (because they were
765 // destroyed), but need to get back in Zot to get the Orb?
766 // Xom finds that funny.
767 if (stair_find == DNGN_RETURN_FROM_ZOT
768 && branches[BRANCH_HALL_OF_ZOT].branch_flags & BFLAG_HAS_ORB)
770 int runes_avail = you.attribute[ATTR_UNIQUE_RUNES]
771 + you.attribute[ATTR_DEMONIC_RUNES]
772 + you.attribute[ATTR_ABYSSAL_RUNES];
774 if (runes_avail < NUMBER_OF_RUNES_NEEDED)
775 xom_is_stimulated(255, "Xom snickers loudly.", true);
778 if (!allow_control_teleport(true))
779 mpr("You sense a powerful magical force warping space.", MSGCH_WARN);
781 request_autopickup();
784 // All changes to you.level_type, you.where_are_you and you.absdepth0
785 // for descending stairs should happen here.
786 static void _player_change_level_downstairs(dungeon_feature_type stair_find,
787 const level_id &place_override,
788 bool shaft,
789 int shaft_level,
790 const level_id &shaft_dest)
792 if (_stair_force_destination(place_override))
793 return;
795 const level_area_type original_level_type(you.level_type);
797 if (you.level_type != LEVEL_DUNGEON
798 && (you.level_type != LEVEL_PANDEMONIUM
799 || stair_find != DNGN_TRANSIT_PANDEMONIUM)
800 && (you.level_type != LEVEL_PORTAL_VAULT
801 || !feat_is_stone_stair(stair_find)))
803 you.level_type = LEVEL_DUNGEON;
806 if (stair_find == DNGN_ENTER_HELL)
808 you.hell_branch = you.where_are_you;
809 you.where_are_you = BRANCH_VESTIBULE_OF_HELL;
810 you.hell_exit = you.absdepth0;
812 you.absdepth0 = 26;
815 // Welcome message.
816 // Try to find a branch stair.
817 for (int i = 0; i < NUM_BRANCHES; ++i)
819 if (branches[i].entry_stairs == stair_find)
821 you.where_are_you = branches[i].id;
822 break;
826 if (stair_find == DNGN_ENTER_LABYRINTH)
827 you.level_type = LEVEL_LABYRINTH;
828 else if (stair_find == DNGN_ENTER_ABYSS)
829 you.level_type = LEVEL_ABYSS;
830 else if (stair_find == DNGN_ENTER_PANDEMONIUM)
831 you.level_type = LEVEL_PANDEMONIUM;
832 else if (stair_find == DNGN_ENTER_PORTAL_VAULT)
833 you.level_type = LEVEL_PORTAL_VAULT;
835 if (shaft)
837 you.absdepth0 = shaft_level;
838 you.where_are_you = shaft_dest.branch;
840 else if (original_level_type == LEVEL_DUNGEON
841 && you.level_type == LEVEL_DUNGEON)
843 you.absdepth0++;
847 static void _maybe_destroy_trap(const coord_def &p)
849 trap_def* trap = find_trap(p);
850 if (trap)
851 trap->destroy();
854 int runes_in_pack(std::vector<int> &runes)
856 int num_runes = 0;
858 for (int i = 0; i < ENDOFPACK; i++)
860 if (you.inv[i].defined()
861 && you.inv[i].base_type == OBJ_MISCELLANY
862 && you.inv[i].sub_type == MISC_RUNE_OF_ZOT)
864 num_runes += you.inv[i].quantity;
865 for (int q = 1;
866 runes.size() < 3 && q <= you.inv[i].quantity; ++q)
868 runes.push_back(i);
873 return num_runes;
876 void down_stairs(dungeon_feature_type force_stair,
877 entry_cause_type entry_cause, const level_id* force_dest)
879 const level_id old_level = level_id::current();
880 const dungeon_feature_type old_feat = grd(you.pos());
881 const dungeon_feature_type stair_find =
882 force_stair? force_stair : old_feat;
884 const bool shaft = (!force_stair
885 && get_trap_type(you.pos()) == TRAP_SHAFT
886 || force_stair == DNGN_TRAP_NATURAL);
887 level_id shaft_dest;
888 int shaft_level = -1;
890 // Up and down both work for shops.
891 if (stair_find == DNGN_ENTER_SHOP)
893 shop();
894 return;
897 // Up and down both work for portals.
898 if (feat_is_bidirectional_portal(stair_find))
900 if (stair_find == DNGN_ENTER_HELL && player_in_hell()) {
901 up_stairs(force_stair, entry_cause);
902 return;
905 // Probably still need this check here (teleportation) -- bwr
906 else if (feat_stair_direction(stair_find) != CMD_GO_DOWNSTAIRS && !shaft)
908 if (stair_find == DNGN_STONE_ARCH)
909 mpr("There is nothing on the other side of the stone arch.");
910 else if (stair_find == DNGN_ABANDONED_SHOP)
911 mpr("This shop appears to be closed.");
912 else
913 mpr("You can't go down here!");
914 return;
917 if (stair_find == DNGN_ENTER_HELL && you.level_type != LEVEL_DUNGEON)
919 mpr("You can't enter Hell from outside the dungeon!",
920 MSGCH_ERROR);
921 return;
924 if (stair_find > DNGN_ENTER_LABYRINTH
925 && stair_find <= DNGN_ESCAPE_HATCH_DOWN
926 && player_in_branch(BRANCH_VESTIBULE_OF_HELL))
928 // Down stairs in vestibule are one-way!
929 // This doesn't make any sense. Why would there be any down stairs
930 // in the Vestibule? {due, 9/2010}
931 mpr("A mysterious force prevents you from descending the staircase.");
932 return;
935 if (stair_find == DNGN_STONE_ARCH)
937 mpr("There is nothing on the other side of the stone arch.");
938 return;
941 if (!force_stair && you.flight_mode() == FL_LEVITATE
942 && !feat_is_gate(stair_find))
944 mpr("You're floating high up above the floor!");
945 learned_something_new(HINT_LEVITATING);
946 return;
949 if (_stair_moves_pre(stair_find))
950 return;
952 if (shaft)
954 const bool known_trap = (grd(you.pos()) != DNGN_UNDISCOVERED_TRAP
955 && !force_stair);
957 if (you.flight_mode() == FL_LEVITATE && !force_stair)
959 if (known_trap)
960 mpr("You can't fall through a shaft while levitating.");
961 return;
964 if (!is_valid_shaft_level())
966 if (known_trap)
967 mpr("The shaft disappears in a puff of logic!");
968 _maybe_destroy_trap(you.pos());
969 return;
972 shaft_dest = you.shaft_dest(known_trap);
973 if (shaft_dest == level_id::current())
975 if (known_trap)
977 mpr("Strange, the shaft seems to lead back to this level.");
978 mpr("The strain on the space-time continuum destroys the "
979 "shaft!");
981 _maybe_destroy_trap(you.pos());
982 return;
984 shaft_level = absdungeon_depth(shaft_dest.branch, shaft_dest.depth);
986 if (!known_trap && shaft_level - you.absdepth0 > 1)
987 mark_milestone("shaft", "fell down a shaft to " +
988 short_place_name(shaft_dest) + ".");
990 if (you.flight_mode() != FL_FLY || force_stair)
991 mpr("You fall through a shaft!");
992 if (you.flight_mode() == FL_FLY && !force_stair)
993 mpr("You dive down through the shaft.");
995 // Shafts are one-time-use.
996 mpr("The shaft crumbles and collapses.");
997 _maybe_destroy_trap(you.pos());
1000 if (stair_find == DNGN_ENTER_ZOT && !you.opened_zot)
1002 std::vector<int> runes;
1003 const int num_runes = runes_in_pack(runes);
1005 if (num_runes < NUMBER_OF_RUNES_NEEDED)
1007 switch (NUMBER_OF_RUNES_NEEDED)
1009 case 1:
1010 mpr("You need a rune to enter this place.");
1011 break;
1013 default:
1014 mprf("You need at least %d runes to enter this place.",
1015 NUMBER_OF_RUNES_NEEDED);
1017 return;
1020 ASSERT(runes.size() >= 3);
1022 mprf("You insert %s into the lock.",
1023 you.inv[runes[0]].name(DESC_NOCAP_THE).c_str());
1024 #ifdef USE_TILE
1025 tiles.add_overlay(you.pos(), tileidx_zap(GREEN));
1026 update_screen();
1027 #else
1028 flash_view(LIGHTGREEN);
1029 #endif
1030 mpr("The lock glows an eerie green colour!");
1031 more();
1033 mprf("You insert %s into the lock.",
1034 you.inv[runes[1]].name(DESC_NOCAP_THE).c_str());
1035 big_cloud(CLOUD_BLUE_SMOKE, &you, you.pos(), 20, 7 + random2(7));
1036 viewwindow();
1037 mpr("Heavy smoke blows from the lock!");
1038 more();
1040 mprf("You insert %s into the lock.",
1041 you.inv[runes[2]].name(DESC_NOCAP_THE).c_str());
1043 if (silenced(you.pos()))
1044 mpr("The gate opens wide!");
1045 else
1046 mpr("With a loud hiss the gate opens wide!");
1047 more();
1049 you.opened_zot = true;
1052 // Bail if any markers veto the move.
1053 if (_marker_vetoes_level_change())
1054 return;
1056 level_id destination_override = _stair_destination_override();
1057 if (force_dest)
1058 destination_override = *force_dest;
1060 // All checks are done, the player is on the move now.
1062 // Magical level changes (Portal, Banishment) need this.
1063 clear_trapping_net();
1065 // Fire level-leaving trigger.
1066 _leaving_level_now();
1068 if (!force_stair && !crawl_state.game_is_arena())
1070 // Not entirely accurate - the player could die before
1071 // reaching the Abyss.
1072 if (grd(you.pos()) == DNGN_ENTER_ABYSS)
1073 mark_milestone("abyss.enter", "entered the Abyss!");
1074 else if (grd(you.pos()) == DNGN_EXIT_ABYSS
1075 && you.char_direction != GDT_GAME_START)
1077 mark_milestone("abyss.exit", "escaped from the Abyss!");
1081 // Interlevel travel data.
1082 const bool collect_travel_data = can_travel_interlevel();
1083 if (collect_travel_data)
1085 LevelInfo &old_level_info = travel_cache.get_level_info(old_level);
1086 old_level_info.update();
1088 const coord_def stair_pos = you.pos();
1090 // Preserve abyss uniques now, since this Abyss level will be deleted.
1091 if (you.level_type == LEVEL_ABYSS)
1092 save_abyss_uniques();
1094 // XXX: Obsolete, now that labyrinth entrances are only placed via Lua
1095 // with timed markes. Leaving in to reduce the chance of an
1096 // accidental permanent labyrinth entry. [rob]
1097 if (stair_find == DNGN_ENTER_LABYRINTH)
1098 dungeon_terrain_changed(you.pos(), DNGN_STONE_ARCH);
1100 if (stair_find == DNGN_ENTER_LABYRINTH
1101 || stair_find == DNGN_ENTER_PORTAL_VAULT)
1103 _mark_portal_return_point(you.pos());
1106 const int shaft_depth = (shaft ? shaft_level - you.absdepth0 : 1);
1107 _player_change_level_reset();
1108 _player_change_level_downstairs(stair_find, destination_override, shaft,
1109 shaft_level, shaft_dest);
1111 // When going downstairs into a special level, delete any previous
1112 // instances of it.
1113 if (you.level_type != LEVEL_DUNGEON)
1115 std::string lname = level_id::current().describe();
1116 #ifdef DEBUG_DIAGNOSTICS
1117 mprf(MSGCH_DIAGNOSTICS, "Deleting: %s", lname.c_str());
1118 #endif
1119 you.save->delete_chunk(lname);
1122 // Did we enter a new branch.
1123 const bool entered_branch(
1124 you.where_are_you != old_level.branch
1125 && branches[you.where_are_you].parent_branch == old_level.branch);
1127 if (stair_find == DNGN_EXIT_ABYSS || stair_find == DNGN_EXIT_PANDEMONIUM)
1129 mpr("You pass through the gate.");
1130 if (!you.wizard || !crawl_state.is_replaying_keys())
1131 more();
1134 if (old_level.level_type != you.level_type && you.level_type == LEVEL_DUNGEON)
1135 mprf("Welcome back to %s!", branches[you.where_are_you].longname);
1137 if (!you.airborne()
1138 && you.confused()
1139 && !feat_is_escape_hatch(stair_find)
1140 && force_stair != DNGN_ENTER_ABYSS
1141 && coinflip())
1143 const char* fall_where = "down the stairs";
1144 if (!feat_is_staircase(stair_find))
1145 fall_where = "through the gate";
1147 mprf("In your confused state, you trip and fall %s.", fall_where);
1148 // Note that this only does damage; it doesn't cancel the level
1149 // transition.
1150 if (!feat_is_staircase(stair_find))
1151 ouch(1, NON_MONSTER, KILLED_BY_FALLING_THROUGH_GATE);
1152 else
1153 ouch(1, NON_MONSTER, KILLED_BY_FALLING_DOWN_STAIRS);
1156 dungeon_feature_type stair_taken = stair_find;
1158 if (you.level_type == LEVEL_ABYSS)
1159 stair_taken = DNGN_FLOOR;
1161 if (you.level_type == LEVEL_PANDEMONIUM)
1162 stair_taken = DNGN_TRANSIT_PANDEMONIUM;
1164 if (shaft)
1165 stair_taken = DNGN_ESCAPE_HATCH_DOWN;
1167 switch (you.level_type)
1169 case LEVEL_LABYRINTH:
1170 // XXX: Ideally, we want to hint at the wall rule (rock > metal),
1171 // and that the walls can shift occasionally.
1172 // Are these too long?
1173 mpr("As you enter the labyrinth, previously moving walls settle noisily into place.");
1174 mpr("You hear the metallic echo of a distant snort before it fades into the rock.");
1175 mark_milestone("br.enter", "entered a Labyrinth.");
1176 break;
1178 case LEVEL_ABYSS:
1179 if (!force_stair)
1180 mpr("You enter the Abyss!");
1182 mpr("To return, you must find a gate leading back.");
1183 if (you.religion == GOD_CHEIBRIADOS)
1185 mpr("You feel Cheibriados slowing down the madness of this place.",
1186 MSGCH_GOD, GOD_CHEIBRIADOS);
1188 learned_something_new(HINT_ABYSS);
1189 break;
1191 case LEVEL_PANDEMONIUM:
1192 if (old_level.level_type == LEVEL_PANDEMONIUM)
1193 mpr("You pass into a different region of Pandemonium.");
1194 else
1196 mpr("You enter the halls of Pandemonium!");
1197 mpr("To return, you must find a gate leading back.");
1199 break;
1201 default:
1202 if (shaft)
1203 handle_items_on_shaft(you.pos(), false);
1204 else
1205 _climb_message(stair_find, false, old_level.level_type);
1206 break;
1209 if (!shaft)
1210 _exit_stair_message(stair_find, false);
1212 if (entered_branch)
1214 if (branches[you.where_are_you].entry_message)
1215 mpr(branches[you.where_are_you].entry_message);
1216 else
1217 mprf("Welcome to %s!", branches[you.where_are_you].longname);
1220 if (stair_find == DNGN_ENTER_HELL)
1222 mpr("Welcome to Hell!");
1223 mpr("Please enjoy your stay.");
1225 // Kill -more- prompt if we're traveling.
1226 if (!you.running && !force_stair)
1227 more();
1230 const bool newlevel = load(stair_taken, LOAD_ENTER_LEVEL, old_level);
1232 _set_entry_cause(entry_cause, old_level.level_type);
1233 entry_cause = you.entry_cause;
1235 if (newlevel)
1237 // When entering a new level, reset friendly_pickup to default.
1238 you.friendly_pickup = Options.default_friendly_pickup;
1240 switch (you.level_type)
1242 case LEVEL_DUNGEON:
1243 // Xom thinks it's funny if you enter a new level via shaft
1244 // or escape hatch, for shafts it's funnier the deeper you fell.
1245 if (shaft || feat_is_escape_hatch(stair_find))
1246 xom_is_stimulated(shaft_depth * 50);
1247 else
1248 xom_is_stimulated(14);
1249 break;
1251 case LEVEL_PORTAL_VAULT:
1252 // Portal vaults aren't as interesting.
1253 xom_is_stimulated(25);
1254 break;
1256 case LEVEL_LABYRINTH:
1257 // Finding the way out of a labyrinth interests Xom,
1258 // but less so for Minotaurs. (though not now, as they cannot
1259 // map the labyrinth any more {due})
1260 xom_is_stimulated(98);
1261 break;
1263 case LEVEL_ABYSS:
1264 case LEVEL_PANDEMONIUM:
1266 // Paranoia
1267 if (old_level.level_type == you.level_type)
1268 break;
1270 PlaceInfo &place_info = you.get_place_info();
1271 generate_random_blood_spatter_on_level();
1273 // Entering voluntarily only stimulates Xom if you've never
1274 // been there before
1275 if ((place_info.num_visits == 1 && place_info.levels_seen == 1)
1276 || entry_cause != EC_SELF_EXPLICIT)
1278 if (crawl_state.is_god_acting())
1279 xom_is_stimulated(255);
1280 else if (entry_cause == EC_SELF_EXPLICIT)
1282 // Entering Pandemonium or the Abyss for the first
1283 // time *voluntarily* stimulates Xom much more than
1284 // entering a normal dungeon level for the first time.
1285 xom_is_stimulated(128, XM_INTRIGUED);
1287 else if (entry_cause == EC_SELF_RISKY)
1288 xom_is_stimulated(128);
1289 else
1290 xom_is_stimulated(255);
1293 break;
1296 default:
1297 die("unknown level type");
1301 switch (you.level_type)
1303 case LEVEL_ABYSS:
1304 grd(you.pos()) = DNGN_FLOOR;
1306 init_pandemonium(); // colours only
1307 break;
1309 case LEVEL_PANDEMONIUM:
1310 init_pandemonium();
1312 for (int pc = random2avg(28, 3); pc > 0; pc--)
1313 pandemonium_mons();
1314 break;
1316 default:
1317 break;
1320 you.turn_is_over = true;
1322 save_game_state();
1324 new_level();
1326 moveto_location_effects(old_feat);
1328 // Clear list of beholding monsters.
1329 you.clear_beholders();
1330 you.clear_fearmongers();
1332 if (!allow_control_teleport(true))
1333 mpr("You sense a powerful magical force warping space.", MSGCH_WARN);
1335 trackers_init_new_level(true);
1337 // XXX: Using force_dest to decide whether to save stair info.
1338 // Currently it's only used for Portal, where we don't
1339 // want to mark the destination known.
1340 if (!force_dest)
1341 _update_travel_cache(collect_travel_data, old_level, stair_pos);
1343 env.map_shadow = env.map_knowledge;
1344 // Preventing obvious finding of stairs at your position.
1345 env.map_shadow(you.pos()).flags |= MAP_SEEN_FLAG;
1347 viewwindow();
1349 // Checking new squares for interesting features.
1350 if (!you.running)
1351 check_for_interesting_features();
1353 maybe_update_stashes();
1355 request_autopickup();
1357 // Zotdef: returning from portals (e.g. bazaar) paralyses the player in
1358 // place for 5 moves. Nasty, but punishes players for using portals as
1359 // quick-healing stopovers.
1360 if (crawl_state.game_is_zotdef())
1361 start_delay(DELAY_UNINTERRUPTIBLE, 5);
1365 void new_level(bool restore)
1367 print_stats_level();
1368 #ifdef DGL_WHEREIS
1369 whereis_record();
1370 #endif
1372 if (restore)
1373 return;
1375 cancel_tornado();
1377 if (you.level_type == LEVEL_PORTAL_VAULT)
1379 // This here because place_name can't find the name of a level that you
1380 // *are no longer on* when it spits out the new notes list.
1381 std::string desc = "Entered " + place_name(get_packed_place(), true, true);
1382 take_note(Note(NOTE_DUNGEON_LEVEL_CHANGE, 0, 0, NULL,
1383 desc.c_str()));
1385 else
1386 take_note(Note(NOTE_DUNGEON_LEVEL_CHANGE));
1389 // Returns a hatch or stair (up or down)
1390 dungeon_feature_type random_stair()
1392 return (static_cast<dungeon_feature_type>(
1393 DNGN_STONE_STAIRS_DOWN_I+random2(
1394 DNGN_ESCAPE_HATCH_UP-DNGN_STONE_STAIRS_DOWN_I+1)));