From c98e65d7c1e611743f82997954c259dedbe843b2 Mon Sep 17 00:00:00 2001 From: haranp Date: Sat, 1 Dec 2007 19:38:40 +0000 Subject: Added a function, apply_to_all_dungeons(), which basically acts as a Visitor for every dungeon level. The idea is to use this for galaxy-spanning effects, e.g. if you want to shuffle all the decks in existence or deconvert all the Beogh-converted orcs. Not well tested; might be buggy. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2960 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/files.cc | 109 ++++++++++++++++++++++++++++++++++++---------- crawl-ref/source/files.h | 10 +++-- crawl-ref/source/items.cc | 29 +++++------- crawl-ref/source/misc.cc | 5 +-- crawl-ref/source/view.cc | 4 +- 5 files changed, 107 insertions(+), 50 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index aa9cb3e425..bf82b47e10 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -888,13 +888,16 @@ static void do_lost_items(level_area_type old_level_type) } } -bool load( dungeon_feature_type stair_taken, int load_mode, +bool load( dungeon_feature_type stair_taken, load_mode_type load_mode, level_area_type old_level_type, char old_level, - branch_type where_were_you2 ) + branch_type old_branch ) { unwind_var stair( you.transit_stair, stair_taken, DNGN_UNSEEN); unwind_bool ylev(you.entering_level, true, false); + + const bool make_changes = + (load_mode != LOAD_RESTART_GAME && load_mode != LOAD_VISITOR); bool just_created_level = false; @@ -921,7 +924,7 @@ bool load( dungeon_feature_type stair_taken, int load_mode, // We clear twice - on save and on load. // Once would be enough... - if (load_mode != LOAD_RESTART_GAME) + if (make_changes) clear_clouds(); // Lose all listeners. @@ -933,10 +936,11 @@ bool load( dungeon_feature_type stair_taken, int load_mode, grab_followers(); if (old_level_type == LEVEL_DUNGEON) - save_level( old_level, LEVEL_DUNGEON, where_were_you2 ); + save_level( old_level, LEVEL_DUNGEON, old_branch ); } - do_lost_items(old_level_type); + if ( make_changes ) + do_lost_items(old_level_type); // Try to open level savefile. FILE *levelFile = fopen(cha_fil.c_str(), "rb"); @@ -944,6 +948,7 @@ bool load( dungeon_feature_type stair_taken, int load_mode, // GENERATE new level when the file can't be opened: if (levelFile == NULL) { + ASSERT( load_mode != LOAD_VISITOR ); env.turns_on_level = -1; builder( you.your_level, you.level_type ); just_created_level = true; @@ -996,20 +1001,18 @@ bool load( dungeon_feature_type stair_taken, int load_mode, clear_env_map(); // Here's the second cloud clearing, on load (see above) - if (load_mode != LOAD_RESTART_GAME) - clear_clouds(); - - if (load_mode != LOAD_RESTART_GAME) + if ( make_changes ) { + clear_clouds(); if (you.level_type != LEVEL_ABYSS) - place_player_on_stair(where_were_you2, stair_taken); + place_player_on_stair(old_branch, stair_taken); else you.moveto(45, 35); } crawl_view.set_player_at(you.pos(), true); // This should fix the "monster occuring under the player" bug? - if (mgrd[you.x_pos][you.y_pos] != NON_MONSTER) + if (make_changes && mgrd[you.x_pos][you.y_pos] != NON_MONSTER) monster_teleport(&menv[mgrd[you.x_pos][you.y_pos]], true, true); // actually "move" the followers if applicable @@ -1027,7 +1030,9 @@ bool load( dungeon_feature_type stair_taken, int load_mode, sanity_test_monster_inventory(); - dungeon_events.fire_event(DET_ENTERING_LEVEL); + if (load_mode != LOAD_VISITOR) + dungeon_events.fire_event(DET_ENTERING_LEVEL); + // Things to update for player entering level if (load_mode == LOAD_ENTER_LEVEL) { @@ -1067,24 +1072,24 @@ bool load( dungeon_feature_type stair_taken, int load_mode, } // Save the created/updated level out to disk: - save_level( you.your_level, you.level_type, you.where_are_you ); + if ( make_changes ) + save_level( you.your_level, you.level_type, you.where_are_you ); setup_environment_effects(); // Inform user of level's annotation. - if (get_level_annotation().length() > 0 + if (load_mode != LOAD_VISITOR + && !get_level_annotation().empty() && !crawl_state.level_annotation_shown) { - char buf[200]; - - sprintf(buf, "Level annotation: %s\n", - get_level_annotation().c_str() ); - mpr(buf, MSGCH_PLAIN, YELLOW); + mprf(MSGCH_PLAIN, YELLOW, "Level annotation: %s", + get_level_annotation().c_str()); } - crawl_state.level_annotation_shown = false; + if (load_mode != LOAD_VISITOR) + crawl_state.level_annotation_shown = false; - if (load_mode != LOAD_RESTART_GAME) + if ( make_changes ) { // Update PlaceInfo entries PlaceInfo& curr_PlaceInfo = you.get_place_info(); @@ -1092,7 +1097,7 @@ bool load( dungeon_feature_type stair_taken, int load_mode, if (load_mode == LOAD_START_GAME || (load_mode == LOAD_ENTER_LEVEL && - (where_were_you2 != you.where_are_you || + (old_branch != you.where_are_you || old_level_type != you.level_type))) delta.num_visits++; @@ -1109,7 +1114,8 @@ bool load( dungeon_feature_type stair_taken, int load_mode, if (just_created_level) you.attribute[ATTR_ABYSS_ENTOURAGE] = 0; - dungeon_events.fire_event(DET_ENTERED_LEVEL); + if ( load_mode != LOAD_VISITOR ) + dungeon_events.fire_event(DET_ENTERED_LEVEL); return just_created_level; } // end load() @@ -1401,6 +1407,63 @@ void restore_game(void) } } +void apply_to_all_dungeons(void (*applicator)()) +{ + const branch_type original_branch = you.where_are_you; + const int original_level = you.your_level; + const level_area_type original_type = you.level_type; + + branch_type last_visited_branch = original_branch; + int last_visited_level = original_level; + const coord_def old_pos(you.pos()); + + // Apply to current level, then save it out. + applicator(); + save_level(original_level, original_type, original_branch); + + you.level_type = LEVEL_DUNGEON; + + for ( int i = 0; i < MAX_LEVELS; ++i ) + { + for ( int j = 0; j < NUM_BRANCHES; ++j ) + { + if ( tmp_file_pairs[i][j] ) + { + you.your_level = i; + you.where_are_you = static_cast(j); + + // Don't apply to the original level - already done up top. + if ( original_type == you.level_type && + original_level == you.your_level && + original_branch == you.where_are_you ) + continue; + + // Load the dungeon level... + load( DNGN_STONE_STAIRS_DOWN_I, LOAD_VISITOR, + LEVEL_DUNGEON, last_visited_level, + last_visited_branch ); + + // Modify it... + applicator(); + + // And save it back. + save_level(you.your_level, LEVEL_DUNGEON, you.where_are_you); + + last_visited_branch = you.where_are_you; + last_visited_level = you.your_level; + } + } + } + + // Reload the original level. + you.where_are_you = original_branch; + you.your_level = original_level; + you.level_type = original_type; + + load( DNGN_STONE_STAIRS_DOWN_I, LOAD_VISITOR, + original_type, original_level, original_branch ); +} + static bool determine_version( FILE *restoreFile, char &majorVersion, char &minorVersion ) { diff --git a/crawl-ref/source/files.h b/crawl-ref/source/files.h index 8a9cf6a6c8..8300e8134c 100644 --- a/crawl-ref/source/files.h +++ b/crawl-ref/source/files.h @@ -22,9 +22,10 @@ enum load_mode_type { - LOAD_START_GAME, - LOAD_RESTART_GAME, - LOAD_ENTER_LEVEL + LOAD_START_GAME, // game has just begun + LOAD_RESTART_GAME, // loaded savefile + LOAD_ENTER_LEVEL, // entered a level for the first time + LOAD_VISITOR // Visitor pattern to see all levels }; // referenced in files - newgame - ouch - overmap: @@ -61,7 +62,7 @@ void check_newer(const std::string &target, void (*action)()); -bool load( dungeon_feature_type stair_taken, int load_mode, +bool load( dungeon_feature_type stair_taken, load_mode_type load_mode, level_area_type old_level_type, char old_level, branch_type where_were_you2 ); @@ -80,6 +81,7 @@ void save_game_state(); * *********************************************************************** */ void restore_game(void); +void apply_to_all_dungeons(void (*applicator)()); // last updated 12may2000 {dlb} /* *********************************************************************** diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 30f69c4acc..60b760aca3 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -90,14 +90,12 @@ static bool will_autoinscribe = false; // sure item coordinates are correct to the stack they're in. -- bwr void fix_item_coordinates(void) { - int x,y,i; - // nails all items to the ground (i.e. sets x,y) - for (x = 0; x < GXM; x++) + for (int x = 0; x < GXM; x++) { - for (y = 0; y < GYM; y++) + for (int y = 0; y < GYM; y++) { - i = igrd[x][y]; + int i = igrd[x][y]; while (i != NON_ITEM) { @@ -112,19 +110,13 @@ void fix_item_coordinates(void) // This function uses the items coordinates to relink all the igrd lists. void link_items(void) { - int i,j; - // first, initialise igrd array - for (i = 0; i < GXM; i++) - { - for (j = 0; j < GYM; j++) - igrd[i][j] = NON_ITEM; - } + igrd.init(NON_ITEM); // link all items on the grid, plus shop inventory, // DON'T link the huge pile of monster items at (0,0) - for (i = 0; i < MAX_ITEMS; i++) + for (int i = 0; i < MAX_ITEMS; i++) { if (!is_valid_item(mitm[i]) || (mitm[i].x == 0 && mitm[i].y == 0)) { @@ -141,7 +133,7 @@ void link_items(void) static bool item_ok_to_clean(int item) { - // 5. never clean food or Orbs + // never clean food or Orbs if (mitm[item].base_type == OBJ_FOOD || mitm[item].base_type == OBJ_ORBS) return false; @@ -176,14 +168,13 @@ int cull_items(void) 9. unrandarts are 'destroyed', but may be generated again */ - int x,y, item, next; int first_cleaned = NON_ITEM; // 2. avoid shops by avoiding (0,5..9) // 3. avoid monster inventory by iterating over the dungeon grid - for (x = 5; x < GXM; x++) + for (int x = 5; x < GXM; x++) { - for (y = 5; y < GYM; y++) + for (int y = 5; y < GYM; y++) { // 1. not near player! if (x > you.x_pos - 9 && x < you.x_pos + 9 @@ -192,8 +183,10 @@ int cull_items(void) continue; } + int next; + // iterate through the grids list of items: - for (item = igrd[x][y]; item != NON_ITEM; item = next) + for (int item = igrd[x][y]; item != NON_ITEM; item = next) { next = mitm[item].link; // in case we can't get it later. diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 2335c74b42..fbf60e9cee 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -903,7 +903,7 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, if (stair_find == DNGN_ENTER_ZOT) { - int num_runes = runes_in_pack(); + const int num_runes = runes_in_pack(); if (num_runes < NUMBER_OF_RUNES_NEEDED) { @@ -1030,8 +1030,7 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, } if (old_level_type != you.level_type && you.level_type == LEVEL_DUNGEON) - mprf("Welcome back to %s!", - branches[you.where_are_you].longname); + mprf("Welcome back to %s!", branches[you.where_are_you].longname); if (!player_is_airborne() && you.duration[DUR_CONF] diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index fbdf5cab3b..889c46a503 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -1030,14 +1030,14 @@ void fire_monster_alerts() // Monster was not viewed this turn monster->flags &= ~MF_WAS_IN_VIEW; } - monster->seen_context = ""; + monster->seen_context.clear(); } // Xom thinks it's hilarious the way the player picks up an ever // growing entourage of monsters while running through the Abyss. // To approximate this, if the number of hostile monsters in view // is greater than it ever was for this particular trip to the - // Abyss, Xom is stimulated in proprotion to the number of + // Abyss, Xom is stimulated in proportion to the number of // hostile monsters. Thus if the entourage doesn't grow, then // Xom becomes bored. if (you.level_type == LEVEL_ABYSS -- cgit v1.2.3-54-g00ecf