diff options
author | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-09-15 11:02:27 +0000 |
---|---|---|
committer | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-09-15 11:02:27 +0000 |
commit | 325516c60743ee1241e9ca3d13e4fd8a36d19c94 (patch) | |
tree | 151760b072e644587218af90c0c0d7694256fb1a /crawl-ref/source | |
parent | 298c1e905c0c3d04acdb1dd0c5e6bedce77dec3c (diff) | |
download | crawl-ref-325516c60743ee1241e9ca3d13e4fd8a36d19c94.tar.gz crawl-ref-325516c60743ee1241e9ca3d13e4fd8a36d19c94.zip |
Smarter exclusions, yay!
* Exclusions are now treated similarly to annotations and automatically
added to the overmap (with the monster name if centered on a monster).
* Exclusions remember whether they were placed automatically and if so,
what monster triggered it.
* If a grid that was previously autoexcluded comes back into sight and no
longer contains the monster that triggered the autoexclusion (dead,
moved away or invisible), the autoexclusion is removed again.
I updated the tags, so it should be save compatible but I'm not making
any promises.
Also fix the Wild magic card not being documented correctly.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@10679 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/dat/descript/cards.txt | 10 | ||||
-rw-r--r-- | crawl-ref/source/dat/descript/items.txt | 8 | ||||
-rw-r--r-- | crawl-ref/source/files.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/overmap.cc | 42 | ||||
-rw-r--r-- | crawl-ref/source/overmap.h | 7 | ||||
-rw-r--r-- | crawl-ref/source/spells4.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/tags.cc | 15 | ||||
-rw-r--r-- | crawl-ref/source/tags.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/travel.cc | 90 | ||||
-rw-r--r-- | crawl-ref/source/travel.h | 26 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 3 |
12 files changed, 173 insertions, 40 deletions
diff --git a/crawl-ref/source/dat/descript/cards.txt b/crawl-ref/source/dat/descript/cards.txt index f945df51d4..24fcb33346 100644 --- a/crawl-ref/source/dat/descript/cards.txt +++ b/crawl-ref/source/dat/descript/cards.txt @@ -103,6 +103,11 @@ Experience card This card makes you more experienced. It is usually found in decks of changes and wonders. %%%% +Wild Magic card + +This card causes wild magic, as if from miscasting a spell, to act upon you. +It is usually found in the deck of wonders. +%%%% the Helix card This cards changes your mutations. Higher power levels make the change more likely to be beneficial. @@ -251,11 +256,6 @@ Famine card This card starves you. It is usually only found in Nemelex Xobeh's deck of punishment. %%%% -Wild Magic card - -This card causes wild magic, as if from miscasting a spell, to act upon you. -It is usually only found in Nemelex Xobeh's deck of punishment. -%%%% # deck of oddities (random card, along with a few others) the Bargain card diff --git a/crawl-ref/source/dat/descript/items.txt b/crawl-ref/source/dat/descript/items.txt index a42add8db1..a30b6ad72d 100644 --- a/crawl-ref/source/dat/descript/items.txt +++ b/crawl-ref/source/dat/descript/items.txt @@ -509,7 +509,7 @@ deck of wonders A deck of highly mysterious and magical cards, which can permanently alter the drawer's physical and mental condition, for better or worse. -It may contain the following cards: the Potion, Focus, Shuffle, Experience, the Helix, the Sage. +It may contain the following cards: the Potion, Focus, Shuffle, Experience, Wild Magic, the Helix, the Sage. %%%% demon blade @@ -1309,9 +1309,9 @@ not apply to beings fully immune to magic. scroll of silence This scroll eliminates all sound near the reader. This makes reading -scrolls, casting spells, praying or yelling in the reader's vicinity -impossible. (Applies to reader too, of course.) This silence will not -hide your presence, since its oppressive, unnatural effect will almost +scrolls, casting spells, praying or yelling in the reader's vicinity +impossible. (Applies to reader too, of course.) This silence will not +hide your presence, since its oppressive, unnatural effect will almost certainly alert any living creature that something is very wrong. %%%% scythe diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 78d86aa5a1..b10808d4a9 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -1441,7 +1441,10 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode, you.attribute[ATTR_ABYSS_ENTOURAGE] = 0; if (load_mode != LOAD_VISITOR) + { dungeon_events.fire_event(DET_ENTERED_LEVEL); +// set_level_exclusion_annotation(get_exclusion_desc()); + } if (load_mode == LOAD_ENTER_LEVEL) { @@ -1818,7 +1821,7 @@ void restore_game(void) if (travelf) { reader inf(travelf); - travel_cache.load(inf); + travel_cache.load(inf, minorVersion); fclose(travelf); } diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index f7c10046fe..6181cea8f0 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -2769,7 +2769,7 @@ void set_auto_exclude(const monsters *mon) { if (need_auto_exclude(mon) && !is_exclude_root(mon->pos())) { - toggle_exclude(mon->pos()); + toggle_exclude(mon->pos(), true); #ifdef USE_TILE viewwindow(true, false); #endif diff --git a/crawl-ref/source/overmap.cc b/crawl-ref/source/overmap.cc index 5c1df7c285..26d797ef72 100644 --- a/crawl-ref/source/overmap.cc +++ b/crawl-ref/source/overmap.cc @@ -57,6 +57,7 @@ portal_vault_map_type portal_vaults_present; portal_note_map_type portal_vault_notes; portal_vault_colour_map_type portal_vault_colours; annotation_map_type level_annotations; +annotation_map_type level_exclusions; static void _seen_altar( god_type god, const coord_def& pos ); static void _seen_staircase(dungeon_feature_type which_staircase, @@ -721,14 +722,45 @@ void clear_level_annotation(level_id li) level_annotations.erase(li); } -std::string get_level_annotation(level_id li) +void set_level_exclusion_annotation(std::string str, level_id li) +{ + if (str.empty()) + { + clear_level_exclusion_annotation(li); + return; + } + + level_exclusions[li] = str; +} + +void clear_level_exclusion_annotation(level_id li) +{ + level_exclusions.erase(li); +} + +std::string get_level_annotation(level_id li, bool skip_excl) { annotation_map_type::const_iterator i = level_annotations.find(li); - if (i == level_annotations.end()) + if (skip_excl) + { + if (i == level_annotations.end()) + return ""; + + return (i->second); + } + + annotation_map_type::const_iterator j = level_exclusions.find(li); + + if (i == level_annotations.end() && j == level_exclusions.end()) return ""; - return (i->second); + if (i == level_annotations.end()) + return (j->second); + if (j == level_annotations.end()) + return (i->second); + + return (i->second + ", " + j->second); } bool level_annotation_has(std::string find, level_id li) @@ -768,7 +800,7 @@ void annotate_level() if (!get_level_annotation(li).empty()) { mpr("Current level annotation is:", MSGCH_PROMPT); - mpr(get_level_annotation(li).c_str() ); + mpr(get_level_annotation(li, true).c_str() ); } mpr("Set level annotation to what (using ! forces prompt)? ", @@ -780,7 +812,7 @@ void annotate_level() if (buf[0] == 0) { - if (get_level_annotation(li).length() > 0) + if (get_level_annotation(li, true).length() > 0) { if (!yesno("Really clear the annotation?")) return; diff --git a/crawl-ref/source/overmap.h b/crawl-ref/source/overmap.h index 60c71beb73..90b79b56a4 100644 --- a/crawl-ref/source/overmap.h +++ b/crawl-ref/source/overmap.h @@ -25,7 +25,12 @@ void set_level_annotation(std::string str, level_id li = level_id::current()); void clear_level_annotation(level_id li = level_id::current()); -std::string get_level_annotation(level_id li = level_id::current()); +void set_level_exclusion_annotation(std::string str, + level_id li = level_id::current()); +void clear_level_exclusion_annotation(level_id li = level_id::current()); + +std::string get_level_annotation(level_id li = level_id::current(), + bool skip_excl = false); bool level_annotation_has(std::string str, level_id li = level_id::current()); diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index 0101f92d1c..6484fa1f83 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -1359,7 +1359,7 @@ bool cast_fragmentation(int pow, const dist& spd) { int debris = 0; bool explode = false; - bool hole = true; + bool hole = true; const char *what = NULL; ray_def ray; diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 520e02fc02..3b6c0ef4af 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -96,6 +96,7 @@ extern std::map<level_pos, std::string> portal_vaults_present; extern std::map<level_pos, std::string> portal_vault_notes; extern std::map<level_pos, char> portal_vault_colours; extern std::map<level_id, std::string> level_annotations; +extern std::map<level_id, std::string> level_exclusions; // temp file pairs used for file level cleanup @@ -166,7 +167,7 @@ static void tag_construct_lost_monsters(writer &th); static void tag_construct_lost_items(writer &th); static void tag_read_you(reader &th, char minorVersion); static void tag_read_you_items(reader &th, char minorVersion); -static void tag_read_you_dungeon(reader &th); +static void tag_read_you_dungeon(reader &th, char minorVersion); static void tag_read_lost_monsters(reader &th); static void tag_read_lost_items(reader &th); @@ -722,7 +723,7 @@ tag_type tag_read(FILE *fp, char minorVersion) { case TAG_YOU: tag_read_you(th, minorVersion); break; case TAG_YOU_ITEMS: tag_read_you_items(th, minorVersion); break; - case TAG_YOU_DUNGEON: tag_read_you_dungeon(th); break; + case TAG_YOU_DUNGEON: tag_read_you_dungeon(th, minorVersion); break; case TAG_LEVEL: tag_read_level(th, minorVersion); break; case TAG_LEVEL_ITEMS: tag_read_level_items(th, minorVersion); break; case TAG_LEVEL_MONSTERS: tag_read_level_monsters(th, minorVersion); break; @@ -1133,6 +1134,8 @@ static void tag_construct_you_dungeon(writer &th) marshall_level_pos, marshallByte); marshallMap(th, level_annotations, marshall_level_id, marshallStringNoMax); + marshallMap(th, level_exclusions, + marshall_level_id, marshallStringNoMax); marshallPlaceInfo(th, you.global_info); std::vector<PlaceInfo> list = you.get_all_place_info(); @@ -1575,7 +1578,7 @@ static PlaceInfo unmarshallPlaceInfo(reader &th) return place_info; } -static void tag_read_you_dungeon(reader &th) +static void tag_read_you_dungeon(reader &th, char minorVersion) { // how many unique creatures? int count_c = unmarshallShort(th); @@ -1616,6 +1619,12 @@ static void tag_read_you_dungeon(reader &th) unmarshallMap(th, level_annotations, unmarshall_level_id, unmarshallStringNoMax); + if (minorVersion >= TAG_ANNOTATE_EXCL) + { + unmarshallMap(th, level_exclusions, + unmarshall_level_id, unmarshallStringNoMax); + } + PlaceInfo place_info = unmarshallPlaceInfo(th); ASSERT(place_info.is_global()); you.set_place_info(place_info); diff --git a/crawl-ref/source/tags.h b/crawl-ref/source/tags.h index d6bcebc293..0535dbefad 100644 --- a/crawl-ref/source/tags.h +++ b/crawl-ref/source/tags.h @@ -69,7 +69,8 @@ enum tag_minor_version TAG_MINOR_JIYVA = 17, // Added some player bits for Jiyva. TAG_MINOR_ZOT_OPEN = 18, // Remember whether Zot was opened. TAG_MINOR_JELLY = 19, // Remember whether the royal jelly is dead. - TAG_MINOR_VERSION = 19 // Current version. (Keep equal to max.) + TAG_ANNOTATE_EXCL = 20, // Store exclusion information for annotations. + TAG_MINOR_VERSION = 20 // Current version. (Keep equal to max.) }; diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc index 4dbbce3a68..e7f9d11f87 100644 --- a/crawl-ref/source/travel.cc +++ b/crawl-ref/source/travel.cc @@ -424,6 +424,7 @@ void clear_excludes() toggle_exclude(curr_excludes[i].pos); #endif curr_excludes.clear(); + clear_level_exclusion_annotation(); if (can_travel_interlevel()) { @@ -456,19 +457,20 @@ void cycle_exclude_radius(const coord_def &p) } } -void toggle_exclude(const coord_def &p) +void toggle_exclude(const coord_def &p, bool autoexcl) { if (is_exclude_root(p)) set_exclude(p, 0); else - set_exclude(p, LOS_RADIUS); + set_exclude(p, LOS_RADIUS, autoexcl); #ifdef USE_TILE _tile_exclude_gmap_update(p); #endif + set_level_exclusion_annotation(get_exclusion_desc()); } -void set_exclude(const coord_def &p, int radius) +void set_exclude(const coord_def &p, int radius, bool autoexcl) { // Sanity checks; excludes can be set in Pan and regular dungeon // levels only. @@ -499,7 +501,12 @@ void set_exclude(const coord_def &p, int radius) } else { - curr_excludes.push_back(travel_exclude(p, radius)); + int montype = NON_MONSTER; + const monsters *m = monster_at(p); + if (m && mons_near(m) && you.can_see(m)) + montype = m->type; + + curr_excludes.push_back(travel_exclude(p, radius, autoexcl, montype)); } if (can_travel_interlevel()) @@ -509,6 +516,64 @@ void set_exclude(const coord_def &p, int radius) } } +// If a grid that was placed automatically no longer contains the original +// monster (or it is invisible), remove the exclusion. +void maybe_remove_autoexclusion(const coord_def &p) +{ + ASSERT(in_bounds(p) && see_grid(p) && is_exclude_root(p)); + + for (int i = 0, count = curr_excludes.size(); i < count; ++i) + { + if (curr_excludes[i].pos == p) + { + if (curr_excludes[i].autoexclude) + { + const monsters *m = monster_at(p); + if (!m || !you.can_see(m) || m->type != curr_excludes[i].mon) + { + set_exclude(p, 0); + set_level_exclusion_annotation(get_exclusion_desc()); + } + } + break; + } + } +} + +// Lists alls exclusions on the current level. +std::string get_exclusion_desc() +{ + std::vector<std::string> monsters; + int count_other = 0; + for (int i = 0, count = curr_excludes.size(); i < count; ++i) + { + if (curr_excludes[i].mon != NON_MONSTER) + monsters.push_back(get_monster_data(curr_excludes[i].mon)->name); + else + count_other++; + } + + if (count_other > 0) + { + snprintf(info, INFO_SIZE, "%d %sexclusion%s", + count_other, monsters.empty() ? "" : "more ", + count_other > 1 ? "s" : ""); + monsters.push_back(info); + } + else if (monsters.empty()) + return ""; + + std::string desc = ""; + if (monsters.size() > 1 || count_other == 0) + { + snprintf(info, INFO_SIZE, "exclusion%s: ", + monsters.size() > 1 ? "s" : ""); + desc += info; + } + return (desc + comma_separated_line(monsters.begin(), monsters.end(), + ", and ", ", ")); +} + static bool _is_monster_blocked(const coord_def& c) { const monsters *mons = monster_at(c); @@ -3595,11 +3660,13 @@ void LevelInfo::save(writer& outf) const { marshallCoord(outf, excludes[i].pos); marshallShort(outf, excludes[i].radius); + marshallBoolean(outf, excludes[i].autoexclude); + marshallShort(outf, excludes[i].mon); } } } -void LevelInfo::load(reader& inf) +void LevelInfo::load(reader& inf, char minorVersion) { stairs.clear(); int stair_count = unmarshallShort(inf); @@ -3635,7 +3702,14 @@ void LevelInfo::load(reader& inf) coord_def c; unmarshallCoord(inf, c); const int radius = unmarshallShort(inf); - excludes.push_back(travel_exclude(c, radius)); + bool autoexcl = false; + int mon = NON_MONSTER; + if (minorVersion >= TAG_ANNOTATE_EXCL) + { + autoexcl = unmarshallBoolean(inf); + mon = unmarshallShort(inf); + } + excludes.push_back(travel_exclude(c, radius, autoexcl, mon)); } } } @@ -3897,7 +3971,7 @@ void TravelCache::save(writer& outf) const waypoints[wp].save(outf); } -void TravelCache::load(reader& inf) +void TravelCache::load(reader& inf, char minorVersion) { levels.clear(); @@ -3916,7 +3990,7 @@ void TravelCache::load(reader& inf) // Must set id before load, or travel_hell_entry will not be // correctly set. linfo.id = id; - linfo.load(inf); + linfo.load(inf, minorVersion); levels[id] = linfo; } diff --git a/crawl-ref/source/travel.h b/crawl-ref/source/travel.h index e584bc3057..60f1e23cd6 100644 --- a/crawl-ref/source/travel.h +++ b/crawl-ref/source/travel.h @@ -60,9 +60,12 @@ void init_travel_terrain_check(bool check_race_equip = true); void stop_running(void); void travel_init_new_level(); void cycle_exclude_radius(const coord_def &p); -void toggle_exclude(const coord_def &p); -void set_exclude(const coord_def &p, int radius2); +void toggle_exclude(const coord_def &p, bool autoexcl = false); +void set_exclude(const coord_def &p, int radius2, bool autoexcl = false); +void maybe_remove_autoexclusion(const coord_def &p); +std::string get_exclusion_desc(); void clear_excludes(); + unsigned char is_waypoint(const coord_def &p); bool is_exclude_root(const coord_def &p); bool is_stair(dungeon_feature_type gridc); @@ -351,15 +354,18 @@ void mark_all_excludes_non_updated(); struct travel_exclude { - coord_def pos; // exclusion centre - int radius; // exclusion radisu - env_show_grid show; // los from exclusion centre - bool uptodate; // Is show up to date? + coord_def pos; // exclusion centre + int radius; // exclusion radius + bool autoexclude; // Was set automatically. + int mon; // Monster around which exclusion is centered. + env_show_grid show; // los from exclusion centre + bool uptodate; // Is show up to date? void set_exclude_show(); - travel_exclude(const coord_def &p, int r = LOS_RADIUS) - : pos(p), radius(r) + travel_exclude(const coord_def &p, int r = LOS_RADIUS, + bool autoexcl = false, int mons = NON_MONSTER) + : pos(p), radius(r), autoexclude(autoexcl), mon(mons) { set_exclude_show(); } @@ -378,7 +384,7 @@ struct LevelInfo } void save(writer&) const; - void load(reader&); + void load(reader&, char minorVersion); std::vector<stair_info> &get_stairs() { @@ -490,7 +496,7 @@ public: void update(); void save(writer&) const; - void load(reader&); + void load(reader&, char minorVersion); bool is_known_branch(unsigned char branch) const; diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 9ebb400a95..fa46b023f5 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -5336,6 +5336,9 @@ void viewwindow(bool draw_it, bool do_updates) const coord_def sep = ep - coord_def(1,1); #endif + if (in_bounds(gc) && see_grid(gc) && is_exclude_root(gc)) + maybe_remove_autoexclusion(gc); + // Print tutorial messages for features in LOS. if (Options.tutorial_left && in_bounds(gc) |