moved some overlapping parts of base_mpr and formatted_mpr into separate functions. This makes them more readable and avoids code duplication.
I'm uncertain as to whether translating every string in replay_messages into a formatted string (just in case) would be overkill - so for now that only happens for messages of MSGCH_TUTORIAL.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1071 c06c8d41-db1a-0410-9941-cceddc491573
6HQB2N6N75R2RGKJFWRUN7WAC2PNGWQFXTII5DTRLTHZ2BOTMTVAC
5RK245FAGZFCDDYG4AZAXSC7JPVIJG4DSAVAKHWWVBUNGICHYNJQC
7NDXS36TE7QVXTXJWMYSVG5UHCCLPIO4VL6NXFGTDK3ZNKE3A2IAC
77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
ID2OZJTHFXL74RVUCS3JCMDQEUHAXCQFZU7235VU6IEVAAUWD2FAC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
GCIZIUXO5TYROKDUYB3HAY7H7MRDTJNM7HR7DGSH7KXDIZC2LCDAC
KU6YUIJWXZSNTABFB36HDEEZ6LTY7O4VKI3RNFBQE3LEYZCT3XQQC
LXLUKS5CKXBUSVV3QTZ4SM7NWSY6JFQEBHUBQW2VUEU5DOL3RRLAC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
RC6L3CIBLJEH4GWRFD7UQNGI6PZT74FRUVOYHSAN2XCC74NZUASQC
Q5SFQO7ANODRI6OXKHPFQ4QWKGQ367S64DPURQW2TWK7ANTYO4NQC
2GV6OW7P54FXZ5OD2NUMX7MLXH424LYAFMOAUQ2UGSOLKLYDBJGAC
}
}
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";
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);
unsigned short ch, col;
get_mons_glyph(&mon, &ch, &col);
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.";
std::string text = "<magenta>That ";
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.";
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.";
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 (!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 );
}
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 );
// 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)
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)
{
for (unsigned i = 0; i < Options.sound_mappings.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))
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)
{
// 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();
// 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);
// 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 );
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
/* 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() );
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;
}
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 );
}