.-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-. 
 |                                                                       | 
 |                                                                       | 
 |                                                                       | 
 |                         PROMPT BEAUTY TOKEN                           | 
 |                                                                       | 
 !                                                                       ! 
 :                         A Snippet written by                          : 
 :                              Valcados                                 : 
 .                           for SMAUG MUDS                              . 
 .                                                                       . 
 :                                                                       : 
 :                                                                       : 
 !                                                                       ! 
 |                                                                       | 
 |                                                                       | 
 |                                                                       | 
 |                                                                       | 
 |                                                                       | 
 `-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-'

DESCRIPTION:
     This snippet adds the %! prompt token which toggles prompt
     beautification on and off.  In those parts of the prompt where
     beautification is turned on, other prompt tokens will be auto-
     coloured based on their values.  For instance, hp will go red
     when low, light blue when high.  The idea for the autocoloring
     itself is taken from KaViR's Godwars, but there the "token" is
     forced on the players, whereas this way it's just another
     option for customizing the prompt.

EXAMPLE:
     If your prompt is %!&w<%h/%H>, then you will see the <, >, and
     / in light gray, the max hitpoints in light blue, and the
     current hitpoints will be colour-coded based on your health.
     If your prompt is &c<%h/%H %!%m%!/%M %v/%V>, then everything
     will be cyan, except your current mana, which will be colour-
     coded.  Note how the first %! tells beautification to start,
     and the second %! tells it to end.

KNOWN PROBLEMS/BUGS:
     While this has been pretty thoroughly tested over at
     the Lands of Aethar, I had to change some things to put
     it in snippet form for stock SMAUG, since the Lands' code
     is quite different.  If there are problems, or if it
     doesn't compile, please let me know in the comments section
     for this snippet at mudbytes.net

IN-GAME MECHANICS:
     If beauty is toggled on using the %! token, the other prompt
     tokens will be autocoloured in the following way...
     - Current Hp/Mana/Mv/Blood:  light blue at 100%, blue at 70-99%,
       green at 40-69%, yellow at 20-39%, red below 20%.
     - Max Hp/Mana/Mv:  light blue (or red if the max is 0)
     - Alignment:  Light blue for good, red for evil,
       dark grey for neutral.
     - Conditions (ie self, enemy, tank):  same color as
       current Hp above, based on the appropriate person's hp.
     - Tank name:  light blue if tank != ch, red if tank = ch
     - Time: dark cyan for night, brown for dawn, light blue for
       day, dark green for dusk.
     - gold:  yellow if player has gold, red if not.
     - style: bright red for berserk, dark red for aggressive,
       blue for defensive, light blue for evasive, light gray
       for standard.

HOW TO INSTALL:

1.  Open comm.c, all the changes we will be making take place here so
    no other files will need to be opened.

2.  Add this function prototype somewhere near the top:

char insert_beauty args(( char ** pbuf, char *col, DESCRIPTOR_DATA *d ));

3.  Find where the display_prompt function starts.  Right above it,
    add these macros:

#define BEAUTY_COLOR( color ) do                                                                \
                              {                                                                 \
                                if ( beauty )                                                   \
                                {                                                               \
                                  prevpromptcolor[1] = currpromptcolor[1];                      \
                                  prevpromptcolor[0] = currpromptcolor[0];                      \
                                  currpromptcolor[1] = insert_beauty( &pbuf, color, d );        \
                                  currpromptcolor[0] = '&';                                     \
                                }                                                               \
                              }                                                                 \
                              while(0)

#define BEAUTY( color ) BEAUTY_COLOR( color )

#define BEAUTY_PERCENT( percent )               \
                do {                            \
                   if (percent >= 100)          \
                     BEAUTY( "&C" );            \
                   else if ( percent >= 70 )    \
                     BEAUTY( "&B" );            \
                   else if ( percent >= 40 )    \
                     BEAUTY( "&G" );            \
                   else if ( percent >= 20 )    \
                     BEAUTY( "&Y" );            \
                   else                         \
                     BEAUTY( "&R" );            \
                 } while(0)

4.  In function display_prompt, declare the following variables:

  bool beauty = FALSE;
  char prevpromptcolor[2];
  char currpromptcolor[2];

5.  Right below those variables we declared above, add this:

  prevpromptcolor[0] = '&', prevpromptcolor[1] = 'w';
  currpromptcolor[0] = '&', currpromptcolor[1] = 'w';

6.  Further below, find something like this:

    case '&':
    case '^':
      stat = make_color_sequence(&prompt[-1], pbuf, d);
      if ( stat < 0 )
        --prompt;
      else if ( stat > 0 )
        pbuf += stat;

    Change it to this:

    case '&':
    case '^':
      stat = make_color_sequence(&prompt[-1], pbuf, d);
      if ( stat < 0 )
        --prompt;
      else if ( stat > 0 )
      {
        pbuf += stat;
        prevpromptcolor[0] = currpromptcolor[0] = prompt[-1];
        prevpromptcolor[1] = currpromptcolor[1] = prompt[0];
      }

7.  Further down, find something like this:

    case '%':
      *pbuf = '\0';
      stat = 0x80000000;
      switch(*prompt)
      {
      case '%':
	*pbuf++ = '%';
	*pbuf = '\0';
	break;
      case 'a':
	if ( ch->level >= 10 )

Change it to this:

    case '%':
      *pbuf = '\0';
      stat = 0x80000000;
      switch(*prompt)
      {
      case '%':
	*pbuf++ = '%';
	*pbuf = '\0';
	break;
      case '!':
        beauty = beauty ? FALSE : TRUE;
        break;
      case 'a':
        BEAUTY( IS_GOOD(ch) ? "&C" : IS_EVIL(ch) ? "&R" : "&w" );
	if ( ch->level >= 10 )

8.  Further down, find something like this:

        case 'C':  /* Tank */
	  if ( !IS_IMMORTAL( ch ) ) break;
          if ( !ch->fighting || ( victim = ch->fighting->who ) == NULL )
             strcpy( pbuf, "N/A" );
          else if(!victim->fighting||(victim = victim->fighting->who)==NULL)
             strcpy( pbuf, "N/A" );
          else {
              if ( victim->max_hit > 0 )
                    percent = (100 * victim->hit) / victim->max_hit;
              else
                    percent = -1;
                   if (percent >= 100)
                       strcpy (pbuf, "perfect health");

Change it to this:

        case 'C':  /* Tank */
	  if ( !IS_IMMORTAL( ch ) ) break;
          if ( !ch->fighting || ( victim = ch->fighting->who ) == NULL )
             strcpy( pbuf, "N/A" );
          else if(!victim->fighting||(victim = victim->fighting->who)==NULL)
             strcpy( pbuf, "N/A" );
          else {
              if ( victim && victim->max_hit > 0 )
                    percent = (100 * victim->hit) / (victim->max_hit ? victim->max_hit : 1);
              else
                    percent = -1;
                   BEAUTY_PERCENT(percent);
                   if (percent >= 100)
                       strcpy (pbuf, "perfect health");

9.  Further down, find something like this:

        case 'c':
	  if ( !IS_IMMORTAL( ch ) ) break;
          if ( !ch->fighting || ( victim = ch->fighting->who ) == NULL )
             strcpy( pbuf, "N/A" );
          else {
              if ( victim->max_hit > 0 )
                    percent = (100 * victim->hit) / victim->max_hit;
              else
                    percent = -1;
                if (percent >= 100)
                       strcpy (pbuf, "perfect health");

Change it to this:

        case 'c':
	  if ( !IS_IMMORTAL( ch ) ) break;
          if ( !ch->fighting || ( victim = ch->fighting->who ) == NULL )
          {
             BEAUTY( "&R" );
             strcpy( pbuf, "N/A" );
             break;
          }
          else {
              if ( victim->max_hit > 0 )
                    percent = (100 * victim->hit) / (victim->max_hit ? victim->max_hit : 1);
              else
                    percent = -1;
                BEAUTY_PERCENT(percent);
                if (percent >= 100)
                       strcpy (pbuf, "perfect health");

10. Further down, find something like this:

      case 'h':
	stat = ch->hit;
	break;
      case 'H':
	stat = ch->max_hit;
	break;
      case 'm':
	if ( IS_VAMPIRE(ch) )
	  stat = 0;
	else
	  stat = ch->mana;
	break;
      case 'M':
	if ( IS_VAMPIRE(ch) )
	  stat = 0;
	else
	  stat = ch->max_mana;
	break;
        case 'N': /* Tank */
	  if ( !IS_IMMORTAL(ch) ) break;
          if ( !ch->fighting || ( victim = ch->fighting->who ) == NULL )
            strcpy( pbuf, "N/A" );
          else if(!victim->fighting||(victim=victim->fighting->who)==NULL)
            strcpy( pbuf, "N/A" );
          else {
            if ( ch == victim )
                    strcpy ( pbuf, "You" );
            else if ( IS_NPC(victim) )
                    strcpy ( pbuf, victim->short_descr );
            else
                    strcpy ( pbuf, victim->name );
                pbuf[0] = UPPER( pbuf[0] );
          }
          break;

Change it to this:

      case 'h':
        percent = ( 100 * ch->hit ) / (ch->max_hit ? ch->max_hit : 1);
        BEAUTY_PERCENT( percent );
	stat = ch->hit;
	break;
      case 'H':
        BEAUTY( "&C" );
	stat = ch->max_hit;
	break;
      case 'm':
	if ( IS_VAMPIRE(ch) )
	  stat = 0;
	else
	  stat = ch->mana;
        if ( IS_VAMPIRE(ch) )
          BEAUTY( "&R" );
        else
        {
          percent = ( 100 * ch->mana ) / (ch->max_mana ? ch->max_mana : 1);
          BEAUTY_PERCENT( percent );
        }
	break;
      case 'M':
        if ( IS_VAMPIRE(ch) )
        {
          BEAUTY( "&R" );
          stat = 0;
        }
        else
        {
          BEAUTY( "&C" );
          stat = ch->max_mana;
        }
	break;
        case 'N': /* Tank */
	  if ( !IS_IMMORTAL(ch) ) break;
          if ( !ch->fighting || ( victim = ch->fighting->who ) == NULL )
            strcpy( pbuf, "N/A" );
          else if(!victim->fighting||(victim=victim->fighting->who)==NULL)
            strcpy( pbuf, "N/A" );
          else {
            if ( ch == victim )
                    strcpy ( pbuf, "You" );
            else if ( IS_NPC(victim) )
                    strcpy ( pbuf, victim->short_descr );
            else
                    strcpy ( pbuf, victim->name );
                pbuf[0] = UPPER( pbuf[0] );
            if ( ch == victim )
              BEAUTY( "&R" );
            else
              BEAUTY( "&C" );
          }
          break;

11. Further down, find something like this:

      case 'T':
        if      ( time_info.hour <  5 ) strcpy( pbuf, "night" );
        else if ( time_info.hour <  6 ) strcpy( pbuf, "dawn" );
        else if ( time_info.hour < 19 ) strcpy( pbuf, "day" );
        else if ( time_info.hour < 21 ) strcpy( pbuf, "dusk" );
        else                            strcpy( pbuf, "night" );
        break;

Change it to this:

      case 'T':
        if      ( time_info.hour <  5 ) { BEAUTY("&c"); strcpy( pbuf, "night" ); }
        else if ( time_info.hour <  6 ) { BEAUTY("&O"); strcpy( pbuf, "dawn" ); }
        else if ( time_info.hour < 19 ) { BEAUTY("&C"); strcpy( pbuf, "day" ); }
        else if ( time_info.hour < 21 ) { BEAUTY("&g"); strcpy( pbuf, "dusk" ); }
        else                            { BEAUTY("&c"); strcpy( pbuf, "night" ); }
        break;

12. Further down, find this:

      case 'b':
	if ( IS_VAMPIRE(ch) )
	  stat = ch->pcdata->condition[COND_BLOODTHIRST];
	else
	  stat = 0;
	break;
      case 'B':
	if ( IS_VAMPIRE(ch) )
	  stat = ch->level + 10;
	else
	  stat = 0;
	break;

Change it to this:

      case 'b':
        if ( IS_VAMPIRE(ch) )
          stat = ch->pcdata->condition[COND_BLOODTHIRST];
        else
          stat = 0;
        percent = ( 100 * stat ) / (ch->max_blood ? ch->max_blood : 1);
        BEAUTY_PERCENT(percent);
        break;
      case 'B':
        if ( IS_VAMPIRE(ch) )
          stat = ch->level + 10;
        else
          stat = 0;
        BEAUTY( stat ? "&C" : "&R" );
        break;

13. Further down, find this:

      case 'v':
	stat = ch->move;
	break;
      case 'V':
	stat = ch->max_move;
	break;
      case 'g':
	stat = ch->gold;
	break;

Change it to this:

      case 'v':
	stat = ch->move;
        percent = ( 100 * stat ) / (ch->max_move ? ch->max_move : 1 );
        BEAUTY_PERCENT( percent );
	break;
      case 'V':
	stat = ch->max_move;
        BEAUTY( stat ? "&C" : "&R" );
	break;
      case 'g':
	stat = ch->gold;
        BEAUTY( stat ? "&Y" : "&R" );
	break;

14. Further down, find something like this:

      case 'S':
        if      ( ch->style == STYLE_BERSERK )    strcpy( pbuf, "B" );
        else if ( ch->style == STYLE_AGGRESSIVE ) strcpy( pbuf, "A" );
        else if ( ch->style == STYLE_DEFENSIVE )  strcpy( pbuf, "D" );
        else if ( ch->style == STYLE_EVASIVE )    strcpy( pbuf, "E" );
        else                                      strcpy( pbuf, "S" );
	break;

Change it to this:

      case 'S':
        if      ( ch->style == STYLE_BERSERK )    { BEAUTY( "&R" ); strcpy( pbuf, "B" ); }
        else if ( ch->style == STYLE_AGGRESSIVE ) { BEAUTY( "&r" ); strcpy( pbuf, "A" ); }
        else if ( ch->style == STYLE_DEFENSIVE )  { BEAUTY( "&B" ); strcpy( pbuf, "D" ); }
        else if ( ch->style == STYLE_EVASIVE )    { BEAUTY( "&C" ); strcpy( pbuf, "E" ); }
        else                                      { BEAUTY( "&w" ); strcpy( pbuf, "S" ); }
	break;

15. Further down, find something like this:

      if ( stat != 0x80000000 )
	sprintf(pbuf, "%d", stat);
      pbuf += strlen(pbuf);
      break;

Change it to this:

      if ( stat != 0x80000000 )
	sprintf(pbuf, "%d", stat);
      pbuf += strlen(pbuf);

      if ( prevpromptcolor[0] != currpromptcolor[0]
      ||   prevpromptcolor[1] != currpromptcolor[1] )
      {
        insert_beauty( &pbuf, prevpromptcolor, d );
        currpromptcolor[0] = prevpromptcolor[0];
        currpromptcolor[1] = prevpromptcolor[1];
      }

      break;

16. Somewhere in comm.c, for example at the very bottom, add this function:

char insert_beauty( char ** pbuf, char *col, DESCRIPTOR_DATA *d )
{
  int stat;

  stat = make_color_sequence( col, *pbuf, d );
  if ( stat > 0 )
    *pbuf += stat;

  return col[1];
}

17. Recompile, reboot, and have fun with the %! token  :)