summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc4
-rw-r--r--crawl-ref/source/menu.cc28
-rw-r--r--crawl-ref/source/message.cc244
-rw-r--r--crawl-ref/source/message.h5
-rw-r--r--crawl-ref/source/output.cc4
-rw-r--r--crawl-ref/source/tutorial.cc140
6 files changed, 252 insertions, 173 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 7c45aa60a3..1766076e1f 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -221,8 +221,8 @@ int main( int argc, char *argv[] )
bool game_start = initialise();
- // override some options for tutorial
- init_tutorial_options();
+ // override some options for tutorial
+ init_tutorial_options();
if (game_start || Options.always_greet)
{
diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc
index bc7ee61821..35e054f0d9 100644
--- a/crawl-ref/source/menu.cc
+++ b/crawl-ref/source/menu.cc
@@ -1180,13 +1180,13 @@ int linebreak_string2( std::string& s, int maxcol )
// hard linebreak
else if ( xpos >= maxcol )
{
- if (spacepos >= xpos-maxcol)
+ if (spacepos >= xpos-maxcol)
{
- loc = spacepos;
- s.replace(loc, 1, "\n");
- }
- else
- s.insert(loc, "\n");
+ loc = spacepos;
+ s.replace(loc, 1, "\n");
+ }
+ else
+ s.insert(loc, "\n");
xpos = 0;
++breakcount;
}
@@ -1212,19 +1212,21 @@ void print_formatted_paragraph(std::string &s, int maxcol, int channel)
{
linebreak_string2(s,maxcol);
std::string text;
-
+
size_t loc = 0, oldloc = 0;
while ( loc < s.size() )
{
if (s[loc] == '\n') {
- text = s.substr(oldloc, loc-oldloc);
- formatted_mpr( formatted_string::parse_string(text), channel );
- oldloc = ++loc;
- }
+ text = s.substr(oldloc, loc-oldloc);
+// formatted_mpr( formatted_string::parse_string(text), channel );
+ formatted_message_history( text, channel );
+ oldloc = ++loc;
+ }
loc++;
}
- formatted_mpr( formatted_string::parse_string( s.substr(oldloc, loc-oldloc) ), channel );
-}
+// formatted_mpr( formatted_string::parse_string( s.substr(oldloc, loc-oldloc) ), channel );
+ formatted_message_history( s.substr(oldloc, loc-oldloc), channel );
+}
bool formatted_scroller::jump_to( int i )
{
diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc
index 4bad0ce3d1..d1b1a45ff8 100644
--- a/crawl-ref/source/message.cc
+++ b/crawl-ref/source/message.cc
@@ -308,34 +308,25 @@ void mpr(const char *inf, int channel, int param)
}
}
-static bool need_prefix = false;
-static void base_mpr(const char *inf, int channel, int param)
+// checks whether a given message contains patterns relevant for
+// notes, stop_running or sounds and handles these cases
+static void mpr_check_patterns(std::string message, int channel, int param)
{
- if (suppress_messages)
- return;
-
- int colour = channel_to_colour( channel, 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))
+ if (Options.note_messages[i].matches(message))
{
- take_note(Note(NOTE_MESSAGE, channel, param, inf));
+ take_note(Note( NOTE_MESSAGE, channel, param, message.c_str() ));
break;
}
}
if (channel != MSGCH_DIAGNOSTICS && channel != MSGCH_EQUIPMENT)
- interrupt_activity( AI_MESSAGE, channel_to_str(channel) + ":" + inf );
+ interrupt_activity( AI_MESSAGE, channel_to_str(channel) + ":" + message );
// Check messages for all forms of running now.
if (you.running)
{
- std::string message = inf;
for (unsigned i = 0; i < Options.travel_stop_message.size(); ++i)
{
if (Options.travel_stop_message[i].is_filtered( channel, message ))
@@ -346,12 +337,11 @@ static void base_mpr(const char *inf, int channel, int param)
}
}
- if (!Options.sound_mappings.empty())
+ if (!Options.sound_mappings.empty())
{
- std::string message = inf;
- for (unsigned i = 0; i < Options.sound_mappings.size(); i++)
+ for (unsigned i = 0; i < Options.sound_mappings.size(); i++)
{
- // Maybe we should allow message channel matching as for
+ // Maybe we should allow message channel matching as for
// travel_stop_message?
if (Options.sound_mappings[i].pattern.matches(message))
{
@@ -361,44 +351,19 @@ static void base_mpr(const char *inf, int channel, int param)
}
}
- if (!Options.message_colour_mappings.empty())
- {
- std::string message = inf;
- for (int i = 0, size = Options.message_colour_mappings.size();
- i < size; ++i)
- {
- const message_colour_mapping &m =
- Options.message_colour_mappings[i];
- if (m.message.is_filtered(channel, message))
- {
- colour = m.colour;
- break;
- }
- }
- }
-
- flush_input_buffer( FLUSH_ON_MESSAGE );
+}
+// adds a given message to the message history
+static void mpr_store_messages(std::string message, int channel, int param)
+{
const int num_lines = get_message_window_height();
-
- if (New_Message_Count == num_lines - 1)
- more();
-
- if (need_prefix)
- {
- message_out( Message_Line, colour, "-", 1, false );
- need_prefix = false;
- }
-
- message_out( Message_Line, colour, inf,
- Options.delay_message_clear? 2 : 1 );
// Prompt lines are presumably shown to / seen by the player accompanied
// by a request for input, which should do the equivalent of a more(); to
// save annoyance, don't bump New_Message_Count for prompts.
if (channel != MSGCH_PROMPT)
New_Message_Count++;
-
+
if (Message_Line < num_lines - 1)
Message_Line++;
@@ -409,7 +374,7 @@ static void base_mpr(const char *inf, int channel, int param)
if (channel != MSGCH_EQUIPMENT)
{
// Put the message into Store_Message, and move the '---' line forward
- Store_Message[ Next_Message ].text = inf;
+ Store_Message[ Next_Message ].text = message.c_str();
Store_Message[ Next_Message ].channel = channel;
Store_Message[ Next_Message ].param = param;
Next_Message++;
@@ -417,15 +382,10 @@ static void base_mpr(const char *inf, int channel, int param)
if (Next_Message >= NUM_STORED_MESSAGES)
Next_Message = 0;
}
-} // end mpr()
-
+}
-// Line wrapping is not available here!
-// Note that the colour will be first set to the appropriate channel
-// colour before displaying the formatted_string.
-// XXX This code just reproduces base_mpr(). There must be a better
-// way to do this.
-void formatted_mpr(const formatted_string& fs, int channel, int param)
+static bool need_prefix = false;
+static void base_mpr(const char *inf, int channel, int param)
{
if (suppress_messages)
return;
@@ -434,42 +394,21 @@ void formatted_mpr(const formatted_string& fs, int channel, int param)
if (colour == MSGCOL_MUTED)
return;
- const std::string imsg = fs.tostring();
+ 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, imsg.c_str()));
- break;
- }
- }
-
- if (channel != MSGCH_DIAGNOSTICS && channel != MSGCH_EQUIPMENT)
- interrupt_activity(AI_MESSAGE, channel_to_str(channel) + ":" + imsg);
-
- // Check messages for all forms of running now.
- if (you.running)
- {
- for (unsigned i = 0; i < Options.travel_stop_message.size(); ++i)
- {
- if (Options.travel_stop_message[i].is_filtered(channel, imsg))
- {
- stop_running();
- break;
- }
- }
- }
-
- if (Options.sound_mappings.size() > 0)
+ mpr_check_patterns(imsg, channel, param);
+
+ if (!Options.message_colour_mappings.empty())
{
- for (unsigned i = 0; i < Options.sound_mappings.size(); i++)
+ std::string message = inf;
+ for (int i = 0, size = Options.message_colour_mappings.size();
+ i < size; ++i)
{
- // Maybe we should allow message channel matching as for
- // travel_stop_message?
- if (Options.sound_mappings[i].pattern.matches(imsg))
+ const message_colour_mapping &m =
+ Options.message_colour_mappings[i];
+ if (m.message.is_filtered(channel, message))
{
- play_sound(Options.sound_mappings[i].soundfile.c_str());
+ colour = m.colour;
break;
}
}
@@ -482,6 +421,21 @@ void formatted_mpr(const formatted_string& fs, int channel, int param)
if (New_Message_Count == num_lines - 1)
more();
+ if (need_prefix)
+ {
+ message_out( Message_Line, colour, "-", 1, false );
+ need_prefix = false;
+ }
+
+ message_out( Message_Line, colour, inf,
+ Options.delay_message_clear? 2 : 1 );
+
+ mpr_store_messages(imsg, channel, param);
+} // end mpr()
+
+
+static void mpr_formatted_output(formatted_string fs, int colour)
+{
int curcol = 1;
if (need_prefix)
@@ -509,33 +463,65 @@ void formatted_mpr(const formatted_string& fs, int channel, int param)
}
}
message_out( Message_Line, colour, "", Options.delay_message_clear? 2 : 1);
+}
- // Prompt lines are presumably shown to / seen by the player accompanied
- // by a request for input, which should do the equivalent of a more(); to
- // save annoyance, don't bump New_Message_Count for prompts.
- if (channel != MSGCH_PROMPT)
- New_Message_Count++;
+// Line wrapping is not available here!
+// Note that the colour will be first set to the appropriate channel
+// colour before displaying the formatted_string.
+// XXX This code just reproduces base_mpr(). There must be a better
+// way to do this.
+void formatted_mpr(const formatted_string& fs, int channel, int param)
+{
+ if (suppress_messages)
+ return;
+
+ int colour = channel_to_colour( channel, param );
+ if (colour == MSGCOL_MUTED)
+ return;
+
+ const std::string imsg = fs.tostring();
- if (Message_Line < num_lines - 1)
- Message_Line++;
+ mpr_check_patterns(imsg, channel, param);
- // reset colour
- textcolor(LIGHTGREY);
+ flush_input_buffer( FLUSH_ON_MESSAGE );
- // equipment lists just waste space in the message recall
- if (channel != MSGCH_EQUIPMENT)
- {
- // Put the message into Store_Message, and move the '---' line forward
- Store_Message[ Next_Message ].text = imsg.c_str();
- Store_Message[ Next_Message ].channel = channel;
- Store_Message[ Next_Message ].param = param;
- Next_Message++;
+ const int num_lines = get_message_window_height();
+
+ if (New_Message_Count == num_lines - 1)
+ more();
+
+ mpr_formatted_output(fs, colour);
- if (Next_Message >= NUM_STORED_MESSAGES)
- Next_Message = 0;
- }
+ mpr_store_messages(imsg, channel, param);
}
+// output given string as formatted message, but check patterns
+// for string stripped of tags and store original tagged string
+// for message history
+void formatted_message_history(const std::string st, int channel, int param)
+{
+ if (suppress_messages)
+ return;
+
+ int colour = channel_to_colour( channel, param );
+ if (colour == MSGCOL_MUTED)
+ return;
+
+ formatted_string fs = formatted_string::parse_string(st);
+
+ mpr_check_patterns(fs.tostring(), channel, param);
+
+ flush_input_buffer( FLUSH_ON_MESSAGE );
+
+ const int num_lines = get_message_window_height();
+
+ if (New_Message_Count == num_lines - 1)
+ more();
+
+ mpr_formatted_output(fs, colour);
+
+ mpr_store_messages(st, channel, param);
+}
bool any_messages(void)
{
@@ -676,18 +662,36 @@ void replay_messages(void)
textcolor( colour );
+ std::string text = Store_Message[ line ].text;
+ // for tutorial texts (for now, used for debugging)
+ // allow formatted output of tagged messages
+ if (Store_Message[ line ].channel == MSGCH_TUTORIAL)
+ {
+ formatted_string fs = formatted_string::parse_string(text);
+ int curcol = 1;
+ for ( unsigned int j = 0; j < fs.ops.size(); ++j )
+ {
+ switch ( fs.ops[j].type )
+ {
+ case FSOP_COLOUR:
+ colour = fs.ops[j].x;
+ break;
+ case FSOP_TEXT:
+ textcolor( colour );
+ gotoxy(curcol, wherey());
+ cprintf(fs.ops[j].text.c_str());
+ curcol += fs.ops[j].text.length();
+ break;
+ case FSOP_CURSOR:
+ break;
+ }
+ }
+ }
+ else
#if DEBUG_DIAGNOSTICS
- cprintf( "%d: %s", line, Store_Message[ line ].text.c_str() );
+ cprintf( "%d: %s", line, text.c_str() );
#else
- /* TODO: allow colour changes in previous messages, as well
- if (Store_Message[ line ].channel == MSGCH_TUTORIAL)
- {
- formatted_string help = formatted_string::parse_string(Store_Message[ line ].text);
- help.display();
- }
- else
- */
- cprintf( "%s", Store_Message[ line ].text.c_str() );
+ cprintf( "%s", text.c_str() );
#endif
cprintf(EOL);
diff --git a/crawl-ref/source/message.h b/crawl-ref/source/message.h
index ec6e4258af..0d82a195d3 100644
--- a/crawl-ref/source/message.h
+++ b/crawl-ref/source/message.h
@@ -59,7 +59,10 @@ class formatted_string;
void formatted_mpr(const formatted_string& fs, int channel = MSGCH_PLAIN,
int param = 0);
-
+
+void formatted_message_history(const std::string st,
+ int channel = MSGCH_PLAIN, int param = 0);
+
// 4.1-style mpr, currently named mprf for minimal disruption.
void mprf( int channel, const char *format, ... );
void mprf( const char *format, ... );
diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc
index 2d952b5919..5789c3f879 100644
--- a/crawl-ref/source/output.cc
+++ b/crawl-ref/source/output.cc
@@ -973,7 +973,7 @@ void print_overview_screen()
bool calc_unid = false;
formatted_scroller cmd_help;
// Set flags, and don't use easy exit.
- cmd_help.set_flags(MF_NOSELECT | MF_NOWRAP, false);
+ cmd_help.set_flags(MF_NOSELECT | MF_ALWAYS_SHOW_MORE | MF_NOWRAP, false);
cmd_help.set_more( formatted_string::parse_string(
"<cyan>[ + : Page down. - : Page up. Esc exits.]"));
@@ -1563,8 +1563,8 @@ std::string status_mut_abilities()
text += ", able to fly";
if (you.experience_level > 14)
text += " continuously";
- have_any = true;
}
+ have_any = true;
break;
case SP_MUMMY:
diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc
index 6cbe6f8a47..3c3b04cbc2 100644
--- a/crawl-ref/source/tutorial.cc
+++ b/crawl-ref/source/tutorial.cc
@@ -22,7 +22,7 @@
//#define TUTORIAL_DEBUG
#define TUTORIAL_VERSION 110
-int COLS = get_number_of_cols();
+int COLS = (get_number_of_cols() > 80) ? 80 : get_number_of_cols();
void save_tutorial( FILE* fp )
{
@@ -226,7 +226,7 @@ static formatted_string tut_starting_info(unsigned int width)
linebreak_string2(text, width);
result += formatted_string::parse_string(text);
- result += "For the moment, just remember the following two keys and their functions:" EOL;
+ result += "For the moment, just remember the following keys and their functions:" EOL;
result += " <white>?</white> - shows the items and the commands" EOL;
result += " <white>S</white> - saves the game, to be resumed later (but note that death is permanent)" EOL;
result += " <white>x</white> - examine something in your vicinity" EOL EOL;
@@ -257,7 +257,7 @@ static std::string tut_debug_list(int event)
case TUT_SEEN_FIRST_OBJECT:
return "seen first object";
case TUT_SEEN_POTION:
- return "seen first potion";
+ return "seen first potion";
case TUT_SEEN_SCROLL:
return "seen first scroll";
case TUT_SEEN_WAND:
@@ -781,23 +781,84 @@ void taken_new_item(unsigned char item_type)
}
}
+static std::string colour_to_tag(int col, bool closed = false)
+{
+ std::string tag = "<";
+ if (closed)
+ tag += "/";
+ switch(col)
+ {
+ case WHITE:
+ tag += "w";
+ break;
+ case YELLOW:
+ tag += "yellow";
+ break;
+ case RED:
+ tag += "red";
+ break;
+ case LIGHTRED:
+ tag += "lightred";
+ break;
+ case MAGENTA:
+ tag += "magenta";
+ break;
+ case LIGHTMAGENTA:
+ tag += "lightmagenta";
+ break;
+ case GREEN:
+ tag += "green";
+ break;
+ case LIGHTGREEN:
+ tag += "lightgreen";
+ break;
+ case BLUE:
+ tag += "blue";
+ break;
+ case LIGHTBLUE:
+ tag += "lightblue";
+ break;
+ case CYAN:
+ tag += "cyan";
+ break;
+ case LIGHTCYAN:
+ tag += "lightcyan";
+ break;
+ case BLACK:
+ tag += "black";
+ break;
+ case BROWN:
+ tag += "brown";
+ break;
+ case DARKGREY:
+ tag += "darkgrey";
+ break;
+ default:
+ tag += "lightgrey";
+ }
+ tag += ">";
+
+ return tag;
+
+}
+
void tutorial_first_monster(monsters mon)
{
if (!Options.tutorial_events[TUT_SEEN_MONSTER])
return;
+ unsigned short ch, col;
+ get_mons_glyph(&mon, &ch, &col);
+
std::string text = "<magenta>That ";
- formatted_string st = formatted_string::parse_string(text);
- st.formatted_string::textcolor(channel_to_colour(MSGCH_TUTORIAL));
- st.formatted_string::add_glyph(&mon);
- text = " is a monster, usually depicted by a letter. Some typical early monsters ";
- st += formatted_string::parse_string(text);
- formatted_mpr(st, MSGCH_TUTORIAL);
-
- text = "look like <brown>r<magenta>, <w>g<magenta>, <lightgray>b<magenta> or "
- "<brown>K<magenta>. You can gain information about it by pressing "
- "<w>x<magenta>, moving the cursor on the monster and then pressing "
- "<w>v<magenta>. To attack it with your wielded weapon, just move into it.";
+ text += colour_to_tag(col);
+ text += ch;
+ text += "<magenta> is a monster, usually depicted by a letter. Some typical "
+ "early monsters look like <brown>r<magenta>, <w>g<magenta>, "
+ "<lightgray>b<magenta> or <brown>K<magenta>. You can gain "
+ "information about it by pressing <w>x<magenta>, moving the cursor "
+ "on the monster and then pressing <w>v<magenta>. To attack it with "
+ "your wielded weapon, just move into it.";
print_formatted_paragraph(text, COLS, MSGCH_TUTORIAL);
more();
@@ -836,19 +897,17 @@ void tutorial_first_item(item_def item)
if (!Options.tutorial_events[TUT_SEEN_FIRST_OBJECT] || Options.tut_just_triggered)
return;
+ unsigned short ch, col;
+ get_item_glyph(&item, &ch, &col);
+
std::string text = "<magenta>That ";
- formatted_string st = formatted_string::parse_string(text);
- st.formatted_string::textcolor(channel_to_colour(MSGCH_TUTORIAL));
- st.formatted_string::add_glyph(&item);
- text = " is an item. If you move there and press <w>g<magenta> or "
- "<w>,<magenta> you will pick it up.";
- st += formatted_string::parse_string(text);
- formatted_mpr(st, MSGCH_TUTORIAL);
-
- text = "Generally, items are shown by non-letter symbols like "
- "<w>%%?!\"=()[<magenta>. Once it is in your inventory, you can drop "
- "it again with <w>d<magenta>. Several types of objects will usually "
- "be picked up automatically.";
+ text += colour_to_tag(col);
+ text += ch;
+ text += "<magenta> is an item. If you move there and press <w>g<magenta> or "
+ "<w>,<magenta> you will pick it up. Generally, items are shown by "
+ "non-letter symbols like <w>%%?!\"=()[<magenta>. Once it is in your "
+ "inventory, you can drop it again with <w>d<magenta>. Several types "
+ "of objects will usually be picked up automatically.";
print_formatted_paragraph(text, COLS, MSGCH_TUTORIAL);
Options.tutorial_events[TUT_SEEN_FIRST_OBJECT] = 0;
@@ -869,6 +928,9 @@ void learned_something_new(unsigned int seen_what, int x, int y)
std::string text;
unsigned short ch, colour;
+ const int ex = x - you.x_pos + 9;
+ const int ey = y - you.y_pos + 9;
+ int object;
switch(seen_what)
{
@@ -886,9 +948,8 @@ void learned_something_new(unsigned int seen_what, int x, int y)
break;
case TUT_SEEN_SPBOOK:
get_item_symbol(DNGN_ITEM_BOOK, &ch, &colour);
- snprintf(info, INFO_SIZE, "%c", ch);
text = "You have picked up a spellbook ('<w>";
- text += info;
+ text += ch;
text += "'<magenta>). You can read it by typing <w>r<magenta>, "
"memorise spells via <w>M<magenta> and cast a memorised spell "
"with <w>Z<magenta>.";
@@ -982,10 +1043,9 @@ void learned_something_new(unsigned int seen_what, int x, int y)
break;
case TUT_SEEN_STAFF:
get_item_symbol(DNGN_ITEM_STAVE, &ch, &colour);
- snprintf(info, INFO_SIZE, "%c", ch);
text = "You have picked up a magic staff or a rod, both of which are "
"represented by '<w>";
- text += info;
+ text += ch;
text += "<magenta>'. Both must be <w>i<magenta>elded to be of use. "
"Magicians use staves to increase their power in certain spell "
"schools. By contrast, a rod allows the casting of certain "
@@ -997,8 +1057,13 @@ void learned_something_new(unsigned int seen_what, int x, int y)
if (you.num_turns < 1)
return;
+ object = env.show[ex][ey];
+ colour = env.show_col[ex][ey];
+ get_item_symbol( object, &ch, &colour );
+
text = "The <w>";
- text += get_screen_glyph(x,y);
+ text += colour_to_tag(colour);
+ text += ch;
text += "<magenta> are some downstairs. You can enter the next (deeper) "
"level by following them down (<w>><magenta>). To get back to "
"this level again, press <w><<<magenta> while standing on the "
@@ -1013,8 +1078,13 @@ void learned_something_new(unsigned int seen_what, int x, int y)
"effects, like teleportation.";
break;
case TUT_SEEN_ALTAR:
- text = "The <blue>";
- text += get_screen_glyph(x,y);
+ object = env.show[ex][ey];
+ colour = env.show_col[ex][ey];
+ get_item_symbol( object, &ch, &colour );
+
+ text = "The ";
+ text += colour_to_tag(colour);
+ text += ch;
text += "<magenta> is an altar. You can get information about it by pressing "
"<w>p<magenta> while standing on the square. Before taking up "
"the responding faith you'll be asked for confirmation.";
@@ -1103,7 +1173,7 @@ void learned_something_new(unsigned int seen_what, int x, int y)
text = "There are two ways to overcome hunger: food you started "
"with or found, and selfmade chunks from corpses. To get the "
"latter, all you need to do is <w>D<magenta> a corpse with a "
- "sharp implement. Your starting weapon will do nicely."
+ "sharp implement. Your starting weapon will do nicely. "
"Try to dine on chunks in order to save permanent food.";
break;
case TUT_YOU_STARVING:
@@ -1217,7 +1287,7 @@ void learned_something_new(unsigned int seen_what, int x, int y)
"danger of dying, check your options carefully. Often, retreat or "
"use of some item might be a viable alternative to fighting on.";
if (you.species == SP_CENTAUR)
- text += "As a four-legged centaur you are particularly quick - "
+ text += " As a four-legged centaur you are particularly quick - "
"running is an option! ";
if (Options.tutorial_type == TUT_BERSERK_CHAR && !you.berserker)
{