/* * color.cpp * Functions to handle color. * ____ _ * | _ \ ___ __ _| |_ __ ___ ___ * | |_) / _ \/ _` | | '_ ` _ \/ __| * | _ < __/ (_| | | | | | | \__ \ * |_| \_\___|\__,_|_|_| |_| |_|___/ * * Permission to use, modify and distribute is granted via the * Creative Commons - Attribution - Non Commercial - Share Alike 3.0 License * http://creativecommons.org/licenses/by-nc-sa/3.0/ * * Copyright (C) 2007-2009 Jason Mitchell, Randi Mitchell * Contributions by Tim Callahan, Jonathan Hseu * Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman * */ #include "mud.h" #include "login.h" #include "commands.h" #include <sstream> #define CLEAR "\033[0m" // Resets color #define C_BLACK "\033[0;30m" // Normal colors #define C_RED "\033[0;31m" #define C_GREEN "\033[0;32m" #define C_YELLOW "\033[0;33m" #define C_BLUE "\033[0;34m" #define C_MAGENTA "\033[0;35m" #define C_CYAN "\033[0;36m" #define C_WHITE "\033[0;37m" #define C_D_GREY "\033[1;30m" // Light Colors #define C_B_RED "\033[1;31m" #define C_B_GREEN "\033[1;32m" #define C_B_YELLOW "\033[1;33m" #define C_B_BLUE "\033[1;34m" #define C_B_MAGENTA "\033[1;35m" #define C_B_CYAN "\033[1;36m" #define C_B_WHITE "\033[1;37m" #define C_BOLD "\033[1m" #define C_BLINK "\033[5m" int Ansi[12] = { 30, 31, 32, 33, 34, 35, 36, 37, 1, 0, 5 }; int Mirc[9] = { 1, 4, 9, 8, 12, 13, 11, 15, 15 }; //*********************************************************************** // nameToColorCode //*********************************************************************** char nameToColorCode(bstring name) { name = name.toLower(); if(name == "blink") return('!'); if(name == "blue") return('b'); if(name == "bold blue") return('B'); if(name == "red") return('r'); if(name == "bold red") return('R'); if(name == "cyan") return('c'); if(name == "bold cyan") return('C'); if(name == "green") return('g'); if(name == "bold green") return('G'); if(name == "magenta") return('m'); if(name == "bold magenta") return('M'); if(name == "yellow") return('y'); if(name == "bold yellow") return('Y'); if(name == "white") return('w'); if(name == "bold white") return('W'); if(name == "black") return('d'); if(name == "grey") return('D'); if(name == "gold") return('l'); if(name == "cerulean") return('e'); if(name == "pink") return('p'); if(name == "sky blue") return('s'); if(name == "brown") return('o'); return('x'); } //*********************************************************************** // getColor //*********************************************************************** const char* colorCodeToColor(const char type) { switch(type) { case 'd': return(C_BLACK); case 'b': return(C_BLUE); case 'E': case 'c': return(C_CYAN); case 'g': return(C_GREEN); case 'm': return(C_MAGENTA); case 'r': return(C_RED); case 'w': return(C_WHITE); case 'o': case 'y': return(C_YELLOW); case 'B': return(C_B_BLUE); case 'e': case 'C': return(C_B_CYAN); case 'G': return(C_B_GREEN); case 'M': return(C_B_MAGENTA); case 'R': return(C_B_RED); case 'W': return(C_B_WHITE); case 'Y': return(C_B_YELLOW); case 'D': return(C_D_GREY); case '@': return(C_BOLD); case '#': return(C_BLINK); case '^': return("^"); case 'x': default: return(CLEAR C_WHITE); } } //********************************************************************* // getCustomColor //********************************************************************** bstring Player::getCustomColor(CustomColor i, bool caret) const { char color; if(customColors[(int)i] != CUSTOM_COLOR_DEFAULT) { color = customColors[(int)i]; if(color == '!') color = '#'; return((bstring)(caret?"^":"") + color); } return(gConfig->getCustomColor(i, caret)); } bstring Config::getCustomColor(CustomColor i, bool caret) const { if(customColors[(int)i] == CUSTOM_COLOR_DEFAULT) return((bstring)(caret?"^":"") + "x"); return((bstring)(caret?"^":"") + customColors[(int)i]); } //********************************************************************* // customColorize //********************************************************************** const char* Monster::customColorize(bstring text, bool caret) const { if(following && following->isPlayer()) text = following->getConstPlayer()->customColorize(text, caret); return(text.c_str()); } const char* Player::customColorize(bstring text, bool caret) const { text.Replace("*CC:BROADCAST*", getCustomColor(CUSTOM_COLOR_BROADCAST, caret).c_str()); text.Replace("*CC:GOSSIP*", getCustomColor(CUSTOM_COLOR_GOSSIP, caret).c_str()); text.Replace("*CC:PTEST*", getCustomColor(CUSTOM_COLOR_PTEST, caret).c_str()); text.Replace("*CC:NEWBIE*", getCustomColor(CUSTOM_COLOR_NEWBIE, caret).c_str()); text.Replace("*CC:DM*", getCustomColor(CUSTOM_COLOR_DM, caret).c_str()); text.Replace("*CC:ADMIN*", getCustomColor(CUSTOM_COLOR_ADMIN, caret).c_str()); text.Replace("*CC:SEND*", getCustomColor(CUSTOM_COLOR_SEND, caret).c_str()); text.Replace("*CC:MESSAGE*", getCustomColor(CUSTOM_COLOR_MESSAGE, caret).c_str()); text.Replace("*CC:WATCHER*", getCustomColor(CUSTOM_COLOR_WATCHER, caret).c_str()); text.Replace("*CC:CLASS*", getCustomColor(CUSTOM_COLOR_CLASS, caret).c_str()); text.Replace("*CC:RACE*", getCustomColor(CUSTOM_COLOR_RACE, caret).c_str()); text.Replace("*CC:CLAN*", getCustomColor(CUSTOM_COLOR_CLAN, caret).c_str()); text.Replace("*CC:TELL*", getCustomColor(CUSTOM_COLOR_TELL, caret).c_str()); text.Replace("*CC:GROUP*", getCustomColor(CUSTOM_COLOR_GROUP, caret).c_str()); text.Replace("*CC:DAMAGE*", getCustomColor(CUSTOM_COLOR_DAMAGE, caret).c_str()); text.Replace("*CC:SELF*", getCustomColor(CUSTOM_COLOR_SELF, caret).c_str()); text.Replace("*CC:GUILD*", getCustomColor(CUSTOM_COLOR_GUILD, caret).c_str()); return(text.c_str()); } //********************************************************************* // resetCustomColors //********************************************************************** void Player::resetCustomColors() { memset(customColors, CUSTOM_COLOR_DEFAULT, sizeof(customColors)); customColors[CUSTOM_COLOR_SIZE-1] = 0; } //*********************************************************************** // cmdColors //*********************************************************************** // this function demonstrates all the color options available // Letters Remaining: // :: a f hijk no q tuv z // :: A F HIJKL NOPQ STUV X Z int cmdColors(Player* player, cmd* cmnd) { player->defineMXP(); if(!strcmp(cmnd->str[1], "reset")) { player->print("Custom colors have been reset to defaults.\n"); player->resetCustomColors(); return(0); } else if(cmnd->num > 2) { CustomColor i; bstring type = cmnd->str[1]; type = type.toLower(); if(type == "broadcast") i = CUSTOM_COLOR_BROADCAST; else if((type == "ptest" || type == "p-test") && isPtester(player)) i = CUSTOM_COLOR_PTEST; else if(type == "gossip") i = CUSTOM_COLOR_GOSSIP; else if(type == "newbie") i = CUSTOM_COLOR_NEWBIE; else if(type == "dm" && player->isDm()) i = CUSTOM_COLOR_DM; else if(type == "admin" && player->isAdm()) i = CUSTOM_COLOR_ADMIN; else if(type == "send" && player->isCt()) i = CUSTOM_COLOR_SEND; else if(type == "message" && player->isStaff()) i = CUSTOM_COLOR_MESSAGE; else if(type == "watcher" && player->isWatcher()) i = CUSTOM_COLOR_WATCHER; else if(type == "class") i = CUSTOM_COLOR_CLASS; else if(type == "race") i = CUSTOM_COLOR_RACE; else if(type == "clan") i = CUSTOM_COLOR_CLAN; else if(type == "tell") i = CUSTOM_COLOR_TELL; else if(type == "group") i = CUSTOM_COLOR_GROUP; else if(type == "damage") i = CUSTOM_COLOR_DAMAGE; else if(type == "self") i = CUSTOM_COLOR_SELF; else if(type == "guild") i = CUSTOM_COLOR_GUILD; else { player->print("Custom color type choice not understood.\n"); return(0); } char color = nameToColorCode(getFullstrText(cmnd->fullstr, 2)); player->setCustomColor(i, color); if(color == '!') color = '#'; player->printColor("The ^%ccustom color^x has been set.\n", color); return(0); } player->print("Colors:\n"); player->printColor(" ^%cBlue ^%cBold Blue\n", nameToColorCode("Blue"), nameToColorCode("Bold Blue")); player->printColor(" ^%cRed ^%cBold Red\n", nameToColorCode("Red"), nameToColorCode("Bold Red")); player->printColor(" ^%cCyan ^%cBold Cyan\n", nameToColorCode("Cyan"), nameToColorCode("Bold Cyan")); player->printColor(" ^%cGreen ^%cBold Green\n", nameToColorCode("Green"), nameToColorCode("Bold Green")); player->printColor(" ^%cMagenta ^%cBold Magenta\n", nameToColorCode("Magenta"), nameToColorCode("Bold Magenta")); player->printColor(" ^%cYellow ^%cBold Yellow\n", nameToColorCode("Yellow"), nameToColorCode("Bold Yellow")); player->printColor(" ^%cWhite ^%cBold White\n", nameToColorCode("White"), nameToColorCode("Bold White")); player->printColor(" ^%cBlack ^%cGrey\n", nameToColorCode("Black"), nameToColorCode("Grey")); player->printColor(" ^x^#Blink\n"); player->print("\n"); player->print("New MXP Colors:\n"); if(!player->flagIsSet(P_MXP_ENABLED)) player->printColor(" ^yYou will need to type \"set mxpcolors\" to enable the following colors.\n"); player->printColor(" ^%cGold ^%cCerulean\n", nameToColorCode("Gold"), nameToColorCode("Cerulean")); player->printColor(" ^%cPink ^%cSky Blue\n", nameToColorCode("Pink"), nameToColorCode("Sky Blue")); player->printColor(" ^%cBrown\n", nameToColorCode("Brown")); player->print("\n"); player->printColor("Custom Colors: type [color ^W<type> <color>^x]\n"); player->printColor(" Choose ^Wtype^x from below, ^Wcolor^x from above.\n"); player->printColor(" Type ^Wcolor reset^x to return to default colors.\n\n"); std::map<bstring,bstring> options; std::map<bstring,bstring>::iterator it; options["Self: @"] = player->customColorize("*CC:SELF*"); options["Broadcast"] = player->customColorize("*CC:BROADCAST*"); options["Tell"] = player->customColorize("*CC:TELL*"); options["Gossip"] = player->customColorize("*CC:GOSSIP*"); options["Newbie"] = player->customColorize("*CC:NEWBIE*"); options["Class"] = player->customColorize("*CC:CLASS*"); options["Race"] = player->customColorize("*CC:RACE*"); options["Clan"] = player->customColorize("*CC:CLAN*"); options["Group"] = player->customColorize("*CC:GROUP*"); options["Damage"] = player->customColorize("*CC:DAMAGE*"); if(player->isDm()) options["DM"] = player->customColorize("*CC:DM*"); if(player->isAdm()) options["Admin"] = player->customColorize("*CC:ADMIN*"); if(player->isCt()) options["Send"] = player->customColorize("*CC:SEND*"); if(player->isStaff()) options["Message"] = player->customColorize("*CC:MESSAGE*"); if(player->isWatcher()) options["Watcher"] = player->customColorize("*CC:WATCHER*"); if(isPtester(player)) options["P-Test"] = player->customColorize("*CC:PTEST*"); if(player->getGuild()) options["Guild"] = player->customColorize("*CC:GUILD*"); for(it = options.begin() ; it != options.end() ; ) { for(int n=0; n<3; n++) { if(it != options.end()) { player->printColor(" ^x* %s%-10s", (*it).second.c_str(), (*it).first.c_str()); it++; } } player->print("\n"); } player->print("\n"); return(0); } //*********************************************************************** // defineColors //*********************************************************************** // setup what color they want - called on new character and login of // existing character void Player::defineColors() { clearFlag(P_ANSI_COLOR); clearFlag(P_MXP_ENABLED); clearFlag(P_MIRC); clearFlag(P_NEWLINE_AFTER_PROMPT); if(mySock->color == WANTS_ANSI_COLOR) setFlag(P_ANSI_COLOR); else if(mySock->color == WANTS_MXP_COLOR) { setFlag(P_ANSI_COLOR); setFlag(P_MXP_ENABLED); defineMXP(); } else if(mySock->color == WANTS_MIRC_COLOR) { setFlag(P_MIRC); setFlag(P_NEWLINE_AFTER_PROMPT); } } //*********************************************************************** // defineMXP //*********************************************************************** void Player::defineMXP() { if(!flagIsSet(P_MXP_ENABLED) || !mySock->getMxp()) return; print("%c[1z", 27); print("<!ELEMENT c1 '<COLOR #FFD700>'>"); // gold print("<!ELEMENT c2 '<COLOR #009CFF>'>"); // cerulean print("<!ELEMENT c3 '<COLOR #FF5ADE>'>"); // pink print("<!ELEMENT c4 '<COLOR #82E6FF>'>"); // sky blue print("<!ELEMENT c5 '<COLOR #484848>'>"); // dark grey print("<!ELEMENT c6 '<COLOR #95601A>'>"); // brown printColor("%c[3z^x", 27); } //*********************************************************************** // ANSI //*********************************************************************** void ANSI(Socket* sock, int color) { if(sock && sock->getPlayer()) { if(sock->getPlayer()->flagIsSet(P_ANSI_COLOR)) { if(color & BOLD) sock->print("%c[%dm", 27, Ansi[COLOR_BOLD]); if(color & BLINK) sock->print("%c[%dm", 27, Ansi[COLOR_BLINK]); if(color & NORMAL) sock->print("%c[%dm", 27, Ansi[COLOR_NORMAL]); if(color & RED) sock->print("%c[%dm", 27, Ansi[COLOR_RED]); else if(color & GREEN) sock->print("%c[%dm", 27, Ansi[COLOR_GREEN]); else if(color & YELLOW) sock->print("%c[%dm", 27, Ansi[COLOR_YELLOW]); else if(color & BLUE) sock->print("%c[%dm", 27, Ansi[COLOR_BLUE]); else if(color & MAGENTA) sock->print("%c[%dm", 27, Ansi[COLOR_MAGENTA]); else if(color & CYAN) sock->print("%c[%dm", 27, Ansi[COLOR_CYAN]); else if(color & BLACK) sock->print("%c[%dm", 27, Ansi[COLOR_BLACK]); else if(color & WHITE) sock->print("%c[%dm", 27, Ansi[COLOR_WHITE]); } else if(sock->getPlayer()->flagIsSet(P_MIRC) && color != BLINK) { if(color & BOLD) sock->print("%c", 2); if(color & UNDERLINE) sock->print("%c", 31); if(color & NORMAL) sock->print("%c%c", 3, 3); if(color & RED) sock->print("%c%d", 3, Mirc[COLOR_RED]); else if(color & GREEN) sock->print("%c%d", 3, Mirc[COLOR_GREEN]); else if(color & YELLOW) sock->print("%c%d", 3, Mirc[COLOR_YELLOW]); else if(color & BLUE) sock->print("%c%d", 3, Mirc[COLOR_BLUE]); else if(color & MAGENTA) sock->print("%c%d", 3, Mirc[COLOR_MAGENTA]); else if(color & CYAN) sock->print("%c%d", 3, Mirc[COLOR_CYAN]); else if(color & BLACK) sock->print("%c%d", 3, Mirc[COLOR_BLACK]); else if(color & WHITE) sock->print("%c%d", 3, Mirc[COLOR_WHITE]); } } } //*********************************************************************** // getMXPColor //*********************************************************************** const char* getMXPColor(const char type, Player* player) { // max length from getColor is 9, ending active MXP is 4, // so 15 storage will be enough static char r[15]; r[0] = 0; // mxp specific color tags switch(type) { case 'l': case 'e': case 'p': case 's': case 'E': case 'o': // start mxp sprintf(r, "%c[4z", 27); player->setFlag(P_MXP_ACTIVE); // grab the color switch(type) { case 'l': strcat(r, "<c1>"); break; case 'e': strcat(r, "<c2>"); break; case 'p': strcat(r, "<c3>"); break; case 's': strcat(r, "<c4>"); break; case 'E': strcat(r, "<c5>"); break; case 'o': strcat(r, "<c6>"); break; default: break; } return(r); default: break; } // dont deactivate color for carets! if(type == '^') return("^"); if(player->flagIsSet(P_MXP_ACTIVE)) { // end mxp sprintf(r, "%c[3z", 27); player->clearFlag(P_MXP_ACTIVE); } strcat(r, colorCodeToColor(type)); return(r); } //*********************************************************************** // stripColor //*********************************************************************** bstring stripColor(bstring color) { std::ostringstream str; unsigned int i=0, max = color.getLength(); for(; i < max ; i++) { if(color.getAt(i) == '^') i++; else str << color.getAt(i); } return(str.str()); } //*********************************************************************** // escapeColor //*********************************************************************** bstring escapeColor(bstring color) { color.Replace("^","^^"); return(color); } //*********************************************************************** // colorize //*********************************************************************** bstring colorize(const char* txt, int option, Player* player) { const char* point; char last = '0'; std::ostringstream coloredStr; if(option) { for(point = txt; *point; point++) { if(*point == '^') { point++; // If we're trying to send out the same color as before // no point wasting the extra space if(*point != last || last == '^') { if(player && player->flagIsSet(P_MXP_ENABLED)) coloredStr << getMXPColor(*point, player); else coloredStr << colorCodeToColor(*point); } last = *point; continue; } coloredStr << *point; } // Now set the color back to normal if(player && player->flagIsSet(P_MXP_ENABLED)) coloredStr << getMXPColor('x', player); else coloredStr << colorCodeToColor('x'); } else { for(point=txt; *point; point++ ) { if(*point == '^') { point++; if(*point == '^') coloredStr << "^"; continue; } coloredStr << *point; } } return(coloredStr.str()); }