12 #include "dgn-overview.h"
31 #include "spl-clouds.h"
32 #include "spl-damage.h"
33 #include "spl-transloc.h"
37 #include "tagstring.h"
47 bool check_annotation_exclusion_warning()
49 // Players might not realise the implications of teleport mutations
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 "
56 if (!yesno("Continue anyway?", false, 'N', true, false))
59 interrupt_activity(AI_FORCE_INTERRUPT
);
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
),
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))
92 interrupt_activity(AI_FORCE_INTERRUPT
);
93 crawl_state
.level_annotation_shown
= false;
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
);
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
;
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
;
142 you
.level_type
= override
.level_type
;
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
))
155 if (you
.level_type
== LEVEL_DUNGEON
)
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
;
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)
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
)
205 if (stair
!= grd(you
.pos()))
208 if (feat_stair_direction(stair
) == CMD_NO_CMD
)
211 if (!you
.duration
[DUR_REPEL_STAIRS_CLIMB
])
215 if (you
.duration
[DUR_REPEL_STAIRS_MOVE
])
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);
225 if (!x_chance_in_y(pct
, 100))
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))
235 std::string verb
= stair_climb_verb(stair
);
237 mprf("%s moves away as you attempt to %s it!", stair_str
.c_str(),
240 you
.turn_is_over
= true;
245 static bool _check_carrying_orb()
247 // We never picked up the Orb, no problem.
248 if (you
.char_direction
!= GDT_ASCENDING
)
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
)
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
)
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
))
307 mpr("A mysterious force pulls you upwards.");
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");
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
)
344 static void _leaving_level_now()
346 // Note the name ahead of time because the events may cause markers
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
;
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
);
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
)
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
461 char letter
= you
.level_type_name
[0];
464 else if (is_vowel(letter
))
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
)
484 if (crawl_state
.is_god_acting())
486 if (crawl_state
.is_god_retribution())
487 you
.entry_cause
= EC_GOD_RETRIBUTION
;
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
;
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.
525 lp
.id
= new_level_id
;
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
);
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).
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
575 const level_id old_level
= level_id::current();
577 // Up and down both work for shops.
578 if (stair_find
== DNGN_ENTER_SHOP
)
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
);
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.");
600 mpr("You can't go up here.");
604 if (_stair_moves_pre(stair_find
))
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
612 && old_level
.level_type
== LEVEL_DUNGEON
613 && !feat_is_escape_hatch(stair_find
)
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
);
624 ouch(1, NON_MONSTER
, KILLED_BY_FALLING_DOWN_STAIRS
);
625 you
.turn_is_over
= true;
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;
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();
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,
658 mpr("Alright, then stay!");
663 // Bail if any markers veto the move.
664 if (_marker_vetoes_level_change())
667 // Magical level changes (don't exist yet in this direction)
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;
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.");
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;
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
;
758 // Checking new squares for interesting features.
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
,
790 const level_id
&shaft_dest
)
792 if (_stair_force_destination(place_override
))
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
;
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
;
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
;
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
)
847 static void _maybe_destroy_trap(const coord_def
&p
)
849 trap_def
* trap
= find_trap(p
);
854 int runes_in_pack(std::vector
<int> &runes
)
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
;
866 runes
.size() < 3 && q
<= you
.inv
[i
].quantity
; ++q
)
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
);
888 int shaft_level
= -1;
890 // Up and down both work for shops.
891 if (stair_find
== DNGN_ENTER_SHOP
)
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
);
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.");
913 mpr("You can't go down here!");
917 if (stair_find
== DNGN_ENTER_HELL
&& you
.level_type
!= LEVEL_DUNGEON
)
919 mpr("You can't enter Hell from outside the dungeon!",
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.");
935 if (stair_find
== DNGN_STONE_ARCH
)
937 mpr("There is nothing on the other side of the stone arch.");
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
);
949 if (_stair_moves_pre(stair_find
))
954 const bool known_trap
= (grd(you
.pos()) != DNGN_UNDISCOVERED_TRAP
957 if (you
.flight_mode() == FL_LEVITATE
&& !force_stair
)
960 mpr("You can't fall through a shaft while levitating.");
964 if (!is_valid_shaft_level())
967 mpr("The shaft disappears in a puff of logic!");
968 _maybe_destroy_trap(you
.pos());
972 shaft_dest
= you
.shaft_dest(known_trap
);
973 if (shaft_dest
== level_id::current())
977 mpr("Strange, the shaft seems to lead back to this level.");
978 mpr("The strain on the space-time continuum destroys the "
981 _maybe_destroy_trap(you
.pos());
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
)
1010 mpr("You need a rune to enter this place.");
1014 mprf("You need at least %d runes to enter this place.",
1015 NUMBER_OF_RUNES_NEEDED
);
1020 ASSERT(runes
.size() >= 3);
1022 mprf("You insert %s into the lock.",
1023 you
.inv
[runes
[0]].name(DESC_NOCAP_THE
).c_str());
1025 tiles
.add_overlay(you
.pos(), tileidx_zap(GREEN
));
1028 flash_view(LIGHTGREEN
);
1030 mpr("The lock glows an eerie green colour!");
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));
1037 mpr("Heavy smoke blows from the lock!");
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!");
1046 mpr("With a loud hiss the gate opens wide!");
1049 you
.opened_zot
= true;
1052 // Bail if any markers veto the move.
1053 if (_marker_vetoes_level_change())
1056 level_id destination_override
= _stair_destination_override();
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
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());
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())
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
);
1139 && !feat_is_escape_hatch(stair_find
)
1140 && force_stair
!= DNGN_ENTER_ABYSS
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
1150 if (!feat_is_staircase(stair_find
))
1151 ouch(1, NON_MONSTER
, KILLED_BY_FALLING_THROUGH_GATE
);
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
;
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.");
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
);
1191 case LEVEL_PANDEMONIUM
:
1192 if (old_level
.level_type
== LEVEL_PANDEMONIUM
)
1193 mpr("You pass into a different region of Pandemonium.");
1196 mpr("You enter the halls of Pandemonium!");
1197 mpr("To return, you must find a gate leading back.");
1203 handle_items_on_shaft(you
.pos(), false);
1205 _climb_message(stair_find
, false, old_level
.level_type
);
1210 _exit_stair_message(stair_find
, false);
1214 if (branches
[you
.where_are_you
].entry_message
)
1215 mpr(branches
[you
.where_are_you
].entry_message
);
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
)
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
;
1237 // When entering a new level, reset friendly_pickup to default.
1238 you
.friendly_pickup
= Options
.default_friendly_pickup
;
1240 switch (you
.level_type
)
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);
1248 xom_is_stimulated(14);
1251 case LEVEL_PORTAL_VAULT
:
1252 // Portal vaults aren't as interesting.
1253 xom_is_stimulated(25);
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);
1264 case LEVEL_PANDEMONIUM
:
1267 if (old_level
.level_type
== you
.level_type
)
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);
1290 xom_is_stimulated(255);
1297 die("unknown level type");
1301 switch (you
.level_type
)
1304 grd(you
.pos()) = DNGN_FLOOR
;
1306 init_pandemonium(); // colours only
1309 case LEVEL_PANDEMONIUM
:
1312 for (int pc
= random2avg(28, 3); pc
> 0; pc
--)
1320 you
.turn_is_over
= true;
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.
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
;
1349 // Checking new squares for interesting features.
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();
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
,
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)));