diff options
-rw-r--r-- | crawl-ref/docs/options_guide.txt | 11 | ||||
-rw-r--r-- | crawl-ref/settings/init.txt | 1 | ||||
-rw-r--r-- | crawl-ref/source/delay.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/initfile.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 40 | ||||
-rw-r--r-- | crawl-ref/source/misc.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 5 |
9 files changed, 75 insertions, 3 deletions
diff --git a/crawl-ref/docs/options_guide.txt b/crawl-ref/docs/options_guide.txt index 10808897e0..3e41f02daf 100644 --- a/crawl-ref/docs/options_guide.txt +++ b/crawl-ref/docs/options_guide.txt @@ -51,7 +51,7 @@ The contents of this text are: travel_stop_message, force_more_message, runrest_ignore_message, runrest_ignore_poison, runrest_ignore_monster, trapwalk_safe_hp, - trap_prompt, rest_wait_both + trap_prompt, rest_wait_both, auto_exclude 4-h Stashes. stash_filter, annotate_item_class, annoate_item_dropped @@ -895,7 +895,14 @@ rest_wait_both = false If rest_wait_both is set to true then resting will only stop when both HP and MP are fully restored, not when either one of them is restored. - + +auto_exclude = <list of monster names> + Whenever you encounter a sleeping or stationary monster during + exploration that is included in this list, automatically a + travel exclusion is set centered on this monster, meaning + autoexplore won't ever bring you in its line of sight. If the + monster dies or wakes up while you are in sight, this exclusion + is automatically removed again. 4-h Stashes. ---------------- diff --git a/crawl-ref/settings/init.txt b/crawl-ref/settings/init.txt index 0f082af20b..1220add8d1 100644 --- a/crawl-ref/settings/init.txt +++ b/crawl-ref/settings/init.txt @@ -161,6 +161,7 @@ trap_item_brand = reverse # explore_greedy = false # explore_stop = items,greedy_items,stairs,shops,altars,gates # explore_improved = true +auto_exclude = oklob plant,silver statue,orange crystal statue # tc_reachable = blue # tc_dangerous = cyan diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index eb9fd015d5..eea7f5820a 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -1657,6 +1657,11 @@ inline static void _monster_warning(activity_interrupt_type ai, } else { + // If the monster is in the auto_exclude list, automatically + // set an exclusion. + if (need_auto_exclude(mon) && !is_exclude_root(mon->pos())) + toggle_exclude(mon->pos()); + std::string text = mon->name(DESC_CAP_A); // For named monsters also mention the base type. if (!(mon->mname).empty() && mon->type != MONS_PLAYER_GHOST) diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index a200989c4f..6214570cd7 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -1813,6 +1813,8 @@ public: int tc_exclude_circle; // Colour for squares in the exclusion radius int tc_dangerous; // Colour for trapped squares, deep water, lava. int tc_disconnected;// Areas that are completely disconnected. + std::vector<text_pattern> auto_exclude; // Automatically set an exclusion + // around certain monsters. int travel_stair_cost; diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index ab9a548b7b..12b3f47370 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -2652,6 +2652,10 @@ void game_options::read_option_line(const std::string &str, bool runscript) { tc_disconnected = str_to_colour(field, tc_disconnected); } + else if (key == "auto_exclude") + { + append_vector(auto_exclude, split_string(",", field)); + } else BOOL_OPTION(classic_item_colours); else BOOL_OPTION(item_colour); else BOOL_OPTION_NAMED("item_color", item_colour); diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 212636c8ca..609c107a39 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -2326,6 +2326,46 @@ bool mons_is_safe(const struct monsters *mon, bool want_move) return (is_safe); } +static bool _mon_needs_auto_exclude(const monsters *mon, bool sleepy = false) +{ + if (mons_is_stationary(mon)) + { + if (sleepy) + return (false); + + // Don't give away mimics unless already known. + return (!mons_is_mimic(mon->type) + || testbits(mon->flags, MF_KNOWN_MIMIC)); + } + // Auto exclusion only makes sense if the monster is still asleep. + return (mons_is_sleeping(mon)); +} + +// Check whether a given monster is listed in the auto_exclude option. +bool need_auto_exclude(const monsters *mon, bool sleepy) +{ + // This only works if the name is lowercased. + std::string name = mon->name(DESC_BASENAME); + lowercase(name); + + for (unsigned i = 0; i < Options.auto_exclude.size(); ++i) + if (Options.auto_exclude[i].matches(name) + && _mon_needs_auto_exclude(mon, sleepy)) + { + return (true); + } + + return (false); +} + +// Clear auto exclusion if the monster is killed or wakes up with the +// player in sight. If sleepy is true, stationary monsters are ignored. +void remove_auto_exclude(const monsters *mon, bool sleepy) +{ + if (need_auto_exclude(mon, sleepy) && is_exclude_root(mon->pos())) + toggle_exclude(mon->pos()); +} + // Return all nearby monsters in range (default: LOS) that the player // is able to recognize as being monsters (i.e. no unknown mimics or // submerged creatures.) diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h index 21fc63889c..efccdec0c7 100644 --- a/crawl-ref/source/misc.h +++ b/crawl-ref/source/misc.h @@ -72,6 +72,8 @@ std::string weird_sound(); void curare_hits_player(int agent, int degree); bool mons_is_safe(const monsters *mon, bool want_move = false); +bool need_auto_exclude(const monsters *mon, bool sleepy = false); +void remove_auto_exclude(const monsters *mon, bool sleepy = false); std::vector<monsters*> get_nearby_monsters(bool want_move = false, bool just_check = false, diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index ede0784ae7..f2549cd11d 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -775,6 +775,9 @@ void monster_die(monsters *monster, killer_type killer, // Update list of monsters beholding player. update_beholders(monster, true); + // Clear auto exclusion now the monster is killed. + remove_auto_exclude(monster); + const int monster_killed = monster_index(monster); const bool hard_reset = testbits(monster->flags, MF_HARD_RESET); const bool gives_xp = !monster->has_ench(ENCH_ABJ); @@ -7603,6 +7606,11 @@ void seen_monster(monsters *monster) // First time we've seen this particular monster. monster->flags |= MF_SEEN; + // If the monster is in the auto_exclude list, automatically + // set an exclusion. + if (need_auto_exclude(monster) && !is_exclude_root(monster->pos())) + toggle_exclude(monster->pos()); + if (!mons_is_mimic(monster->type) && MONST_INTERESTING(monster) && monster->type != MONS_PANDEMONIUM_DEMON diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 9cc0467557..9239c33266 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -1178,9 +1178,12 @@ void monster_grid(bool do_updates) if (monster->type != -1 && mons_near(monster)) { if (do_updates && (mons_is_sleeping(monster) - || mons_is_wandering(monster)) + || mons_is_wandering(monster)) && check_awaken(monster)) { + if (mons_near(monster)) + remove_auto_exclude(monster, true); + behaviour_event( monster, ME_ALERT, MHITYOU ); handle_monster_shouts(monster); } |