/************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefiting. We hope that you share your changes too. What goes * * around, comes around. * *************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * *************************************************************************** * 1stMud ROM Derivative (c) 2001-2004 by Markanth * * http://www.firstmud.com/ <markanth@firstmud.com> * * By using this code you have agreed to follow the term of * * the 1stMud license in ../doc/1stMud/LICENSE * ***************************************************************************/ #include "merc.h" #include "tables.h" #include "interp.h" #include "recycle.h" bool is_ansi_printed_char (char c) { switch (c) { case ' ': case '-': case COLORCODE: return true; default: return false; } } int ansi_skip (const char *pstr) { int i = 0; const char *str = pstr; if (*str != COLORCODE) return i; str++; i++; if (isdigit (*str)) { str++; i++; if (*str == '+') { str++; i++; } else return i; } if (*str == '=') { str++; i++; } switch (*str) { case 'T': case 't': str += 3; i += 3; do { str++; i++; } while (*str && *str != '"'); break; default: break; } return i; } int random_color (int att) { switch (att) { case CT_ATTR: return number_range (CL_NONE, CL_BRIGHT); case CT_FORE: return number_range (FG_RED, FG_WHITE); case CT_BACK: return number_range (BG_RED, BG_WHITE); default: return CL_NONE; } } void convert_random (colatt_t * attr) { int i; for (i = 0; i < CT_MAX; i++) if (attr->at[i] == CL_RANDOM) attr->at[i] = random_color (i); if (attr->at[CT_BACK] >= CL_MOD) { int bg = BG_NONE; if (VALID_FG (attr->at[CT_FORE])) bg = attr->at[CT_FORE] + 10; attr->at[CT_FORE] = attr->at[CT_BACK] - CL_MOD; attr->at[CT_BACK] = bg; } } char * make_color (CharData * ch, colatt_t * c) { int len = 0; char code[100]; convert_random (c); if (ch) { if (c->at[CT_ATTR] == CL_BLINK) { if (VT100_SET (ch, NO_BLINKING)) c->at[CT_ATTR] = CL_NONE; } if (c->at[CT_FORE] == FG_BLACK) { if (VT100_SET (ch, DARK_MOD)) c->at[CT_ATTR] = CL_BRIGHT; } if (c->at[CT_ATTR] == CL_BRIGHT) { if (VT100_SET (ch, DARK_COLORS)) c->at[CT_ATTR] = CL_NONE; } } if (!VT100_SET (ch, BROKEN_ANSI)) { if (VALID_CL (c->at[CT_ATTR])) len = sprintf (code + len, ";%d", c->at[CT_ATTR]); if (VALID_FG (c->at[CT_FORE])) len = sprintf (code + len, ";%d", c->at[CT_FORE]); if (VALID_BG (c->at[CT_BACK])) len = sprintf (code + len, ";%d", c->at[CT_BACK]); if (len > 0) return FORMATF (ESC "[%sm", code + 1); else { bug ("make_color(): invalid color value(s)"); return ""; } } else { if (!VALID_CL (c->at[CT_ATTR])) c->at[CT_ATTR] = CL_NONE; if (!VALID_FG (c->at[CT_FORE])) c->at[CT_FORE] = FG_WHITE; if (!VALID_BG (c->at[CT_BACK])) c->at[CT_BACK] = BG_BLACK; return FORMATF (ESC "[%d;%d;%dm", c->at[CT_ATTR], c->at[CT_FORE], c->at[CT_BACK]); } } char * char_color (CharData * ch, int slot) { colatt_t attr; if (!ch || !ch->desc || IsNPC (ch) || slot < 0 || slot >= MAX_CUSTOM_COLOR) return CL_DEFAULT; attr = ch->pcdata->color[slot]; return make_color (ch, &attr); } void set_col_attr (char c, colatt_t * d, CharData * ch) { int z; int At = NO_FLAG; if (d->at[CT_ATTR] >= CL_MOD) At = d->at[CT_ATTR]; switch (c) { case '?': case '`': d->at[CT_ATTR] = CL_RANDOM; d->at[CT_FORE] = FG_RANDOM; break; case 'z': d->at[CT_ATTR] = CL_RANDOM; d->at[CT_BACK] = BG_RANDOM; break; case 'Z': for (z = 0; z < CT_MAX; z++) d->at[z] = CL_RANDOM; break; case 'b': d->at[CT_ATTR] = CL_NONE; d->at[CT_FORE] = FG_BLUE; break; case 'c': d->at[CT_ATTR] = CL_NONE; d->at[CT_FORE] = FG_CYAN; break; case 'g': d->at[CT_ATTR] = CL_NONE; d->at[CT_FORE] = FG_GREEN; break; case 'm': d->at[CT_ATTR] = CL_NONE; d->at[CT_FORE] = FG_MAGENTA; break; case 'd': d->at[CT_ATTR] = CL_NONE; d->at[CT_FORE] = FG_BLACK; break; case 'r': d->at[CT_ATTR] = CL_NONE; d->at[CT_FORE] = FG_RED; break; case 'y': d->at[CT_ATTR] = CL_NONE; d->at[CT_FORE] = FG_YELLOW; break; case 'w': d->at[CT_ATTR] = CL_NONE; d->at[CT_FORE] = FG_WHITE; break; case 'B': d->at[CT_ATTR] = CL_BRIGHT; d->at[CT_FORE] = FG_BLUE; break; case 'C': d->at[CT_ATTR] = CL_BRIGHT; d->at[CT_FORE] = FG_CYAN; break; case 'G': d->at[CT_ATTR] = CL_BRIGHT; d->at[CT_FORE] = FG_GREEN; break; case 'M': d->at[CT_ATTR] = CL_BRIGHT; d->at[CT_FORE] = FG_MAGENTA; break; case 'D': d->at[CT_ATTR] = CL_BRIGHT; d->at[CT_FORE] = FG_BLACK; break; case 'R': d->at[CT_ATTR] = CL_BRIGHT; d->at[CT_FORE] = FG_RED; break; case 'W': d->at[CT_ATTR] = CL_BRIGHT; d->at[CT_FORE] = FG_WHITE; break; case 'Y': d->at[CT_ATTR] = CL_BRIGHT; d->at[CT_FORE] = FG_YELLOW; break; default: break; } if (At != NO_FLAG) d->at[CT_ATTR] = At - CL_MOD; } char * colorize (const char *str) { static int c; static char out[4][MSL]; char *result; size_t a, b = 0; if (NullStr (str)) return "{?"; ++c, c %= 4; result = out[c]; for (a = 0; str[a] != NUL; a++) { if (str[a] == COLORCODE) { a += ansi_skip (&str[a]); continue; } else if (str[a] == CUSTOMSTART) { do { a++; } while (str[a] != CUSTOMEND); a++; continue; } else if (str[a] == MXP_BEGc) { do { a++; } while (str[a] != MXP_ENDc); a++; continue; } result[b++] = COLORCODE; result[b++] = '?'; result[b++] = str[a]; } result[b++] = COLORCODE; result[b++] = 'x'; result[b++] = NUL; return (result); } Do_Fun (do_color) { if (!ch) return; if (IsNPC (ch) || ch->desc == NULL) { chprintln (ch, "Color is not ON, Way Moron!"); return; } if (!IsSet (ch->desc->desc_flags, DESC_COLOR)) { SetBit (ch->desc->desc_flags, DESC_COLOR); RemBit (ch->comm, COMM_NOCOLOR); chprintln (ch, colorize ("Color is now ON!")); } else { chprintln (ch, casemix ("Color is now OFF, <sigh>")); RemBit (ch->desc->desc_flags, DESC_COLOR); SetBit (ch->comm, COMM_NOCOLOR); } return; } void goto_xy (CharData * ch, int col, int row) { chprintf (ch, ESC "[%u;%uH", row, col); } void clear_window (CharData * ch) { chprint (ch, ESC "[r"); } void clear_screen (CharData * ch) { chprint (ch, ESC "[2J"); } void default_color (CharData * ch, int slot) { int i = 0; if (!ch || IsNPC (ch)) return; if (slot == -1) { for (i = 0; i < MAX_CUSTOM_COLOR; i++) { copy_array (ch->pcdata->color[i].at, color_table[i].col_attr, CT_MAX); } } else { for (i = 0; i < MAX_CUSTOM_COLOR; i++) { if (color_table[i].slot == slot) { copy_array (ch->pcdata->color[slot].at, color_table[i].col_attr, CT_MAX); break; } } } return; } Lookup_Fun (color_lookup) { int i; if (NullStr (name)) return -1; for (i = 0; i < MAX_CUSTOM_COLOR; i++) if (!str_prefix (name, color_table[i].name)) return i; return -1; } Do_Fun (do_colorset) { char arg[MIL], attr[MIL], fore[MIL], back[MIL]; int i = 0, slot = 0; colatt_t c_attr; int pos = 0; if (!ch || IsNPC (ch) || !ch->desc) return; if (!IsSet (ch->desc->desc_flags, DESC_COLOR)) { chprintln (ch, "You must have color on to use colorset."); return; } argument = one_argument (argument, arg); argument = one_argument (argument, attr); argument = one_argument (argument, fore); argument = one_argument (argument, back); if (NullStr (arg)) { cmd_syntax (ch, NULL, n_fun, "colors - lists possible colors", "status - lists options to colorize", "<option> <color> - sets an option to a color", "default <option> - sets option to default value", "default all - reset all options to default values", "vt100 <flag> - toggle a display flag", NULL); return; } else if (!str_prefix (arg, "vt100")) { flag_t vf; if (NullStr (attr) || (vf = flag_value (vt100_flags, attr)) == NO_FLAG) { chprintln (ch, "Invalid vt100 flag."); print_all_on_off (ch, vt100_flags, ch->pcdata->vt100); return; } ToggleBit (ch->pcdata->vt100, vf); chprintlnf (ch, "%s %s.", capitalize (flag_string (vt100_flags, vf)), IsSet (ch->pcdata->vt100, vf) ? "ON" : "OFF"); return; } else if (!str_prefix (arg, "colors") || !str_prefix (arg, "colors")) { int j = 0, k = 0; chprintln (ch, "Attributes Foregrounds Backgrounds"); chprintln (ch, draw_line (ch, NULL, 58)); for (i = 0; color_attributes[i].name != NULL; i++) { chprintf (ch, "%-15s ", Upper (color_attributes[i].name)); if (color_foregrounds[j].name != NULL) chprintf (ch, "%-15s ", Upper (color_foregrounds[j++].name)); else chprintf (ch, "%-15s ", " "); if (color_backgrounds[k].name != NULL) chprintlnf (ch, "%s", Upper (color_backgrounds[k++].name)); else chprintln (ch, NULL); } while (color_foregrounds[j].name != NULL) { chprintf (ch, "%-15s %-15s ", " ", Upper (color_foregrounds[j++].name)); if (color_backgrounds[k].name != NULL) chprintlnf (ch, "%s", Upper (color_backgrounds[k++].name)); else chprintln (ch, NULL); } while (color_backgrounds[k].name != NULL) chprintlnf (ch, "%-15s %-15s %s", " ", " ", Upper (color_backgrounds[k++].name)); chprintln (ch, draw_line (ch, NULL, 58)); } else if (!str_prefix (arg, "status")) { Column *Cd = new_column (); set_cols (Cd, ch, 2, COLS_CHAR, ch); chprintln (ch, "Options that can currently be configured for color are:"); chprintln (ch, draw_line (ch, NULL, 0)); for (i = 0; i < MAX_CUSTOM_COLOR; i++) { print_cols (Cd, "%-12s - %sLooks like this..{x ", color_table[i].name, char_color (ch, color_table[i].slot)); } cols_nl (Cd); chprintln (ch, draw_line (ch, NULL, 0)); free_column (Cd); } else if (!str_prefix (arg, "default")) { if (!str_cmp (attr, "all")) { slot = -1; chprintln (ch, "All colors set to default values."); } else if ((pos = color_lookup (attr)) == -1) { do_colorset (n_fun, ch, ""); return; } else { slot = color_table[pos].slot; chprintlnf (ch, "%s set to default value.", color_table[pos].name); } default_color (ch, slot); return; } else if ((pos = color_lookup (arg)) != -1) { slot = color_table[pos].slot; if (NullStr (attr) || NullStr (fore) || NullStr (back)) { cmd_syntax (ch, NULL, n_fun, "<option> <attribute> <foreground> <background>", NULL); return; } if ((c_attr.at[CT_ATTR] = flag_value (color_attributes, attr)) == NO_FLAG) { chprintln (ch, "Invalid color Attribute."); return; } if ((c_attr.at[CT_FORE] = flag_value (color_foregrounds, fore)) == NO_FLAG) { chprintln (ch, "Invalid Foreground color."); return; } if ((c_attr.at[CT_BACK] = flag_value (color_backgrounds, back)) == NO_FLAG) { chprintln (ch, "Invalid background color."); return; } copy_array (ch->pcdata->color[slot].at, c_attr.at, CT_MAX); chprintf (ch, "%s set to %s%s", color_table[pos].name, char_color (ch, slot), flag_string (color_attributes, c_attr.at[CT_ATTR])); if (VALID_FG (c_attr.at[CT_FORE])) chprintf (ch, " %s", flag_string (color_foregrounds, c_attr.at[CT_FORE])); if (VALID_BG (c_attr.at[CT_BACK])) chprintf (ch, ", with a %s background", flag_string (color_backgrounds, c_attr.at[CT_BACK])); chprintln (ch, "{x."); return; } else do_colorset (n_fun, ch, ""); }