diff options
-rw-r--r-- | crawl-ref/source/dat/clua/lm_flags.lua | 6 | ||||
-rw-r--r-- | crawl-ref/source/dat/lair.des | 2 | ||||
-rw-r--r-- | crawl-ref/source/files.cc | 114 | ||||
-rw-r--r-- | crawl-ref/source/files.h | 8 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 26 | ||||
-rw-r--r-- | crawl-ref/source/spl-util.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/travel.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/travel.h | 2 |
8 files changed, 118 insertions, 51 deletions
diff --git a/crawl-ref/source/dat/clua/lm_flags.lua b/crawl-ref/source/dat/clua/lm_flags.lua index 68bf42177e..86814a26a8 100644 --- a/crawl-ref/source/dat/clua/lm_flags.lua +++ b/crawl-ref/source/dat/clua/lm_flags.lua @@ -73,8 +73,10 @@ function ChangeFlags:new(pars) pars.branch_flags = pars.branch_flags or "" pars.msg = pars.msg or "" - if not (pars.level_flags ~= "" or pars.branch_flags ~= "") then - error("Must provide at least one of level_flags or branch_flags.") + if pars.level_flags == "" and pars.branch_flags == "" + and not pars.trigger + then + error("Must provide at least one of level_flags, branch_flags, or trigger.") end local cf = self:_new() diff --git a/crawl-ref/source/dat/lair.des b/crawl-ref/source/dat/lair.des index 9b63a34ad1..c476cb5581 100644 --- a/crawl-ref/source/dat/lair.des +++ b/crawl-ref/source/dat/lair.des @@ -786,7 +786,7 @@ NSUBST: P = O / *| SHUFFLE: ([{ LFLAGS: no_tele_control MARKER: X = lua:mons_dies_change_flags { \ - level_flags="!no_tele_control", mon_name="royal jelly", \ + mon_name="royal jelly", \ trigger=slime_wall_morph \ } SUBST: X = . diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index d6de3741da..c60c60b706 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -1475,62 +1475,94 @@ void restore_game(void) } } -bool apply_to_all_dungeons(bool (*applicator)()) +static void _restore_level(const level_id &original) { - 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; + // Reload the original level. + you.where_are_you = original.branch; + you.your_level = original.absdepth(); + you.level_type = original.level_type; + + load( DNGN_STONE_STAIRS_DOWN_I, LOAD_VISITOR, + you.level_type, you.your_level, you.where_are_you ); +} - branch_type last_visited_branch = original_branch; - int last_visited_level = original_level; - const coord_def old_pos(you.pos()); +// 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. +bool is_existing_level(const level_id &level) +{ + ASSERT(level.level_type == LEVEL_DUNGEON); + return (tmp_file_pairs[level.absdepth()][level.branch]); +} + +// Applies an operation (applicator) after switching to the specified level. +// If preserve_current is true, will reload the original level after +// modifying the target level. +// +// If the target level has not already been visited by the player, this +// function will assert. +// +bool apply_to_level(const level_id &level, bool preserve_current, + bool (*applicator)()) +{ + ASSERT(is_existing_level(level)); + + const level_id original = level_id::current(); + if (level != original) + { + you.where_are_you = level.branch; + you.your_level = level.absdepth(); + you.level_type = level.level_type; + + // Load the dungeon level... + load( DNGN_STONE_STAIRS_DOWN_I, LOAD_VISITOR, + LEVEL_DUNGEON, original.absdepth(), + original.branch ); + } + + // Apply the change. + const bool result = applicator(); + + if (level != original) + { + // And save it back. + save_level(you.your_level, you.level_type, you.where_are_you); + + if (preserve_current) + _restore_level(original); + } + + return (result); +} + +bool apply_to_all_dungeons(bool (*applicator)()) +{ + const level_id original = level_id::current(); // Apply to current level, then save it out. bool success = applicator(); - save_level(original_level, original_type, original_branch); - - you.level_type = LEVEL_DUNGEON; + save_level(original.absdepth(), original.level_type, original.branch); 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); + const branch_type br = static_cast<branch_type>(j); + const level_id thislevel(br, subdungeon_depth(br, i)); - // 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... - if ( applicator() ) - success = true; - - // And save it back. - save_level(you.your_level, LEVEL_DUNGEON, you.where_are_you); + if (!is_existing_level(thislevel)) + continue; + + // Don't apply to the original level - already done up top. + if (original == thislevel) + continue; - last_visited_branch = you.where_are_you; - last_visited_level = you.your_level; - } + if (apply_to_level(thislevel, false, applicator)) + success = true; } } - // 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 ); + _restore_level(original); return success; } diff --git a/crawl-ref/source/files.h b/crawl-ref/source/files.h index 422925343e..830f99bc41 100644 --- a/crawl-ref/source/files.h +++ b/crawl-ref/source/files.h @@ -83,6 +83,14 @@ void restore_game(void); bool apply_to_all_dungeons(bool (*applicator)()); +class level_id; + +bool apply_to_level(const level_id &level, bool preserve_current, + bool (*applicator)()); + +bool is_existing_level(const level_id &level); + + // last updated 12may2000 {dlb} /* *********************************************************************** * called from: ouch diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 28b340f0fb..39651da8f0 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -38,6 +38,7 @@ #include "describe.h" #include "dgnevent.h" #include "fight.h" +#include "files.h" #include "ghost.h" #include "hiscores.h" #include "it_use2.h" @@ -639,6 +640,25 @@ static bool _is_mons_mutator_or_rotter(monsters *mons) return (attk_flavour == AF_MUTATE || attk_flavour == AF_ROT); } +static bool _slime_pit_enable_teleport_control() +{ + return unset_level_flags(LFLAG_NO_TELE_CONTROL); +} + +static void _fire_monster_death_event(monsters *monster, + killer_type killer, + int i) +{ + dungeon_events.fire_event( + dgn_event(DET_MONSTER_DIED, monster->pos(), 0, + monster_index(monster), killer)); + + if (monster->type == MONS_ROYAL_JELLY) + apply_to_level( level_id(BRANCH_SLIME_PITS, 6), + true, + _slime_pit_enable_teleport_control ); +} + void monster_die(monsters *monster, killer_type killer, int i, bool silent) { if (monster->type == -1) @@ -1202,9 +1222,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) } } - dungeon_events.fire_event( - dgn_event(DET_MONSTER_DIED, monster->pos(), 0, - monster_index(monster), killer)); + _fire_monster_death_event(monster, killer, i); const coord_def mwhere = monster->pos(); if (drop_items) @@ -1217,7 +1235,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) view_update_at(mwhere); update_screen(); } -} // end monster_die +} void monster_cleanup(monsters *monster) { diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc index 7f6adfe75d..abf3ebabc6 100644 --- a/crawl-ref/source/spl-util.cc +++ b/crawl-ref/source/spl-util.cc @@ -114,10 +114,10 @@ spell_type spell_by_name(std::string name, bool partial_match) for (int i = 0; i < NUM_SPELLS; i++) { spell_type type = static_cast<spell_type>(i); - const char *sptitle = spell_title(type); - if (!sptitle) + if (!is_valid_spell(type)) continue; - + + const char *sptitle = spell_title(type); const std::string spell_name = lowercase_string(sptitle); if (spell_name.find(name) != std::string::npos) diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc index f48abe8b81..20ec7cd138 100644 --- a/crawl-ref/source/travel.cc +++ b/crawl-ref/source/travel.cc @@ -2927,6 +2927,11 @@ level_id level_id::current() return id; } +int level_id::absdepth() const +{ + return absdungeon_depth(branch, depth); +} + level_id level_id::get_next_level_id(const coord_def &pos) { int gridc = grd[pos.x][pos.y]; diff --git a/crawl-ref/source/travel.h b/crawl-ref/source/travel.h index 78b924ad66..bada932b2b 100644 --- a/crawl-ref/source/travel.h +++ b/crawl-ref/source/travel.h @@ -260,6 +260,8 @@ public: return (branch < id.branch) || (branch==id.branch && depth < id.depth); } + int absdepth() const; + void save(writer&) const; void load(reader&); }; |