summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-12-01 19:38:40 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-12-01 19:38:40 +0000
commitc98e65d7c1e611743f82997954c259dedbe843b2 (patch)
treeb1da44fc24119b294a01311e0a64891be2578679
parent37ffd29a84d48b08c2ef799a271f3ab83202a03a (diff)
downloadcrawl-ref-c98e65d7c1e611743f82997954c259dedbe843b2.tar.gz
crawl-ref-c98e65d7c1e611743f82997954c259dedbe843b2.zip
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
-rw-r--r--crawl-ref/source/files.cc109
-rw-r--r--crawl-ref/source/files.h10
-rw-r--r--crawl-ref/source/items.cc29
-rw-r--r--crawl-ref/source/misc.cc5
-rw-r--r--crawl-ref/source/view.cc4
5 files changed, 107 insertions, 50 deletions
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<dungeon_feature_type> 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<branch_type>(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