Cleaned up up_stairs() and down_stairs() to remove spurious depth changes when changing you.level_type - depth (you.your_level) now changes only for stairs with both ends in LEVEL_DUNGEON.
All levels are now saved on exit, including non LEVEL_DUNGEON levels. Re-entering non-dungeon levels from down_stairs will still delete the old level. Re-entering non-dungeon levels from up_stairs (i.e. returning to a non-dungeon level from some other place, like a ziggurat) will reload the old level.
Fixed bogus marker trashing when player attempts to use a Zot entrance with insufficient runes.
Delete .msg files when game ends.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7598 c06c8d41-db1a-0410-9941-cceddc491573
KSM4H3SBM6FIQTUEGHXXYATJXEOJ4EKUBAFCRMFKSHY7N2HWECRQC S4RG6BEPNGMZELQ3HDRLX6XI5Y4FYLZME5FVO76WNRN4J52IAZRQC 7G2RWMLC5YBT3W7DNXDGEA4SMTI524RJIH3VO7MOQYGBMQHML2MAC CI2RMLJLIAZMEGNN6LJN6PSHXHLPG7PXFIDYRGFPVMDPJ2R4S4NQC CM2YC5KBTUB4JFT3CL3NRS7V5X76M7RI7SNT4XK6IOVBZA2URRKAC CPBVQFT7NWEYLYD34D5VYZIEOZ32YADXYTSFMS635YNXX4OFIZVAC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC 4N5PW5S3OV25HFN634NNWMMYX26NA2TB6TVFG4UMYSZ2VBJWKE4QC DKRSOHZXL6EPSLKOKHF7GJXSZEJVY7CXGACSHWLM5B5FTRETWWCAC T4IH76FA5TWHFOZUJFHLQXQJENJHWTUZZP4EGNA7D4GTZY7D4ZKAC 6HG6JFO47Y3BZLU7Y6G3R2CX6JFGN4X5PKK6S5IGUXUYQ5GVZYFQC RISMOCQM6BKK4XSIRKYLOBB2UPDYJNDAL6OGIIR5GGNZQAK5YSZAC ZVK4J5HTKFNOOIVCI62ZWEYGXEE5TYJ65DLYYZAZWTADFSXE62ZAC ANBVGN4RZOMY5LI4QSHOV2477FN55H353ZYLSVCPTXC7AWWSQZBAC 5ASC3STDYCNLZFEBN6UTMUCGDETHBR2OCBZCF5VIAZ5RRWLOTDYQC WX2VFNANQZ3IRHBXSLKJT3G3OAQREAZISXLOTG6JO7KXFBHQFOYAC NKONHW4JNY6HP2M63MNPM3H64ZWSUNUT5FX2STW4KTS4AMXJXXVQC G3UKWY6JNG2ZQO6R2UTAAIQ3ECJIGEKEHTKOJNL5EN4YBC7U44KQC 7KWDC7XFNMBLSUO2HISIROBINZBX5T67LJEEXTAORXW2YZ7VWFGAC Q2AYZGR7UBWG4CKVR6PJQD3UHDEBMAFBQ5PZLHT64CTREG3JYFZAC T6TL6NTIOBYNUIONGK3JFZJ5ONWV6S4CTIRDC5JMKMCBGG5IY3EAC WF2DSJGR6PKLGQSXEFF4ZW4EZZFGMHXPXWUYAKYBPFJH6KJKAANQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC 5UVDIVD4NSXA52U4QMQIVST3GSZJ2A2YZK3RUEXKPM43YVQ7LI5AC WQLOHSNCA3VOMDJF6IINJYKSYVYZEBPJJWBB33QSNE4RP5HEXPMAC 6L4EP4ZRWWYLT55PD5KTTJON5J2JB5VV5MWNHF5VPZQZ5BKEYZ4QC T7CUIVICB74342RA32BR37T36FOX4RBSQIB5PNOHTGTGUYGDKSTQC ED62QWGKBPORWVKDFOQRKJXEIWZVNGR3O4KWQBDSRNPT36AYOQYAC DOZORMA366M4HB5JKSS27BMCR6ET7QNZNND2B7KV3NVEEPR5H7EAC NVSFIV2ZKP44XHCSCXG6OZVGL67OIFINC34J2EMKTA4KULCERUEAC FMKQARDH6JZ7DUTPPQ6I3LLNQAFGXS36XJCSROUJMEIYQYJDVITQC W5VEC2PBIM5DMU5233HOWAZUEPTGWJRZZIA3H35YYQQW6BTP6XUAC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC 74LQ7JXVLAFSHLI7LCBKFX47CNTYSKGUQSXNX5FCIUIGCC2JTR3QC 6LT6USGJOTDMRJGXLAN2NSZXK2GKWEXDKKUV6SVV7ZC6WI6EKMDQC VXSORUQOM2VZA4CAZDC6KPAY373NQIN3UT7CXQXTRCYXO2WM62DAC O6SX3NYKNE2YSFLFOXGJQGL7SMVDFQYDQG6OR6MUEPVQKBRI45XQC M27JU3PI7UXV4S4LTHOCGVASHX2RBXL5ZU4MLFWCQCSMGQC53IAAC AVCMVFA3MKCXHO6H44UK5KJNIHTGQV7UA7GYXM26VI6TXXU5ZN6QC 3CY6KJWHQUZFZGO2C7VVCO32RRHUIMQQQJAE2MUXFF45F7ECRLJQC F4WAQJD7KLOXHZOTOT6WG26PVIDHYNVS3AV6ZNXGAS7PDR4HBWQAC 6GSGCC5JQJ5NOKX36UHRNOCXNHDBS2A2TDMAR34UBOGWE2DORXIQC TO43FWKHNIA5MVDOFXYHQODTLBQYEZKX5UIUGID57436UF7G2EXQC GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC JM7UAK777RAVDAVLQLEOBRTGNW2B47S5G55XITJXO243IUNZHVYQC SBTVKHKZRMVDBYLGQNMZMJXPAYJG43UWBBD7HQJWIPN3BMMHUBJAC NXIVXEHVXS22UDSQL4KZQ4VHK3XTW7DAGA5LLL3EXY5MHPIUXL7AC 5BJPWUPLJFS34FUTFJVKA4A52YMIGV6EWDXLNSDCWBJWBGVSQFGQC ZBPS5ZTPF3DVTR5WET4XEFHYXU26CRHU2OHX3YO6PD4MTM2DUXAQC CK7CT5TUFUL2AQY7FUHB5JI3FC2KSPWUWHXC6VEUJJ7G4OWUQFTAC 7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC BPSH3LUDUTXMK2QZKSMFDTBNDD6HPILMCBLZNMCRLZZQKPS5QOQQC XKQ2XYVSHYRTEKIYXFLXCPULEEO6IQUSKQHX32UZGNMAMQN2CTMQC 4C6O4H7IO3LDZPBDGRST3QUFKMNQRB4Y6JXUV3NKIJVVPLAA2AWQC AXB2FZCJPA5YETYDCAEQ7ZS5HBT2KAS4NBVUVWKH5TQJI2O2DMVQC RWSXCNYUGDSMP2GKN22HROC5Q2GHSAVJJUDRT3Z53WU2DAI4IZOQC DDU4A3JGN5IUIPP5IASOODKPR2WBHSDSV4FITZ6HNXNSXXQACWAQC X7MFMKQTNZ2IWBFVGS6WQV7NRNKJ3DWQAW2X7IQMFQQXW24AHPZQC IVVRQ52VA3MAD25ZMPID3GCRBBFYR54CH33DKXYTRAGUBLTRAZNAC TLO257LZSB6ZO36STDUEWJBO2LETXFKTFGXELA6Y4BZBVAEIIINAC OYYZVCE3QHBVJM6IEKK5HTJRG5YOVQNCBRMSJENTHOI2WPJLNCFAC AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC C55G5JGGSVWMU7XVEJL6YZZLDXQZGRN7JQOAALS6WIKFPX3L2U6QC PDOFPXD2X6VI23AHKCGQ5RVDBG74CNP2E3YOHKXLOARHHBXEK3HQC 5B5DP5S6A6LQMKZYVLQAEMHQZWFWYDHPCKQGRNSCNNYIBQYZ6BIQC SW3RLYFNRT3IJBK6LYKHKP2J2YDU7SXQWAJZX7U6S7ICYW43OMNQC PJ7HBIWAV3H23LXGZAAD2QYJ7HMOFOIR5ZJ4U2UTHI766LOTRRWQC YF2GZWXNV6NVFFEBEOYS67JQJQK2IUS5BZMGJW3XQPYIJYHQJCEQC ASLW3Z5PAVZSWJEMMMVZT226P44EKSAD47QS72JIFJESAI3RPN3AC // Identifies a level. Should never include virtual methods or// dynamically allocated memory (see code to push level_id onto Lua// stack in luadgn.cc)class level_id{public:branch_type branch; // The branch in which the level is.int depth; // What depth (in this branch - starting from 1)level_area_type level_type;public:// Returns the level_id of the current level.static level_id current();
level_id(): branch(BRANCH_MAIN_DUNGEON), depth(-1),level_type(LEVEL_DUNGEON){}level_id(branch_type br, int dep, level_area_type ltype = LEVEL_DUNGEON): branch(br), depth(dep), level_type(ltype){}level_id(const level_id &ot): branch(ot.branch), depth(ot.depth), level_type(ot.level_type){}level_id(level_area_type ltype): branch(BRANCH_MAIN_DUNGEON), depth(-1), level_type(ltype){}static level_id parse_level_id(const std::string &s) throw (std::string);unsigned short packed_place() const;std::string describe(bool long_name = false, bool with_number = true) const;void clear(){branch = BRANCH_MAIN_DUNGEON;depth = -1;level_type = LEVEL_DUNGEON;}int absdepth() const;bool is_valid() const{return (branch != NUM_BRANCHES && depth != -1)|| level_type != LEVEL_DUNGEON;}const level_id &operator = (const level_id &id){branch = id.branch;depth = id.depth;level_type = id.level_type;return (*this);}bool operator == ( const level_id &id ) const{return (level_type == id.level_type&& (level_type != LEVEL_DUNGEON|| (branch == id.branch && depth == id.depth)));}bool operator != ( const level_id &id ) const{return !operator == (id);}bool operator <( const level_id &id ) const{if (level_type != id.level_type)return (level_type < id.level_type);if (level_type != LEVEL_DUNGEON)return (false);return (branch < id.branch) || (branch==id.branch && depth < id.depth);}bool operator == ( const branch_type _branch ) const{return (branch == _branch && level_type == LEVEL_DUNGEON);}bool operator != ( const branch_type _branch ) const{return !operator == (_branch);}void save(writer&) const;void load(reader&);};
marshallShort(th, MAX_LEVELS);for (i = 0; i < MAX_LEVELS; ++i)for (j = 0; j < NUM_BRANCHES; ++j)marshallBoolean(th, tmp_file_pairs[i][j]);
marshallSet(th, Generated_Levels, marshall_level_id);
count_s = unmarshallShort(th);for (i = 0; i < count_s; ++i)for (j = 0; j < count_c; ++j)tmp_file_pairs[i][j] = unmarshallBoolean(th);
unmarshallSet(th, Generated_Levels, unmarshall_level_id);
for (int dungeon = 0; dungeon < NUM_BRANCHES; dungeon++){if (tmp_file_pairs[level][dungeon]){unlink(make_filename( you.your_name, level,static_cast<branch_type>(dungeon),LEVEL_DUNGEON, false ).c_str() );}}
const level_id &place(*i);unlink(make_filename( you.your_name,place.absdepth(),place.branch,place.level_type,false ).c_str() );
}static void _player_change_level_reset(){you.prev_targ = MHITNOT;if (you.pet_target != MHITYOU)you.pet_target = MHITNOT;you.prev_grd_targ = coord_def(0, 0);}static level_id _stair_destination_override(){const std::string force_place =env.markers.property_at(you.pos(), MAT_ANY, "dstplace");if (!force_place.empty()){try{const level_id place = level_id::parse_level_id(force_place);return (place);}catch (const std::string &err){end(1, false, "Marker set with invalid level name: %s",force_place.c_str());}}const level_id invalid;return (invalid);}static bool _stair_force_destination(const level_id &override){if (override.is_valid()){if (override.level_type == LEVEL_DUNGEON){you.where_are_you = override.branch;you.your_level = override.absdepth();you.level_type = override.level_type;}else{you.level_type = override.level_type;}return (true);}return (false);}static void _player_change_level_upstairs(dungeon_feature_type stair_find,const level_id &place_override){if (_stair_force_destination(place_override))return;if (you.level_type == LEVEL_DUNGEON)you.your_level--;// Make sure we return to our main dungeon level... labyrinth entrances// in the abyss or pandemonium are a bit trouble (well the labyrinth does// provide a way out of those places, its really not that bad I suppose).if (level_type_exits_up(you.level_type))you.level_type = LEVEL_DUNGEON;if (player_in_branch( BRANCH_VESTIBULE_OF_HELL )){you.where_are_you = BRANCH_MAIN_DUNGEON;you.your_level = you.hell_exit;}if (player_in_hell()){you.where_are_you = BRANCH_VESTIBULE_OF_HELL;you.your_level = 27;}// Did we take a branch stair?for (int i = 0; i < NUM_BRANCHES; ++i){if (branches[i].exit_stairs == stair_find&& you.where_are_you == i){you.where_are_you = branches[i].parent_branch;// If leaving a branch which wasn't generated in this// particular game (like the Swamp or Shoals), then// its startdepth is set to -1; compensate for that,// so we don't end up on "level -1".if (branches[i].startdepth == -1)you.your_level += 2;break;}}
// Make sure we return to our main dungeon level... labyrinth entrances// in the abyss or pandemonium are a bit trouble (well the labyrinth does// provide a way out of those places, its really not that bad I suppose).if (level_type_exits_up(you.level_type))you.level_type = LEVEL_DUNGEON;
_player_change_level_reset();_player_change_level_upstairs(stair_find, destination_override);
you.prev_grd_targ = coord_def(0, 0);if (player_in_branch( BRANCH_VESTIBULE_OF_HELL ))
if (old_level_id.branch == BRANCH_VESTIBULE_OF_HELL&& !player_in_branch( BRANCH_VESTIBULE_OF_HELL ))
you.where_are_you = branches[i].parent_branch;// If leaving a branch which wasn't generated in this// particular game (like the Swamp or Shoals), then// its startdepth is set to -1; compensate for that,// so we don't end up on "level -1".if (branches[i].startdepth == -1)you.your_level += 2;
case BRANCH_COCYTUS:stair_find = DNGN_ENTER_COCYTUS;break;case BRANCH_DIS:stair_find = DNGN_ENTER_DIS;break;case BRANCH_GEHENNA:stair_find = DNGN_ENTER_GEHENNA;break;case BRANCH_TARTARUS:stair_find = DNGN_ENTER_TARTARUS;break;default:
// All changes to you.level_type, you.where_are_you and you.your_level// for descending stairs should happen here.static void _player_change_level_downstairs(dungeon_feature_type stair_find,const level_id &place_override,bool shaft,int shaft_level,const level_id &shaft_dest){if (_stair_force_destination(place_override))return;const level_area_type original_level_type(you.level_type);if (you.level_type != LEVEL_DUNGEON&& (you.level_type != LEVEL_PANDEMONIUM|| stair_find != DNGN_TRANSIT_PANDEMONIUM)&& (you.level_type != LEVEL_PORTAL_VAULT|| !grid_is_stone_stair(stair_find))){you.level_type = LEVEL_DUNGEON;}if (stair_find == DNGN_ENTER_HELL){you.where_are_you = BRANCH_VESTIBULE_OF_HELL;you.hell_exit = you.your_level;you.your_level = 26;}// Welcome message.// Try to find a branch stair.for (int i = 0; i < NUM_BRANCHES; ++i){if (branches[i].entry_stairs == stair_find){you.where_are_you = branches[i].id;break;}}if (stair_find == DNGN_ENTER_LABYRINTH)you.level_type = LEVEL_LABYRINTH;else if (stair_find == DNGN_ENTER_ABYSS)you.level_type = LEVEL_ABYSS;else if (stair_find == DNGN_ENTER_PANDEMONIUM)you.level_type = LEVEL_PANDEMONIUM;else if (stair_find == DNGN_ENTER_PORTAL_VAULT)you.level_type = LEVEL_PORTAL_VAULT;if (shaft){you.your_level = shaft_level;you.where_are_you = shaft_dest.branch;}else if (original_level_type == LEVEL_DUNGEON&& you.level_type == LEVEL_DUNGEON){you.your_level++;}}
// All checks are done, the player is on the move now.// Fire level-leaving trigger.leaving_level_now();#ifdef DGL_MILESTONESif (!force_stair){// Not entirely accurate - the player could die before// reaching the Abyss.if (grd(you.pos()) == DNGN_ENTER_ABYSS)mark_milestone("abyss.enter", "entered the Abyss!");else if (grd(you.pos()) == DNGN_EXIT_ABYSS&& you.char_direction != GDT_GAME_START){mark_milestone("abyss.exit", "escaped from the Abyss!");}}#endif// [ds] Descending into the Labyrinth increments your_level. Going// downstairs from a labyrinth implies that you've been banished (or been// sent to Pandemonium somehow). Decrementing your_level here is needed// to fix this buggy sequence: D:n -> Labyrinth -> Abyss -> D:(n+1).if (level_type_exits_up(you.level_type))you.your_level--;
const level_id destination_override(_stair_destination_override());// All checks are done, the player is on the move now.// Fire level-leaving trigger.leaving_level_now();#ifdef DGL_MILESTONESif (!force_stair){// Not entirely accurate - the player could die before// reaching the Abyss.if (grd(you.pos()) == DNGN_ENTER_ABYSS)mark_milestone("abyss.enter", "entered the Abyss!");else if (grd(you.pos()) == DNGN_EXIT_ABYSS&& you.char_direction != GDT_GAME_START){mark_milestone("abyss.exit", "escaped from the Abyss!");}}#endif
if (you.level_type != LEVEL_DUNGEON&& (you.level_type != LEVEL_PANDEMONIUM|| stair_find != DNGN_TRANSIT_PANDEMONIUM)&& (you.level_type != LEVEL_PORTAL_VAULT|| !grid_is_stone_stair(stair_find))){you.level_type = LEVEL_DUNGEON;}you.prev_targ = MHITNOT;if (you.pet_target != MHITYOU)you.pet_target = MHITNOT;you.prev_grd_targ = coord_def(0, 0);if (stair_find == DNGN_ENTER_HELL){you.where_are_you = BRANCH_VESTIBULE_OF_HELL;you.hell_exit = you.your_level;you.your_level = 26;}// Welcome message.// Try to find a branch stair.bool entered_branch = false;for (i = 0; i < NUM_BRANCHES; ++i){if (branches[i].entry_stairs == stair_find){entered_branch = true;you.where_are_you = branches[i].id;break;}}
if (stair_find == DNGN_ENTER_LABYRINTH)you.level_type = LEVEL_LABYRINTH;else if (stair_find == DNGN_ENTER_ABYSS)you.level_type = LEVEL_ABYSS;else if (stair_find == DNGN_ENTER_PANDEMONIUM)you.level_type = LEVEL_PANDEMONIUM;else if (stair_find == DNGN_ENTER_PORTAL_VAULT)you.level_type = LEVEL_PORTAL_VAULT;
_player_change_level_reset();_player_change_level_downstairs(stair_find, destination_override, shaft,shaft_level, shaft_dest);
if (shaft){you.your_level = shaft_level;you.where_are_you = shaft_dest.branch;}else if (level_type_exits_up(you.level_type))you.your_level++;else if (level_type_exits_down(you.level_type)&& !level_type_exits_down(old_level_type)){you.your_level--;}
if (you.level_type == LEVEL_DUNGEON&& old_branch == BRANCH_VESTIBULE_OF_HELL&& stair_taken == DNGN_STONE_STAIRS_UP_I)
if (stair_taken == DNGN_EXIT_PANDEMONIUM)
// Given a level in the dungeon (i.e. level_type == LEVEL_DUNGEON),// returns true if the level has been created already in this game.// Asserts if the level_type is not LEVEL_DUNGEON.
// Given a level returns true if the level has been created already// in this game.
// Identifies a level. Should never include virtual methods or// dynamically allocated memory (see code to push level_id onto Lua// stack in luadgn.cc)class level_id{public:branch_type branch; // The branch in which the level is.int depth; // What depth (in this branch - starting from 1)level_area_type level_type;public:// Returns the level_id of the current level.static level_id current();
level_id(): branch(BRANCH_MAIN_DUNGEON), depth(-1),level_type(LEVEL_DUNGEON){}level_id(branch_type br, int dep, level_area_type ltype = LEVEL_DUNGEON): branch(br), depth(dep), level_type(ltype){}level_id(const level_id &ot): branch(ot.branch), depth(ot.depth), level_type(ot.level_type){}level_id(level_area_type ltype): branch(BRANCH_MAIN_DUNGEON), depth(-1), level_type(ltype){}static level_id parse_level_id(const std::string &s) throw (std::string);unsigned short packed_place() const;std::string describe(bool long_name = false, bool with_number = true) const;void clear(){branch = BRANCH_MAIN_DUNGEON;depth = -1;level_type = LEVEL_DUNGEON;}int absdepth() const;bool is_valid() const{return (branch != NUM_BRANCHES && depth != -1)|| level_type != LEVEL_DUNGEON;}const level_id &operator = (const level_id &id){branch = id.branch;depth = id.depth;level_type = id.level_type;return (*this);}bool operator == ( const level_id &id ) const{return (level_type == id.level_type&& (level_type != LEVEL_DUNGEON|| (branch == id.branch && depth == id.depth)));}bool operator != ( const level_id &id ) const{return !operator == (id);}bool operator <( const level_id &id ) const{if (level_type != id.level_type)return (level_type < id.level_type);if (level_type != LEVEL_DUNGEON)return (false);return (branch < id.branch) || (branch==id.branch && depth < id.depth);}bool operator == ( const branch_type _branch ) const{return (branch == _branch && level_type == LEVEL_DUNGEON);}bool operator != ( const branch_type _branch ) const{return !operator == (_branch);}void save(writer&) const;void load(reader&);};