eldhamud_2.3.3/clans/
eldhamud_2.3.3/councils/
eldhamud_2.3.3/doc/
eldhamud_2.3.3/doc/DIKU/
eldhamud_2.3.3/doc/DIKU/.svn/
eldhamud_2.3.3/doc/DIKU/.svn/prop-base/
eldhamud_2.3.3/doc/DIKU/.svn/text-base/
eldhamud_2.3.3/doc/MERC/
eldhamud_2.3.3/doc/MERC/.svn/
eldhamud_2.3.3/doc/SMAUG/.svn/
eldhamud_2.3.3/doc/SMAUG/mudprogs/
eldhamud_2.3.3/doc/SMAUG/mudprogs/.svn/
eldhamud_2.3.3/doc/mudprogs/
eldhamud_2.3.3/gods/
eldhamud_2.3.3/houses/
eldhamud_2.3.3/player/a/
/*
.-------------------------------------------------------------------------------.
| Title    : MIP (Messaging Interface Protocol) v8.1 Support Module  |
| Author   : Chris Coulter (aka Gabriel Androctus)    |
| Date     : 08.26.02        |
| Dev. MUD : Perils of Quiernin ( perils.org 6000 )    |
| Platform : SMAUG v1.4a       |
| MUD Page : http://www.perils.org/      |
| Res. Page: http://www.perils.org/goodies/     |
+-------------------------------------------------------------------------------+
| DESCRIPTION:         |
| MIP (Messaging Interface Protocol) enables your mud to communicate specific   |
| text strings to a player using the Portal client software. This module        |
| provides basic support for establishing if the player is using the Portal     |
| client and assigning the appropriate information, as well as a simplified     |
| way to send the strings to trigger specific features on the player's client.  |
|          |
| For more information, visit Portal's web page ( www.gameaxle.com ) and click  |
| on the "Developers" button on the menu bar. From there you can download a PDF |
| file that explains in detail the specifics of the MIP.   |
|          |
| NOTE: If a player is not using the Portal client, the mud will function as    |
| it normally would, and the player would not receive the MIP codes. It will    |
| only function for players who has connected via the Portal mud client         |
|           |
`-------------------------------------------------------------------------------'
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "./Headers/mud.h"

/* Parses jumpstart command and assigns sec_code & version information.  -gabe */
void do_mip_start ( CHAR_DATA * ch, char *argument )
{
  char arg[MAX_INPUT_LENGTH];  /* version */
  char buf[MAX_STRING_LENGTH];
  int sec_code;

  if ( IS_NPC ( ch ) )
  {
    send_to_char ( "Huh?\n\r", ch );
    return;
  }

  if ( argument[0] == '\0' )
  {
    send_to_char ( "Huh?\n\r", ch );
    return;
  }

  sscanf ( argument, "%d~%s\n\r", &sec_code, arg );

  /*
   * pad sec_code with zeros
   */

  if ( sec_code >= 10000 )
    sprintf ( buf, "%d", sec_code );
  else
    if ( sec_code >= 1000 )
      sprintf ( buf, "0%d", sec_code );
    else
      if ( sec_code >= 100 )
        sprintf ( buf, "00%d", sec_code );
      else
        if ( sec_code >= 10 )
          sprintf ( buf, "000%d", sec_code );
        else
          if ( sec_code >= 0 )
            sprintf ( buf, "0000%d", sec_code );

  ch->pcdata->sec_code = str_dup ( buf );

  ch->pcdata->mip_ver = str_dup ( arg );

  xSET_BIT ( ch->act, PLR_MIP );
}



/* Initial settings are all done here. -gabe */
void init_mip ( CHAR_DATA * ch )
{
  send_mip_mask ( ch, CL_HP_MASK, "Hit Points" );
  send_mip_mask ( ch, CL_SP_MASK, "Mana" );
  send_mip_mask ( ch, CL_GP1_MASK, "Movement" );
  send_mip_mask ( ch, CL_GP2_MASK, "Unused" );
}


/* Is the character's client MIP-enhanced? -gabe */
bool mip_enabled ( CHAR_DATA * ch )
{
  if ( IS_NPC ( ch ) )
    return FALSE;

  if ( ( !ch->pcdata->sec_code || ch->pcdata->sec_code[0] == '\0' )
       && ( !ch->pcdata->mip_ver || ch->pcdata->mip_ver[0] == '\0' ) )
    return FALSE;

  if ( xIS_SET ( ch->act, PLR_MIP ) )
    return TRUE;

  return FALSE;
}



/* provides the generic prefix for all MIP communication -gabe */
void send_mip ( char *argument, CHAR_DATA * ch )
{
  char buf[MAX_STRING_LENGTH];
  char length2[MAX_STRING_LENGTH];
  int length;

  if ( !mip_enabled ( ch ) )
    return;

  length = strlen ( argument );

  if ( length >= 1000 )
    sprintf ( length2, "999" );
  else if ( length >= 100 )
      sprintf ( length2, "%d", length );
  else if ( length >= 10 )
      sprintf ( length2, "0%d", length );
  else if ( length >= 0 )
      sprintf ( length2, "00%d", length );
  else
      sprintf ( length2, "000" );

  sprintf ( buf, "#K%%%s%s%s", ch->pcdata->sec_code, length2, argument );
  send_to_char ( buf, ch );
  return;
}


void send_mip_2 ( char *argument, CHAR_DATA * victim )
{
  char buf[MAX_STRING_LENGTH];
  char length2[MAX_STRING_LENGTH];
  int length;

  if ( !mip_enabled ( victim ) )
    return;

  length = strlen ( argument );

  if ( length >= 1000 )
    sprintf ( length2, "999" );
  else if ( length >= 100 )
      sprintf ( length2, "%d", length );
  else if ( length >= 10 )
      sprintf ( length2, "0%d", length );
  else if ( length >= 0 )
      sprintf ( length2, "00%d", length );
  else
      sprintf ( length2, "000" );

  sprintf ( buf, "#K%%%s%s%s", victim->pcdata->sec_code, length2, argument );
  send_to_char ( buf, victim );
  return;
}


void send_mip_3 ( char *argument, CHAR_DATA * victim )
{
  char buf[MAX_STRING_LENGTH];
  char length2[MAX_STRING_LENGTH];
  int length;

  length = strlen ( argument );

  if ( length >= 1000 )
    sprintf ( length2, "999" );
  else if ( length >= 100 )
      sprintf ( length2, "%d", length );
  else if ( length >= 10 )
      sprintf ( length2, "0%d", length );
  else if ( length >= 0 )
       sprintf ( length2, "00%d", length );
  else
       sprintf ( length2, "000" );

  sprintf ( buf, "#K%%%s%s%s", victim->pcdata->sec_code, length2, argument );
  send_to_char ( buf, victim );
  return;
}



/* Triggers sound on client's computer.  -gabe
 * Formats: .WAV
 */
void send_mip_sound ( CHAR_DATA * ch, char *filename )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", CL_SEND_SOUND, filename );
  send_mip ( buf, ch );
  return;
}



/* Triggers music on client's computer.  -gabe
 * Formats: .MID, .RMI, .MP3
 */
void send_mip_music ( CHAR_DATA * ch, char *filename, int iterations )
{
  char buf[MAX_STRING_LENGTH];

  if ( !filename || filename[0] == '\0' )
    sprintf ( buf, "%s", CL_SEND_MUSIC );
  else
    if ( iterations > 1 )
      sprintf ( buf, "%s%s%s%d", CL_SEND_MUSIC, filename, CL_DELIM, iterations );
    else
      sprintf ( buf, "%s%s", CL_SEND_MUSIC, filename );

  send_mip ( buf, ch );

  return;
}



/* Displays an image on client's computer. -gabe
 * Formats: .BMP, .GIF send_mip_image(ch, "weapons.bmp", "Map 1");
 */
void send_mip_image ( CHAR_DATA * ch, char *filename, char *label )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s%s%s", CL_SEND_IMAGE, filename, CL_DELIM, label );
  send_mip ( buf, ch );
  return;
}



/* Display amount of time remaining (HH:MM) until next reboot.  -gabe */
void send_mip_reboot ( CHAR_DATA * ch, char *argument )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", CL_SEND_REBOOT, argument );
  send_mip ( buf, ch );
  return;
}



/* Display amount of time (HH:MM) the mud has been up since last reboot. -gabe */
void send_mip_uptime ( CHAR_DATA * ch, char *argument )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", CL_SEND_UPTIME, argument );
  send_mip ( buf, ch );
  return;
}



/* Trigger an .AVI on the client's computer -gabe */
void send_mip_avi ( CHAR_DATA * ch, char *filename, char *label, int height, int width, bool fRepeat )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s%s%s%s%d%s%d%s%s", CL_SEND_AVI, filename, CL_DELIM, label, CL_DELIM, height,
            CL_DELIM, width, ( fRepeat ) ? CL_DELIM : "", ( fRepeat ) ? "1" : "" );
  send_mip ( buf, ch );
  return;
}



/* Send a media file to the client's hard disk.  -gabe
 * Formats: .WAV, .MID, .RMI, .MP3, .BMP, .GIF, .AVI
 */
void mip_download ( CHAR_DATA * ch, char *filename )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s%s%s%s", CL_DOWNLOAD_MEDIA, filename, CL_DELIM, MIP_MEDIA_URL, filename );
  send_mip ( buf, ch );
  return;
}



/* Send special information to client in a text string  -gabe
 * note: haven't found a use for this, but it's part of mip. so here it is. */
void send_mip_special ( CHAR_DATA * ch, char *argument )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", CL_SEND_SPECIAL, argument );
  send_mip ( buf, ch );
  return;
}



/* Send special guild information to client in a text string -gabe
 * note: haven't found a use for this, but it's a part of mip. so here it is. */
void send_mip_special2 ( CHAR_DATA * ch, char *argument )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", CL_SEND_SPECIAL2, argument );
  send_mip ( buf, ch );
  return;
}



/* Send 'tell' information to player's client -gabe
 * fSender values:
 *  TRUE = ( ch == sender of tell ) + ( victim == receiver of tell )
 *  FALSE = ( ch == receiver of tell ) + ( victim == sender of tell )
 */
void send_mip_tell ( CHAR_DATA * ch, CHAR_DATA * victim, char *argument, bool fSender )
{
  char buf[MAX_STRING_LENGTH];
 
  if ( IS_NPC ( ch ) || IS_NPC ( victim ) )
    return;

  if ( fSender )
  {
    sprintf ( buf, "%sx%s%s%s%s", CL_SEND_TELL, CL_DELIM, victim->name, CL_DELIM, argument );
    send_mip_2 ( buf, ch );
    return;
  }
  else
  {
    sprintf ( buf, "%s%s%s%s%s", CL_SEND_TELL, CL_DELIM, victim->name, CL_DELIM, argument );
    send_mip ( buf, victim );
    return;
  }
}

/* Send short description of a room to player's client  -gabe */
void send_mip_room ( CHAR_DATA * ch, char *argument )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", CL_SEND_ROOM, argument );
  send_mip ( buf, ch );
  return;
}

/* Send a metered lag measurement to client -gabe */
void send_mip_mudlag ( CHAR_DATA * ch, char *argument )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", CL_SEND_MUDLAG, argument );
  send_mip ( buf, ch );
  return;
}

/* Send the current file that is being edited (??) -gabe */
void send_mip_edit ( CHAR_DATA * ch, char *filename )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", CL_SEND_EDIT, filename );
  send_mip ( buf, ch );
  return;
}

/* Set the appropriate mask names on player's client -gabe
 * note: for type values, see mip.h */
void send_mip_mask ( CHAR_DATA * ch, char *type, char *argument )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", type, argument );
  send_mip ( buf, ch );
  return;
}

/* Set the caption on the player's client -gabe */
void send_mip_caption ( CHAR_DATA * ch, char *argument )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", CL_SEND_CAPTION, argument );
  send_mip ( buf, ch );
  return;
}

/* Begin a line-by-line transfer (???) -gabe */
void send_mip_begin_file ( CHAR_DATA * ch, int lines, char *tag )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%d%s%s", CL_SEND_BEGIN_FILE, lines, CL_DELIM, tag );
  send_mip ( buf, ch );
  return;
}

/* Continue a line-by-line transfer (???) -gabe */
void send_mip_cont_file ( CHAR_DATA * ch, char *line )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s", CL_SEND_CONT_FILE, line );
  send_mip ( buf, ch );
  return;
}

/* End a line-by-line transfer (???) -gabe */
void send_mip_end_file ( CHAR_DATA * ch )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s", CL_SEND_END_FILE );
  send_mip ( buf, ch );
  return;
}

/* Send channel information to player's client -gabe */
void send_mip_channel ( CHAR_DATA * ch, const char *cmd, char *channel, char *source, char *argument )
{
  char buf[MAX_STRING_LENGTH];
  char buf2[MAX_STRING_LENGTH];
  sprintf ( buf2, "%s-> %s-> %s", source, channel, argument );
  sprintf ( buf, "%s%s%s%s%s%s%s%s", CL_SEND_CHAT, cmd, CL_DELIM, channel, CL_DELIM, source, CL_DELIM, buf2 );
  send_mip_3 ( buf, ch );
  return;
}

/* Send exit information to player's client (for room monitor) -gabe */
void send_mip_exits ( CHAR_DATA *ch )
{
  EXIT_DATA *exit_l;
  char ex_buf[MSL];
  char buf[MSL];

  strcpy ( ex_buf, "" );

  if ( !ch->in_room )
  {
    bug ( "send_mip_exits (%s): ch->in_room == NULL", ch->name );
    return;
  }

  for ( exit_l = ch->in_room->first_exit; exit_l; exit_l = exit_l->next )
  {
    if ( exit_l->to_room
         && !IS_SET ( exit_l->exit_info, EX_CLOSED )
         && !IS_SET ( exit_l->exit_info, EX_HIDDEN )
         && !IS_SET ( exit_l->exit_info, EX_WINDOW ) )
    {
      switch ( exit_l->vdir )
      {

        default:
          break;

        case DIR_NORTH:
          strcat ( ex_buf, "n " );
          break;

        case DIR_EAST:
          strcat ( ex_buf, "e " );
          break;

        case DIR_SOUTH:
          strcat ( ex_buf, "s " );
          break;

        case DIR_WEST:
          strcat ( ex_buf, "w " );
          break;

        case DIR_UP:
          strcat ( ex_buf, "u " );
          break;

        case DIR_DOWN:
          strcat ( ex_buf, "d " );
          break;

        case DIR_NORTHEAST:
          strcat ( ex_buf, "ne " );
          break;

        case DIR_SOUTHEAST:
          strcat ( ex_buf, "se " );
          break;

        case DIR_NORTHWEST:
          strcat ( ex_buf, "nw " );
          break;

        case DIR_SOUTHWEST:
          strcat ( ex_buf, "sw " );
          break;
      }
    }
  }

  sprintf ( buf, "%s%s", CL_SEND_ROOMCODE, ex_buf );

  send_mip ( buf, ch );
  return;
}



/* Send point information (hit points, mana & move points) -gabe */
void send_mip_points ( CHAR_DATA * ch )
{
  char buf[MAX_STRING_LENGTH];

  sprintf ( buf, "%s%s%d%s%s%d%s%s%d%s%s%d%s%s%d%s%s%d", CL_SEND_COMPOSITE,
            CL_SEND_HP, ch->hit, CL_DELIM,
            CL_SEND_MAXHP, ch->max_hit, CL_DELIM,
            CL_SEND_SP, ch->mana, CL_DELIM,
            CL_SEND_MAXSP, ch->max_mana, CL_DELIM,
            CL_SEND_GP1, ch->move, CL_DELIM,
            CL_SEND_MAXGP1, ch->max_move );

  send_mip ( buf, ch );
  return;
}



/* Send combat information (mob condition/name)  -gabe */
void send_mip_attacker ( CHAR_DATA * ch )
{
  CHAR_DATA * victim;
  char buf[MAX_STRING_LENGTH];
  int condition;

  if ( !ch->fighting || ! ( victim = who_fighting ( ch ) ) )
  {
    sprintf ( buf, "%s%s%s", CL_SEND_COMPOSITE, CL_SEND_ATTACKER, CL_DELIM );
    send_mip ( buf, ch );
    sprintf ( buf, "%s%s%d", CL_SEND_COMPOSITE, CL_SEND_ATTCOND, 0 );
    send_mip ( buf, ch );
    return;
  }

  if ( victim->max_hit > 0 && victim->hit > 0 )
    condition = ( 100 * victim->hit ) / victim->max_hit;
  else
    condition = 0;

  sprintf ( buf, "%s%s%s%s%s%d", CL_SEND_COMPOSITE, CL_SEND_ATTACKER, ( IS_NPC ( victim ) ) ? capitalize
            ( victim->short_descr ) : victim->name, CL_DELIM, CL_SEND_ATTCOND, condition );

  send_mip ( buf, ch );

  return;
}