From 530dccaf735b1c9db4fe4c0b630e21f81ec70e6a Mon Sep 17 00:00:00 2001 From: haranp Date: Sat, 23 Sep 2006 12:01:07 +0000 Subject: Integrated Matthew Cline's updates to notes. This breaks note file compatibility. fully_identified() might need some testing. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup@92 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/enum.h | 6 ++-- crawl-ref/source/externs.h | 3 ++ crawl-ref/source/initfile.cc | 17 ++++++++++- crawl-ref/source/itemname.cc | 17 +++++++++-- crawl-ref/source/itemprop.cc | 12 ++++++++ crawl-ref/source/items.cc | 7 +---- crawl-ref/source/message.cc | 13 +++++++- crawl-ref/source/mon-util.cc | 1 + crawl-ref/source/monplace.cc | 49 +++++++++++++++++++++++++++-- crawl-ref/source/monplace.h | 6 ++++ crawl-ref/source/monstuff.cc | 73 +++++++++++++++++++++++++++++++++----------- crawl-ref/source/monstuff.h | 7 +++++ crawl-ref/source/mstuff2.cc | 10 ++++++ crawl-ref/source/notes.cc | 47 ++++++++++++++++++++++++---- crawl-ref/source/notes.h | 7 ++++- crawl-ref/source/spells2.cc | 2 ++ crawl-ref/source/stash.cc | 27 ++++++++++++++++ crawl-ref/source/stash.h | 8 +++++ crawl-ref/source/view.cc | 2 ++ 19 files changed, 274 insertions(+), 40 deletions(-) diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index e99447e558..52df7f5d1b 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -2267,9 +2267,9 @@ enum monster_flag_type MF_JUST_SUMMONED = 0x08, // monster skips next available action MF_TAKING_STAIRS = 0x10, // is following player through stairs - MF_UNUSED_I = 0x20, - MF_UNUSED_II = 0x40, - MF_UNUSED_III = 0x80 + MF_INTERESTING = 0x20, // Player finds monster interesting + MF_SEEN = 0x40, // Player already seen monster + MF_UNUSED_I = 0x80 }; enum mon_dam_level_type diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 0267e63f93..981b38cfeb 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -675,6 +675,7 @@ struct game_options bool confirm_spell_fizzle; // require confirm before cancel bool safe_autopickup; // don't autopickup when monsters visible bool note_skill_max; // take note when skills reach new max + bool note_all_spells; // take note when learning any spell bool use_notes; // take (and dump) notes int note_hp_percent; // percentage hp for notetaking int ood_interesting; // how many levels OOD is noteworthy? @@ -720,6 +721,8 @@ struct game_options std::string map_file_name; // name of mapping file to use std::vector banned_objects; // Objects we'll never pick up + std::vector note_monsters; // Interesting monsters + std::vector note_messages; // Interesting messages std::vector > autoinscriptions; std::vector note_items; // Objects to note std::vector note_skill_levels; // Skill levels to note diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index 8dc252a10f..cf7e57f116 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -384,6 +384,7 @@ void reset_options(bool clear_name) Options.safe_autopickup = false; Options.use_notes = false; Options.note_skill_max = false; + Options.note_all_spells = false; Options.note_hp_percent = 0; Options.ood_interesting = 8; Options.terse_hand = true; @@ -483,6 +484,8 @@ void reset_options(bool clear_name) // Clear vector options. Options.banned_objects.clear(); + Options.note_monsters.clear(); + Options.note_messages.clear(); Options.autoinscriptions.clear(); Options.note_items.clear(); Options.note_skill_levels.clear(); @@ -896,7 +899,7 @@ void parse_option_line(const std::string &str, bool runscript) && key != "stop_travel" && key != "sound" && key != "drop_filter" && key != "lua_file" && key != "note_items" && key != "autoinscribe" - && key != "map_file_name" ) + && key != "note_monsters" && key != "note_messages") { tolower_string( field ); } @@ -1216,6 +1219,14 @@ void parse_option_line(const std::string &str, bool runscript) { Options.ood_interesting = atoi( field.c_str() ); } + else if (key == "note_monsters") + { + append_vector(Options.note_monsters, split_string(",", field)); + } + else if (key == "note_messages") + { + append_vector(Options.note_messages, split_string(",", field)); + } else if (key == "note_hp_percent") { Options.note_hp_percent = atoi( field.c_str() ); @@ -1287,6 +1298,10 @@ void parse_option_line(const std::string &str, bool runscript) { Options.note_skill_max = read_bool( field, Options.note_skill_max ); } + else if (key == "note_all_spells") + { + Options.note_all_spells = read_bool( field, Options.note_all_spells ); + } else if (key == "delay_message_clear") { Options.delay_message_clear = read_bool( field, Options.delay_message_clear ); diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index 11ee7cd504..4d22749cec 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -37,7 +37,7 @@ #include "stuff.h" #include "wpn-misc.h" #include "view.h" - +#include "items.h" char id[NUM_IDTYPE][MAX_SUBTYPES]; @@ -63,7 +63,7 @@ bool item_type_known( const item_def &item ) } // it_name() and in_name() are now somewhat obsolete now that itemname -// takes item_def, so consider them depricated. +// takes item_def, so consider them deprecated. void it_name( int itn, char des, char buff[ ITEMNAME_SIZE ], bool terse ) { item_name( mitm[itn], des, buff, terse ); @@ -2446,5 +2446,16 @@ bool is_interesting_item( const item_def& item ) { } bool fully_identified( const item_def& item ) { - return item_ident( item, ISFLAG_IDENT_MASK ); + item_status_flag_type flagset = ISFLAG_IDENT_MASK; + switch ( item.base_type ) { + case OBJ_BOOKS: + case OBJ_MISCELLANY: + case OBJ_ORBS: + case OBJ_SCROLLS: + flagset = ISFLAG_KNOW_TYPE; + break; + default: + break; + } + return item_ident( item, flagset ); } diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc index 0a48f6c00f..7990f97be6 100644 --- a/crawl-ref/source/itemprop.cc +++ b/crawl-ref/source/itemprop.cc @@ -26,6 +26,7 @@ #include "itemprop.h" #include "macro.h" #include "mon-util.h" +#include "notes.h" #include "player.h" #include "randart.h" #include "skills2.h" @@ -454,7 +455,18 @@ bool item_ident( const item_def &item, unsigned long flags ) void set_ident_flags( item_def &item, unsigned long flags ) { + bool known_before = fully_identified(item); item.flags |= flags; + if ( !known_before && fully_identified(item) ) { + /* make a note of it */ + if ( is_interesting_item(item) ) { + char buf[ITEMNAME_SIZE]; + char buf2[ITEMNAME_SIZE]; + item_name( item, DESC_NOCAP_A, buf ); + strcpy(buf2, origin_desc(item).c_str()); + take_note(Note(NOTE_ID_ITEM, 0, 0, buf, buf2)); + } + } } void unset_ident_flags( item_def &item, unsigned long flags ) diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index bb744be701..ca69eceebb 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -975,12 +975,7 @@ static std::string origin_monster_desc(const item_def &item) static std::string origin_place_desc(const item_def &item) { - std::string place = branch_level_name(item.orig_place); - if (place.length() && place != "Pandemonium") - place[0] = tolower(place[0]); - return (place.find("level") == 0? - "on " + place - : "in " + place); + return prep_branch_level_name(item.orig_place); } bool is_rune(const item_def &item) diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc index a7a117febe..d7d3757626 100644 --- a/crawl-ref/source/message.cc +++ b/crawl-ref/source/message.cc @@ -31,7 +31,8 @@ #include "stuff.h" #include "travel.h" #include "view.h" - +#include "notes.h" +#include "stash.h" // circular buffer for keeping past messages message_item Store_Message[ NUM_STORED_MESSAGES ]; // buffer of old messages @@ -266,6 +267,16 @@ void mpr(const char *inf, int channel, int param) if (colour == MSGCOL_MUTED) return; + std::string imsg = inf; + + for (unsigned i = 0; i < Options.note_messages.size(); ++i) { + if (Options.note_messages[i].matches(imsg)) { + take_note(Note(NOTE_MESSAGE, channel, param, inf, + prep_branch_level_name().c_str())); + break; + } + } + interrupt_activity( AI_MESSAGE, channel_to_str(channel) + ":" + inf ); // If you're travelling, only certain user-specified messages can break diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 4db073c884..641662f184 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -1595,6 +1595,7 @@ int mons_del_ench( struct monsters *mon, unsigned int ench, unsigned int ench2, strcat( info, " appears!" ); mpr( info ); } + seen_monster(mon); } } diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 804abb6f91..beef83df3c 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -20,6 +20,7 @@ #include "player.h" #include "stuff.h" #include "spells4.h" +#include "view.h" // NEW place_monster -- note that power should be set to: // 51 for abyss @@ -308,7 +309,7 @@ bool place_monster(int &id, int mon_type, int power, char behaviour, } id = place_monster_aux( mon_type, behaviour, target, px, py, lev_mons, - extra, true ); + extra, true); // now, forget about banding if the first placement failed, or there's too // many monsters already, or we successfully placed by stairs @@ -353,7 +354,7 @@ bool place_monster(int &id, int mon_type, int power, char behaviour, for(i = 1; i < band_size; i++) { place_monster_aux( band_monsters[i], behaviour, target, px, py, - lev_mons, extra, false, dur ); + lev_mons, extra, false, dur); } // placement of first monster, at least, was a success. @@ -556,6 +557,11 @@ static int place_monster_aux( int mon_type, char behaviour, int target, menv[id].foe = target; + mark_interesting_monst(&menv[id], behaviour); + + if (player_monster_visible(&menv[id]) && mons_near(&menv[id])) + seen_monster(&menv[id]); + return (id); } // end place_monster_aux() @@ -1095,6 +1101,45 @@ static int band_member(int band, int power) return (mon_type); } +static int ood_limit() { + return Options.ood_interesting; +} + +void mark_interesting_monst(struct monsters* monster, char behaviour) +{ + bool interesting = false; + + // Unique monsters are always intersting + if ( mons_is_unique(monster->type) ) + interesting = true; + // If it's never going to attack us, then not interesting + else if (behaviour == BEH_FRIENDLY || behaviour == BEH_GOD_GIFT) + interesting = false; + // Don't waste time on moname() if user isn't using this option + else if ( Options.note_monsters.size() > 0 ) + { + char namebuf[ITEMNAME_SIZE]; + moname(monster->type, true, DESC_NOCAP_A, namebuf); + + std::string iname = namebuf; + + for (unsigned i = 0; i < Options.note_monsters.size(); ++i) { + if (Options.note_monsters[i].matches(iname)) { + interesting = true; + break; + } + + } + } + else if ( you.where_are_you == BRANCH_MAIN_DUNGEON && + mons_level(monster->type) >= you.your_level + ood_limit() && + mons_level(monster->type) < 99 ) + interesting = true; + + if ( interesting ) + monster->flags |= MF_INTERESTING; +} + // PUBLIC FUNCTION -- mons_place(). int mons_place( int mon_type, char behaviour, int target, bool summoned, diff --git a/crawl-ref/source/monplace.h b/crawl-ref/source/monplace.h index e1d7259953..a3c2aa7a2c 100644 --- a/crawl-ref/source/monplace.h +++ b/crawl-ref/source/monplace.h @@ -81,4 +81,10 @@ bool place_monster( int &id, int mon_type, int power, char behaviour, monster_type rand_dragon( dragon_class_type type ); +/* *********************************************************************** + * called from: monplace monstuff + * *********************************************************************** */ +void mark_interesting_monst(struct monsters* monster, + char behaviour = BEH_SLEEP); + #endif // MONPLACE_H diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 46653fda99..3efa056b84 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -52,6 +52,7 @@ #include "spells4.h" #include "stuff.h" #include "view.h" +#include "stash.h" static bool handle_special_ability(struct monsters *monster, bolt & beem); static bool handle_pickup(struct monsters *monster); @@ -324,20 +325,6 @@ static void place_monster_corpse(struct monsters *monster) move_item_to_grid( &o, monster->x, monster->y ); } // end place_monster_corpse() -static int ood_limit() { - return Options.ood_interesting; -} - -static bool is_interesting_monster( const struct monsters *monster ) { - if ( mons_is_unique(monster->type) ) - return true; - if ( you.where_are_you == BRANCH_MAIN_DUNGEON && - mons_level(monster->type) >= you.your_level + ood_limit() && - mons_level(monster->type) < 99 ) - return true; - return false; -} - void monster_die(struct monsters *monster, char killer, int i) { int dmi; // dead monster's inventory @@ -710,11 +697,15 @@ void monster_die(struct monsters *monster, char killer, int i) if (killer != KILL_RESET && killer != KILL_DISMISSED) { - - if ( is_interesting_monster(monster) ) { + if ( MONST_INTERESTING(monster) ) { char namebuf[ITEMNAME_SIZE]; + char wherebuf[INFO_SIZE]; + moname(monster->type, true, DESC_NOCAP_A, namebuf); - take_note(Note(NOTE_KILL_MONSTER, monster->type, 0, namebuf)); + strcpy(wherebuf, prep_branch_level_name().c_str()); + + take_note(Note(NOTE_KILL_MONSTER, monster->type, 0, namebuf, + wherebuf)); } you.kills.record_kill(monster, killer, pet_kill); @@ -996,6 +987,22 @@ bool monster_polymorph( struct monsters *monster, int targetc, int power ) return (player_messaged); } + // If old monster is visible to the player, and is interesting, + // then note why the interesting monster went away. + if (player_monster_visible(monster) && mons_near(monster) + && MONST_INTERESTING(monster)) + { + char namebuf[ITEMNAME_SIZE]; + char wherebuf[INFO_SIZE]; + + moname(monster->type, true, DESC_NOCAP_A, namebuf); + + strcpy(wherebuf, prep_branch_level_name().c_str()); + + take_note(Note(NOTE_POLY_MONSTER, monster->type, 0, namebuf, + wherebuf)); + } + // messaging: {dlb} bool invis = mons_class_flag( targetc, M_INVIS ) || mons_has_ench( monster, ENCH_INVIS ); @@ -1057,6 +1064,13 @@ bool monster_polymorph( struct monsters *monster, int targetc, int power ) monster_drop_ething(monster); + // New monster type might be interesting + mark_interesting_monst(monster); + + // If new monster is visible to player, then we've seen it + if (player_monster_visible(monster) && mons_near(monster)) + seen_monster(monster); + return (player_messaged); } // end monster_polymorph() @@ -1074,6 +1088,9 @@ void monster_blink(struct monsters *monster) monster->y = ny; mgrd[nx][ny] = monster_index(monster); + + if (player_monster_visible(monster) && mons_near(monster)) + seen_monster(monster); } // end monster_blink() // allow_adjacent: allow target to be adjacent to origin @@ -5265,3 +5282,25 @@ static int map_wand_to_mspell(int wand_type) return (mzap); } + +void seen_monster(struct monsters *monster) +{ + if ( monster->flags & MF_SEEN ) + return; + + // First time we've seen this particular monster + + monster->flags |= MF_SEEN; + + if ( MONST_INTERESTING(monster) ) { + char namebuf[ITEMNAME_SIZE]; + char wherebuf[INFO_SIZE]; + + moname(monster->type, true, DESC_NOCAP_A, namebuf); + + strcpy(wherebuf, prep_branch_level_name().c_str()); + + take_note(Note(NOTE_SEEN_MONSTER, monster->type, 0, namebuf, + wherebuf)); + } +} diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h index 296ee6b14e..3cc150ffdf 100644 --- a/crawl-ref/source/monstuff.h +++ b/crawl-ref/source/monstuff.h @@ -16,6 +16,8 @@ // useful macro #define SAME_ATTITUDE(x) (mons_friendly(x)?BEH_FRIENDLY:BEH_HOSTILE) +#define MONST_INTERESTING(x) (x->flags & MF_INTERESTING) + // for definition of type monsters {dlb} #include "externs.h" // for definition of type monsters {dlb} @@ -147,5 +149,10 @@ bool hurt_monster(struct monsters *victim, int damage_dealt); * *********************************************************************** */ bool heal_monster(struct monsters *patient, int health_boost, bool permit_growth); +/* *********************************************************************** + * called from: monplace - spells2 - view + * *********************************************************************** */ +void seen_monster(struct monsters *monster); + #endif diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index bf309be117..87b0269166 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -729,6 +729,8 @@ void monster_teleport(struct monsters *monster, bool instan) return; } + bool was_seen = player_monster_visible(monster) && mons_near(monster); + simple_monster_message(monster, " disappears!"); // pick the monster up @@ -766,6 +768,14 @@ void monster_teleport(struct monsters *monster, bool instan) monster->type = MONS_GOLD_MIMIC + random2(5); monster->number = get_mimic_colour( monster ); } + + if (was_seen) + simple_monster_message(monster, " reappears nearby!"); + else + simple_monster_message(monster, " appears out of thin air!"); + + if (player_monster_visible(monster) && mons_near(monster)) + seen_monster(monster); } // end monster_teleport() void setup_dragon(struct monsters *monster, struct bolt &pbolt) diff --git a/crawl-ref/source/notes.cc b/crawl-ref/source/notes.cc index 922ae901d8..77039f5fe2 100644 --- a/crawl-ref/source/notes.cc +++ b/crawl-ref/source/notes.cc @@ -89,8 +89,11 @@ static bool is_noteworthy( const Note& note ) { note.type == NOTE_GOD_GIFT || note.type == NOTE_GET_MUTATION || note.type == NOTE_LOSE_MUTATION || + note.type == NOTE_SEEN_MONSTER || note.type == NOTE_KILL_MONSTER || + note.type == NOTE_POLY_MONSTER || note.type == NOTE_USER_NOTE || + note.type == NOTE_MESSAGE || note.type == NOTE_LOSE_GOD ) return true; @@ -126,6 +129,12 @@ static bool is_noteworthy( const Note& note ) { note.first == BRANCH_MAIN_DUNGEON && note.second == 1 ) return false; + /* Learning a spell is always noteworthy if note_all_spells is set */ + + if ( note.type == NOTE_LEARN_SPELL && Options.note_all_spells ) + return true; + + unsigned i; for ( i = 0; i < note_list.size(); ++i ) { if ( note_list[i].type != note.type ) @@ -159,10 +168,12 @@ static bool is_noteworthy( const Note& note ) { return false; break; default: - mpr("Buggy note passed"); - break; - } + mpr("Buggy note passed: unknown note type"); + // Return now, rather than give a "Buggy note passed" message + // for each note of the matching type in the note list. + return true; } + } // for ( i = 0; i < note_list.size(); ++i ) return true; } @@ -178,6 +189,7 @@ const char* number_to_ordinal( int number ) { std::string describe_note( const Note& note ) { char buf[200], buf2[50]; + switch ( note.type ) { case NOTE_HP_CHANGE: sprintf(buf, "Had %d/%d hit points", note.first, note.second); @@ -215,6 +227,10 @@ std::string describe_note( const Note& note ) { god_name(note.first)); break; case NOTE_ID_ITEM: + if (note.desc.length() > 0) + sprintf(buf, "Identified %s (%s)", note.name.c_str(), + note.desc.c_str()); + else sprintf(buf, "Identified %s", note.name.c_str()); break; case NOTE_GET_ITEM: @@ -224,8 +240,20 @@ std::string describe_note( const Note& note ) { sprintf(buf, "Reached skill %d in %s", note.second, skill_name(note.first)); break; + case NOTE_SEEN_MONSTER: + sprintf(buf, "Became aware of %s while %s", note.name.c_str(), + note.desc.c_str() + ); + break; case NOTE_KILL_MONSTER: - sprintf(buf, "Defeated %s", note.name.c_str()); + sprintf(buf, "Defeated %s while %s", note.name.c_str(), + note.desc.c_str() + ); + break; + case NOTE_POLY_MONSTER: + sprintf(buf, "%s changed form while %s", note.name.c_str(), + note.desc.c_str() + ); break; case NOTE_GOD_POWER: sprintf(buf, "Acquired %s's %s power", god_name(note.first), @@ -243,8 +271,11 @@ std::string describe_note( const Note& note ) { case NOTE_USER_NOTE: sprintf(buf, "%s", note.name.c_str()); break; + case NOTE_MESSAGE: + sprintf(buf, "%s (while %s)", note.name.c_str(),note.desc.c_str()); + break; default: - sprintf(buf, "Buggy note description"); + sprintf(buf, "Buggy note description: unknown note type"); break; } sprintf(buf2, "Turn %ld: ", note.turn ); @@ -255,10 +286,12 @@ Note::Note() { turn = you.num_turns; } -Note::Note( NOTE_TYPES t, int f, int s, const char* n ) : +Note::Note( NOTE_TYPES t, int f, int s, const char* n, const char* d ) : type(t), first(f), second(s) { if (n) name = std::string(n); + if (d) + desc = std::string(d); turn = you.num_turns; } @@ -268,6 +301,7 @@ void Note::save( FILE* fp ) const { writeLong( fp, first ); writeLong( fp, second ); writeString( fp, name ); + writeString( fp, desc ); } void Note::load( FILE* fp ) { @@ -276,6 +310,7 @@ void Note::load( FILE* fp ) { first = readLong( fp ); second = readLong( fp ); name = readString( fp ); + desc = readString( fp ); } bool notes_active = false; diff --git a/crawl-ref/source/notes.h b/crawl-ref/source/notes.h index 165ca6cf13..8a97059112 100644 --- a/crawl-ref/source/notes.h +++ b/crawl-ref/source/notes.h @@ -32,19 +32,24 @@ enum NOTE_TYPES { /* NOT HOOKED YET */ NOTE_GET_ITEM, /* needs: item name (string) */ NOTE_GAIN_SKILL, /* needs: skill id, level */ + NOTE_SEEN_MONSTER, /* needs: monster name (string) */ NOTE_KILL_MONSTER, /* needs: monster name (string) */ + NOTE_POLY_MONSTER, /* needs: monster name (string) */ NOTE_USER_NOTE, /* needs: description string */ + NOTE_MESSAGE, /* needs: message string */ NOTE_LOSE_GOD, /* needs: god id */ NOTE_NUM_TYPES }; struct Note { Note(); - Note( NOTE_TYPES t, int f = 0, int s = 0, const char* n = 0 ); + Note( NOTE_TYPES t, int f = 0, int s = 0, const char* n = 0, + const char* d = 0); NOTE_TYPES type; int first, second; long turn; std::string name; + std::string desc; void load( FILE* fp ); void save( FILE* fp ) const; }; diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index 08ee5daeac..3f243dcaf0 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -201,6 +201,8 @@ unsigned char detect_creatures( int pow ) struct monsters *mon = &menv[ mgrd[i][j] ]; mark_detected_creature(i, j, mon, fuzz_chance, fuzz_radius); + seen_monster(mon); + // Assuming that highly intelligent spellcasters can // detect scyring. -- bwr if (mons_intel( mon->type ) == I_HIGH diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc index dbdfef440d..a5d6f59574 100644 --- a/crawl-ref/source/stash.cc +++ b/crawl-ref/source/stash.cc @@ -1605,3 +1605,30 @@ std::string branch_level_name(unsigned short packed_place) { return branch_level_name(packed_place >> 8, packed_place & 0xFF); } + +// Prepositional form of branch level name. For example, "in the +// Abyss" or "on level 3 of the Main Dungeon". +std::string prep_branch_level_name(unsigned char branch, int sub_depth) +{ + std::string place = branch_level_name(branch, sub_depth); + if (place.length() && place != "Pandemonium") + place[0] = tolower(place[0]); + return (place.find("level") == 0? + "on " + place + : "in " + place); +} + +std::string prep_branch_level_name(unsigned short packed_place) +{ + return prep_branch_level_name(packed_place >> 8, packed_place & 0xFF); +} + +// Use current branch and depth +std::string prep_branch_level_name() +{ + int branch = you.where_are_you; + int sub_depth = subdungeon_depth( branch, you.your_level ); + + return prep_branch_level_name(branch, sub_depth); +} + diff --git a/crawl-ref/source/stash.h b/crawl-ref/source/stash.h index 5e36eb4a61..dafe707c82 100644 --- a/crawl-ref/source/stash.h +++ b/crawl-ref/source/stash.h @@ -321,6 +321,14 @@ std::string branch_level_name(unsigned char branch, int sub_depth); std::string branch_level_name(unsigned short packed_place); +// Prepositional form of branch level name. For example, "in the +// Abyss" or "on level 3 of the Main Dungeon". +std::string prep_branch_level_name(unsigned char branch, int sub_depth); + +std::string prep_branch_level_name(unsigned short packed_place); + +std::string prep_branch_level_name(); + std::string userdef_annotate_item(const char *s, const item_def *item, bool exclusive = false); diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 23f4b06976..5fd079633d 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -1210,6 +1210,8 @@ void monster_grid(bool do_updates) && !mons_class_flag( monster->type, M_NO_EXP_GAIN )) { interrupt_activity( AI_SEE_MONSTER ); + seen_monster( monster ); + if (you.running != 0 #ifdef CLUA_BINDINGS && clua.callbooleanfn(true, "ch_stop_run", -- cgit v1.2.3-54-g00ecf