/
roa/
roa/lib/boards/
roa/lib/config/
roa/lib/edits/
roa/lib/help/
roa/lib/misc/
roa/lib/plrobjs/
roa/lib/quests/
roa/lib/socials/
roa/lib/www/
roa/lib/www/LEDSign/
roa/lib/www/LEDSign/fonts/
roa/lib/www/LEDSign/scripts/
roa/src/s_inc/
roa/src/sclient/
roa/src/sclient/binary/
roa/src/sclient/text/
roa/src/util/
/************************************************************************
	Realms of Aurealis 		James Rhone aka Vall of RoA

misc.c					Misc player commands...

		******** Heavily modified and expanded ********
		*** BE AWARE OF ALL RIGHTS AND RESERVATIONS ***
		******** Heavily modified and expanded ********
		        All rights reserved henceforth. 

    Please note that no guarantees are associated with any code from
Realms of Aurealis.  All code which has been released to the general
public has been done so with an 'as is' pretense.  RoA is based on both
Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well
as the RoA license.   *** Read, Learn, Understand, Improve ***
*************************************************************************/
#include "conf.h"
#include "sysdep.h"

#include "structures.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "acmd.h"
#include "handler.h"
#include "db.h"
#include "magic.h"
#include "mudlimits.h"
#include "house.h"
#include "screen.h"
#include "nature.h"
#include "objsave.h"
#include "quest.h"
#include "fight.h"
#include "lists.h"
#include "global.h"
#include "htown.h"
#include "darkenelf.h"

/* extern variables */
extern struct htown_data htowns[];

/* extern procedures */
extern int check_room_affects(chdata *ch, int room);

int match(char *regex, char *string)
{
  char *rp = regex, *sp = string, ch, *save;

  while (*rp != '\0')
  {
    switch(ch = *rp++)
    {
      case '|':
        if ('\0' == *sp)  /* match empty string at end of `string' */
	  return ('\0' == *rp);  /* but only if we're done with the pattern */
	/* greedy algorithm: save starting location, then find end of string */
	save = sp;
	sp += strlen(sp);
	do
	{
	  if (match(rp, sp))  /* return success if we can match here */
	    return 1;
	} while (--sp >= save);  /* otherwise back up and try again */
	/*
	 * Backed up all the way to starting location (i.e. `*' matches
	 * empty string) and we _still_ can't match here.  Give up.
	 */
	return 0;
	/* break; not reached */
      case '\\':
	if ((ch = *rp++) != '\0')
	{
	  /* if not end of pattern, match next char explicitly */
	  if (ch != *sp++)
	    return 0;
	  break;
	}
	/* else FALL THROUGH to match a backslash */
      default:	/* normal character */
	if (ch != *sp++)
	  return 0;
	break;
    }
  }
  /*
   * OK, we successfully matched the pattern if we got here.  Now return
   * a match if we also reached end of string, otherwise failure
   */
  return ('\0' == *sp);
}

// test substring matching thing
ACMD(do_match)
{
  char *argu = argument;

  skip_spaces(&argu);

  if (!*argu)
  {
    send_to_char("Usage: match <str1> <str2>.\n\r",ch);
    return;
  }

  half_chop(argu, buf, buf2);

  if (match(buf, buf2))
    send_to_char("Passed.\n\r",ch);
  else
    send_to_char("Failed.\n\r",ch);

  return;
}

void do_mortal_chat(chdata *ch, char *argu)
{
  dsdata *d;

  if (!*argu)
  {
    send_to_char("Usage: chat < join | who >.\n\r",ch);
    return;
  }

  if (str_cmp(argu, "join") && str_cmp(argu, "who"))
  {
    send_to_char("Usage: chat < join | who >.\n\r",ch);
    return;
  }

  if (!str_cmp(argu, "join"))
  {
    SET_BIT(CHAR_FLAGS(ch), CH_CHAT);
    send_to_char("Chat mode on.  Type /exit to leave.\n\r",ch);
    return;
  }
  else
  if (!str_cmp(argu, "who"))
  {
    int i = 0;
    strcpy(buf, "%B%6Chat:%0\n\r");
    Descriptors(d)
    {
      if (D_CHECK(d) && CHAR_FLAGGED(d->character, CH_CHAT))
      {
        sprintf(buf+strlen(buf), "%-15.15s", GET_NAME(d->character));
        if (!(++i%4))
          strcat(buf, "\n\r");
      }
    } 
    if ((i%4))
      strcat(buf, "\n\r");
    page_string(ch->desc, buf, 1);
  }
}

void do_immortal_chat(chdata *ch, char *arg)
{
  dsdata *d;

  if (!*arg)
  {
    send_to_char("Usage: chat < join | who | + | - >.\n\r",ch);
    return;
  }

  if (*arg != '+' && *arg != '-' && str_cmp(arg, "join") && str_cmp(arg, "who"))
  {
    send_to_char("Usage: chat < join | who | + | - >.\n\r",ch);
    return;
  }

  if (*arg == '+')
  {
    SET_BIT(PLR2_FLAGS(ch), PLR2_CHAT);
    send_to_char("Chat is now on.\n\r",ch);
    return;
  }
  else
  if (*arg == '-')
  {
    REMOVE_BIT(PLR2_FLAGS(ch), PLR2_CHAT);
    send_to_char("Chat is now off.\n\r",ch);
  }
  else
  if (!str_cmp(arg, "join"))
  {
    SET_BIT(CHAR_FLAGS(ch), CH_CHAT);
    send_to_char("Chat mode on.  Type /exit to leave.\n\r",ch);
    return;
  }
  else
  if (!str_cmp(arg, "who"))
  {
    int i = 0;
    strcpy(buf, "%B%6Chat:%0\n\r");
    Descriptors(d)
    {
      if (D_CHECK(d) && CHAR_FLAGGED(d->character, CH_CHAT))
      {
        sprintf(buf+strlen(buf), "%-15.15s", GET_NAME(d->character));
        if (!(++i%4))
          strcat(buf, "\n\r");
      }
    } 
    if ((i%4))
      strcat(buf, "\n\r");
    page_string(ch->desc, buf, 1);
  }
}

// send char into chat mode...
// or imms to talk on the chat line...
ACMD(do_chat)
{
  char *argu = argument;

  if (IS_NPC(ch)) return;

  if (!IS_IMMORTAL(ch) && !ROOM_FLAGGED(ch->in_room, PEACEFUL))
  {
    send_to_char("You can only enter chat mode in a peaceful area.\n\r",ch);
    return;
  }

  if (FIGHTING(ch))
  {
    send_to_char("You cannot enter chat mode while fighting.\n\r",ch);
    return;
  }

  skip_spaces(&argu);

  if (!IS_IMMORTAL(ch))
    do_mortal_chat(ch, argu);
  else 
    do_immortal_chat(ch, argu);
}

// level 1-maxnewbielevel can type recall for scroll of recall spell...
ACMD(do_recall)
{
  if (IS_NPC(ch))
  {
    send_to_char("Yeah.... ok.\n\r",ch);
    return;
  }

  if (!IS_IMMORTAL(ch) && GET_LEVEL(ch) > maxnewbielevel)
  {
    send_to_char("You are too high a level to use that command...\n\r",ch);
    return;
  }
  
  send_to_char("You call on the mercy of the gods...\n\r",ch);
 
  // ok, cast the actual spell with self as target
  (*spell_info[SPELL_WORD_OF_RECALL].spell_pointer) (ch, "", ch, NULL);
}

// command for newbie mentors -roa
ACMD(do_findcorpse)
{
  obdata *ob;

  if (!PLR2_FLAGGED(ch, PLR2_MENTOR))
  {
    send_to_char("You must be a mentor to use this command.\n\r",ch);
    return;
  }

  sprintf(buf, "%%BPlayer corpses\n\r--------------%%0\n\r");
  for (ob=object_list; ob; ob=ob->next)
    if (!INVALID_ROOM(ob->in_room) && IS_CORPSE(ob) && ob->plr_num > 0)
      sprintf(buf+strlen(buf), "%-30.30s %-30.30s\n\r", ob->shdesc, world[ob->in_room].name);

  page_string(ch->desc, buf, 1);
}

ACMD(do_walkset)
{
   char msg[MAX_POOFIN_LENGTH];
   char *argu = argument;

   if (IS_NPC(ch)) return;

   skip_spaces(&argu);

   if (strlen(argu) > MAX_POOFIN_LENGTH -1)
    {
       send_to_char("That walkin/out is too long...please shorten it.\n\r",ch);
       return;
    }

   if (!*argu)
      strcpy(msg, "");
   else
      strcpy(msg, argu);

   switch(subcmd) {
     case SCMD_WALKIN: 
       if (*msg) 
         strcpy(ch->pc_specials->saved.walkIn, msg);
       else 
       {
         sprintf(buf, "Your walkin is: %s from the <dir>.\n\r", ch->pc_specials->saved.walkIn);
         S2C();
       }
       break;
     case SCMD_WALKOUT: 
       if (*msg) 
         strcpy(ch->pc_specials->saved.walkOut, msg);
       else 
       {
         sprintf(buf, "Your walkout is: %s <dir>\n\r",ch->pc_specials->saved.walkOut);
         S2C();
       }
       break;
     default: 
       break;
   }
   send_to_char("Ok.\n\r", ch);
}

// should be named has valid loadroom
BOOL has_valid_loadroom(chdata *ch)
{
  if (IS_NPC(ch)) return FALSE;
 
  if (REAL_ZONE(GET_LOADROOM(ch) / 100))
    return TRUE;
  else
    return FALSE;
}

ACMD(do_quit)
{
   void cryo_save(chdata *ch);
   void song_from_char(chdata *ch, struct song_affect *sg);
   void remove_song_from_world(chdata *ch, sh_int song);

   struct song_affect *sg;
   dsdata *d, *next_d;

   if (IS_NPC(ch) || !ch->desc || IN_NOWHERE(ch))
      return;

   if (subcmd != SCMD_QUIT) {
      send_to_char("You have to type quit - no less, to quit!\n\r", ch);
      return;
   }

   if (IS_IMMORTAL(ch) && ch->pc_specials->saved.zone_locked)
   {
     send_to_char("You still have a zone locked.\n\r",ch);
     return;
   }

   if (check_num(ch) > MAX_RENT_S)
   {
     sprintf(buf,"Please reduce your inventory to %%6%d%%0 items.\n\r",MAX_RENT_S);
     S2C();
     sprintf(buf, "%%6Failure%%0 to do so will result in EQ %%6LOSS%%0.\n\r");
     S2C();
     return;
   }

   if (GET_POS(ch) == POS_FIGHTING) {
      send_to_char("No way!  You're fighting for your life!\n\r", ch);
      return;
   }

   if (GET_POS(ch) < POS_STUNNED) 
   {
      send_to_char("You die before your time...\n\r", ch);
      die(ch, FALSE);
      return;
   }

   // make newbies (lev 1) able to quit anywhere 10/1/97 -roa   
   if (!IS_IMMORTAL(ch) && PLR_FLAGGED(ch, PLR_LOADROOM) && 
	ch->in_room == real_room(GET_LOADROOM(ch)))
     send_to_char("Loadroom quit confirmed.\n\r",ch);
   else
   if (has_valid_loadroom(ch) && 
      (world[ch->in_room].zone != (htowns[GET_HTOWN(ch)].rvnum / 100)) &&
      (GET_LEVEL(ch) > maxnewbielevel && !IS_IMMORTAL(ch)))
   {   
      sprintf(buf, "You must quit in or near %s.\n\r", htowns[GET_HTOWN(ch)].name);
      S2C();
      return;  
   }

   sg = ch->specials.songs;
   while (sg)
   {
     song_from_char(ch, sg);
     sg = ch->specials.songs;
   }

   if (IS_PC(ch) && SINGING(ch))
   {
     remove_song_from_world(ch, SINGING(ch));
     SINGING(ch) = SONG_TIME(ch) = 0;
   }

   if (IS_PC(ch) && PLAYING(ch))
   {
     remove_song_from_world(ch, PLAYING(ch));
     PLAYING(ch) = PLAY_TIME(ch) = 0;
   }

   save_char_quests(ch);
   cryo_save(ch);    /* JRhone -- no cost to rent here */
   act("Goodbye, friend.. Come back soon!", FALSE, ch, 0, 0, TO_CHAR);
   if (IS_PC(ch) && !GET_INVIS_LEV(ch))
      act("$n has left the realms.", TRUE, ch, 0, 0, TO_ROOM);
   sprintf(buf, "%s has left the realms.", GET_NAME(ch));
   mudlog(buf, NRM, MAX(LEV_GOD, GET_INVIS_LEV(ch)), TRUE);

   /* 
    * kill off all sockets connected to the same player as the one who is
    * trying to quit.  Helps to maintain sanity as well as prevent duping.
    */
   for (d = descriptor_list; d; d = next_d) {
     next_d = d->next;
     if (d == ch->desc)
       continue;
     if (d->character && GET_IDNUM(d->character) && 
         (GET_IDNUM(d->character) == GET_IDNUM(ch)))
       close_socket(d);
   }

   extract_char(ch); /* Char is saved in extract char */
}

ACMD(do_save)
{
  extern void crashsave_room(int vnum);

  if (IS_NPC(ch) || !ch->desc)
     return;

  if (check_num(ch) > MAX_RENT_S)
  {
    sprintf(buf,"Please reduce your inventory to %%6%d%%0 items.\n\r",MAX_RENT_S);
    S2C();
    sprintf(buf, "%%6Failure%%0 to do so will result in EQ %%6LOSS%%0.\n\r");
    S2C();
    return;
  }

  // if autosave, dont echo it
  if (cmd) {
     sprintf(buf, "Saving %s.\n\r", GET_NAME(ch));
     S2C();
  }

  // save the character possessions and such
  save_char_objects(ch);
  save_char_quests(ch);
  save_char(ch, NOWHERE);

  if (ROOM_FLAGGED2(ch->in_room, HOUSE_CRASH))
    crashsave_house(world[ch->in_room].number);
  else
  if (ROOM_FLAGGED2(ch->in_room, ROOM_CRASH))
    crashsave_room(world[ch->in_room].number);

  REMOVE_BIT(ROOM_FLAGS2(ch->in_room), ROOM_CRASH | HOUSE_CRASH); 
}

ACMD(do_not_here)
{
   send_to_char("Huh!?!\n\r", ch);
}

ACMD(do_visible)
{
  void	appear(chdata *ch);

  if (IS_AFFECTED(ch, AFF_INVISIBLE)) 
  {
    appear(ch);
    send_to_char("You break the spell of invisibility.\n\r", ch);
  }  
  else
    send_to_char("You are already visible.\n\r", ch);
}

ACMD(do_title)
{
   char *argu = argument;

   skip_spaces(&argu); 
   if (strlen(argu) >= TITLE_LENGTH - 1)
   {
     send_to_char("That title is too long.\n\r",ch);
     return;
   }

   if (!*argu)
   {
     sprintf(buf, "Current title: %s %s\n\r", GET_NAME(ch), GET_TITLE(ch));
     S2C();
     return;
   }

   if (IS_NPC(ch))
      send_to_char("Your title is fine... go away.\n\r", ch);
   else if (PLR_FLAGGED(ch, PLR_NOTITLE))
      send_to_char("You can't title yourself -- you shouldn't have abused it!\n\r", ch);
   else if (strstr(argu, "(") || strstr(argu, ")"))
      send_to_char("Titles can't contain the ( or ) characters.\n\r", ch);
   else if (strstr(argu, "{") || strstr(argu, "}"))
      send_to_char("Titles can't contain the { or } characters.\n\r", ch);
   else {
      if (GET_TITLE(ch))
         RECREATE(GET_TITLE(ch), char, strlen(argu) + 1);
      else
         CREATE(GET_TITLE(ch), char, strlen(argu) + 1);
      strcpy(GET_TITLE(ch), argu);

      sprintf(buf, "New title: %s %s\n\r", GET_NAME(ch), GET_TITLE(ch));
      S2C();
   }
}

ACMD(do_group)
{
  chdata *victim, *k;
  struct follow_type *f;
  BOOL found;

  one_argument(argument, buf);

  if (!*buf) 
  {
    if (!IS_AFFECTED(ch, AFF_GROUP)) 
      send_to_char("But you are not the member of a group!\n\r", ch);
    else 
    {
      send_to_char("Your group consists of:\n\r", ch);

      while ((k = group_member(ch, FALSE)))
      {
        if (PRF_FLAGGED(k, PRF_INCOGNITO)) 
	  sprintf(buf, "     [%2d/%2dH %2d/%2dM %2d/%2dV] [      ] $N %s",
	          GET_HIT(k),GET_MAX_HIT(k),GET_MANA(k),GET_MAX_MANA(k), 
                  GET_MOVE(k),GET_MAX_MOVE(k), (k == group_leader(ch)) ? "(Leader)" : "");
        else 
          sprintf(buf, "     [%2d/%2dH %2d/%2dM %2d/%2dV] [%2d %s] $N %s",
	          GET_HIT(k),GET_MAX_HIT(k),GET_MANA(k),GET_MAX_MANA(k), 
                  GET_MOVE(k),GET_MAX_MOVE(k),GET_LEVEL(k), CLASS_ABBR(k), 
                  (k == group_leader(ch)) ? "(Leader)" : "");

	act(buf, FALSE, ch, 0, k, TO_CHAR);
      }
    }
    return;
  }

  if (ch->master) 
  {
    act("You can not enroll group members without being head of a group.", FALSE, ch, 0, 0, TO_CHAR);
    return;
  }

   if (!str_cmp(buf, "all")) 
   {
      if (!ch->followers)
      {
	send_to_char("Nobody is following you.\n\r",ch);
	return;
      }
      SET_BIT(AFF_FLAGS(ch), AFF_GROUP);
      for (f = ch->followers; f; f = f->next) 
      {
	 victim = f->follower;
	 if (!IS_AFFECTED(victim, AFF_GROUP) && IS_PC(victim)) 
 	 {
	    act("$N is now a member of your group.", FALSE, ch, 0, victim, TO_CHAR);
	    act("You are now a member of $n's group.", FALSE, ch, 0, victim, TO_VICT);
	    act("$N is now a member of $n's group.", FALSE, ch, 0, victim, TO_NOTVICT);
	    SET_BIT(AFF_FLAGS(victim), AFF_GROUP);
	 }
      }
      return;
   }

   if (!(victim = get_char_room_vis(ch, buf))) {
      send_to_char("No one here by that name.\n\r", ch);
   } else {
      found = FALSE;

      if (IS_NPC(victim))
      {
	send_to_char("Grouping is used for players only.\n\r",ch);
        return;
      }
      else
      if (victim == ch)
      {
	send_to_char("Use group ALL to group yourself.\n\r",ch);
        return;
      }
      else 
	for (f = ch->followers; f; f = f->next) 
	 if (f->follower == victim) 
	 {
	   found = TRUE;
	   break;
	 }

      if (found) {
	 if (IS_AFFECTED(victim, AFF_GROUP)) {
	    act("$N is no longer a member of your group.", FALSE, ch, 0, victim, TO_CHAR);
	    act("You have been kicked out of $n's group!", FALSE, ch, 0, victim, TO_VICT);
	    act("$N has been kicked out of $n's group!", FALSE, ch, 0, victim, TO_NOTVICT);
	    REMOVE_BIT(AFF_FLAGS(victim), AFF_GROUP);
	 } else {
	    act("$N is now a member of your group.", FALSE, ch, 0, victim, TO_CHAR);
	    act("You are now a member of $n's group.", FALSE, ch, 0, victim, TO_VICT);
	    act("$N is now a member of $n's group.", FALSE, ch, 0, victim, TO_NOTVICT);
	    SET_BIT(AFF_FLAGS(victim), AFF_GROUP);
	 }
      } else
	 act("$N must follow you to enter your group.", FALSE, ch, 0, victim, TO_CHAR);
   }
}

ACMD(do_ungroup)
{
   struct follow_type *f, *next_fol;
   chdata *tch;

   one_argument(argument, buf);

   if (!*buf) {
      if (ch->master || !(IS_AFFECTED(ch, AFF_GROUP))) {
	 send_to_char("But you lead no group!\n\r", ch);
	 return;
      }

      sprintf(buf2, "%s has disbanded the group.\n\r", GET_NAME(ch));
      for (f = ch->followers; f; f = next_fol) {
	 next_fol = f->next;
	 if (IS_AFFECTED(f->follower, AFF_GROUP)) {
	    REMOVE_BIT(AFF_FLAGS(f->follower), AFF_GROUP);
	    send_to_char(buf2, f->follower);
	    stop_follower(f->follower);
	 }
      }

      ch->master = 0;
      REMOVE_BIT(AFF_FLAGS(ch), AFF_GROUP);
      send_to_char("You have disbanded the group.\n\r", ch);
      return;
   }

   if (!(tch = get_char_room_vis(ch, buf))) {
      send_to_char("There is no such person!\n\r", ch);
      return;
   }

   if (tch->master != ch) {
      send_to_char("That person is not following you!\n\r", ch);
      return;
   }

   if (IS_AFFECTED(tch, AFF_GROUP))
      REMOVE_BIT(AFF_FLAGS(tch), AFF_GROUP);

   act("$N is no longer a member of your group.", FALSE, ch, 0, tch, TO_CHAR);
   act("You have been kicked out of $n's group!", FALSE, ch, 0, tch, TO_VICT);
   act("$N has been kicked out of $n's group!", FALSE, ch, 0, tch, TO_NOTVICT);
   stop_follower(tch);

  /* check to see if player grouped by themself, if so, disband */
  if (!ch->followers)
  {
    REMOVE_BIT(AFF_FLAGS(ch), AFF_GROUP);
    send_to_char("Your group has been fully disbanded.\n\r",ch);
  }
}

ACMD(do_report)
{
   chdata *k;
   struct follow_type *f;

   if (!IS_AFFECTED(ch, AFF_GROUP)) {
      send_to_char("But you are not a member of any group!\n\r", ch);
      return;
   }

   sprintf(buf, "%s reports: %3d/%3dHit  %3d/%3dMana  %3d/%3dMove\n\r",
       GET_NAME(ch), GET_HIT(ch), GET_MAX_HIT(ch),
       GET_MANA(ch), GET_MAX_MANA(ch), GET_MOVE(ch), GET_MAX_MOVE(ch));

   k = (ch->master ? ch->master : ch);

   for (f = k->followers; f; f = f->next)
      if (IS_AFFECTED(f->follower, AFF_GROUP) && f->follower != ch)
	 send_to_char(buf, f->follower);
   if (k != ch)
      send_to_char(buf, k);
   send_to_char("You report to the group.\n\r", ch);
}

ACMD(do_split)
{
   int	amount, num, share;
   chdata *k;
   struct follow_type *f;

   if (IS_NPC(ch))
      return;

   one_argument(argument, buf);

   if (is_number(buf)) {
      amount = atoi(buf);
      if (amount <= 0) {
	 send_to_char("Sorry, you can't do that.\n\r", ch);
	 return;
      }

      if (amount > GET_GOLD(ch)) {
	 send_to_char("You don't seem to have that much to split.\n\r", ch);
	 return;
      }

      k = (ch->master ? ch->master : ch);

      if (IS_AFFECTED(k, AFF_GROUP) && (k->in_room == ch->in_room))
	 num = 1;
      else
	 num = 0;

      for (f = k->followers; f; f = f->next)
	 if (IS_AFFECTED(f->follower, AFF_GROUP) && 
	     (IS_PC(f->follower)) && 
	     (f->follower->in_room == ch->in_room))
	    num++;

      if (num && IS_AFFECTED(ch, AFF_GROUP))
	 share = amount / num;
      else {
	 send_to_char("With whom do you wish to share?\n\r", ch);
	 return;
      }

      GET_GOLD(ch) -= share * (num - 1);

      if (IS_AFFECTED(k, AFF_GROUP) && (k->in_room == ch->in_room) && !(IS_NPC(k)) &&  k != ch) 
      {
	 GET_GOLD(k) += share;
	 sprintf(buf, "%s splits %d %s; you receive %d.\n\r", GET_NAME(ch), amount, 
		 currency_name_plural, share);
	 send_to_char(buf, k);
      }

      for (f = k->followers; f; f = f->next) 
      {
	 if (IS_AFFECTED(f->follower, AFF_GROUP) && (IS_PC(f->follower)) && 
	     (f->follower->in_room == ch->in_room) && f->follower != ch) 
         {
	    GET_GOLD(f->follower) += share;
	    sprintf(buf, "%s splits %d %s; you receive %d.\n\r", GET_NAME(ch),
	        amount, currency_name_plural, share);
	    send_to_char(buf, f->follower);
	 }
      }

      sprintf(buf, "You split %d %s among %d members; %d %s each.\n\r",
          amount, currency_name_plural, num, share, currency_name_plural);
      S2C();
   } else {
      send_to_char("How much do you wish to split with your group?\n\r", ch);
      return;
   }
}

ACMD(do_wimpy)
{
   int	wimp_lev;

   if (IS_NPC(ch)) return;

   one_argument(argument, arg);

   if (!*arg) {
      if (WIMP_LEVEL(ch)) {
	 sprintf(buf, "Your current wimp level is %d hit points.\n\r",
	     ch->pc_specials->saved.wimp_level);
	 S2C();
	 return;
      } else {
	 send_to_char("At the moment, you are not a wimp.  (sure, sure...)\n\r", ch);
	 return;
      }
   }

   if (isdigit(*arg)) {
      if ((wimp_lev = atoi(arg))) {
	 if (wimp_lev < 0) {
	    send_to_char("Heh, heh, heh.. we are jolly funny today, eh?\n\r", ch);
	    return;
	 }
	 if (wimp_lev > GET_MAX_HIT(ch)) {
	    send_to_char("That doesn't make much sense, now does it?\n\r", ch);
	    return;
	 }
	 sprintf(buf, "OK, you'll wimp out if you drop below %d hit points.\n\r",
	     wimp_lev);
	 S2C();
	 WIMP_LEVEL(ch) = wimp_lev;
      } else {
	 send_to_char("OK, you'll now tough out fights to the bitter end.\n\r", ch);
	 WIMP_LEVEL(ch) = 0;
      }
   } else
      send_to_char("Specify at how many hit points you want to wimp out at.  (0 to disable)\n\r", ch);

   return;

}

ACMD(do_gen_write)
{
   FILE * fl;
   char	*tmp, *filename;
   long	ct;
   char	str[MAX_STRING_LENGTH];
   char *argu = argument;

   switch (subcmd) {
   case SCMD_BUG:	filename = BUG_FILE; break;
   case SCMD_TYPO:	filename = TYPO_FILE; break;
   case SCMD_IDEA:	filename = IDEA_FILE; break;
   default: return;
   }

   ct  = time(0);
   tmp = asctime(localtime(&ct));

   if (IS_NPC(ch)) {
      send_to_char("Monsters can't have ideas - Go away.\n\r", ch);
      return;
   }

   skip_spaces(&argu);
   if (!*argu) {
      send_to_char("That must be a mistake...\n\r", ch);
      return;
   }

   if (!(fl = fopen(filename, "a"))) {
      perror ("do_gen_write");
      send_to_char("Could not open the file.  Sorry.\n\r", ch);
      return;
   }
   sprintf(str, "%-8s (%6.6s) [%5d] %s\n", GET_NAME(ch), (tmp + 4),
       world[ch->in_room].number, argu);
   fputs(str, fl);
   fclose(fl);
   send_to_char("Ok.  Thanks.  :)\n\r", ch);
}

#define TOG_OFF 0
#define TOG_ON  1

#define PRF_TOG_CHK(ch,flag) ((TOGGLE_BIT(PRF_FLAGS(ch), (flag))) & (flag))

// some big changes due to channel remove 4/10/98 -jtrhone
// some more changes due to channel returns 4/11/98 -jtrhone
ACMD(do_gen_tog)
{
   long	result;
   int level = 0;

   char	*tog_messages[][2] = {
      { "You are now safe from summoning by other players.\n\r",
      "You may now be summoned by other players.\n\r" },
      { "Nohassle disabled.\n\r", 
      "Nohassle enabled.\n\r" },
      { "Brief mode off.\n\r", 
      "Brief mode on.\n\r" },
      { "Compact mode off.\n\r", 
      "Compact mode on.\n\r" },
      { "You can now hear tells.\n\r", 
      "You are now deaf to tells.\n\r" },
      { "You can now hear auctions.\n\r", 
      "You are now deaf to auctions.\n\r" },
      { "You can hear again.\n\r", 
      "You are now deaf to bellows and yells.\n\r" },
      { "You can now hear the Wiz-channel.\n\r", 
      "You are now deaf to the Wiz-channel.\n\r" },
      { "You will no longer see the room flags.\n\r", 
      "You will now see the room flags.\n\r" },
      { "You will now have your communication repeated.\n\r",
      "You will no longer have your communication repeated.\n\r" },
      { "HolyLight mode off.\n\r",
      "HolyLight mode on.\n\r" },
      { "Nameserver_is_slow ->NO; IP addresses will now be resolved.\n\r",
      "Nameserver_is_slow ->YES; sitenames will no longer be resolved.\n\r" },
      { "You no longer see autoexits.\n\r",
      "You now see exits automatically when you enter a room.\n\r" },
      { "Your class and level are now visible to others.\n\r",
      "You go incognito, your class and level are hidden from others.\n\r"},
      { "You will no longer see player advancements/deaths.\n\r",
      "You now see player advancements/deaths.\n\r"},
      { "You no longer wish to become a member of the Circle of Assassins.\n\r",
      "You wish to become a member of the Assassin Circle.\n\r"},
      { "Short exits off.\n\r",
      "Short exits on.\n\r" },
      { "You can now hear OOC.\n\r",
      "You will no longer hear OOC.\n\r" },
      { "You can now hear QA channels.\n\r",
      "You will no longer hear QA channels.\n\r" },
      };
   

   if (IS_NPC(ch)) 
      return;

   switch (subcmd) {
   case SCMD_NOSUMMON	: result = PRF_TOG_CHK(ch, PRF_SUMMONABLE); break;
   case SCMD_NOHASSLE	: result = PRF_TOG_CHK(ch, PRF_NOHASSLE); break;
   case SCMD_BRIEF	: result = PRF_TOG_CHK(ch, PRF_BRIEF); break;
   case SCMD_COMPACT	: result = PRF_TOG_CHK(ch, PRF_COMPACT); break;
   case SCMD_NOAUCTION	: result = PRF_TOG_CHK(ch, PRF_NOAUCT); break;
   case SCMD_DEAF	: result = PRF_TOG_CHK(ch, PRF_DEAF); break;
   case SCMD_NOWIZ	: result = PRF_TOG_CHK(ch, PRF_NOWIZ); break;
   case SCMD_ROOMFLAGS	: result = PRF_TOG_CHK(ch, PRF_ROOMFLAGS); break;
   case SCMD_NOREPEAT	: result = PRF_TOG_CHK(ch, PRF_NOREPEAT); break;
   case SCMD_HOLYLIGHT  : result = PRF_TOG_CHK(ch, PRF_HOLYLIGHT); break;
   case SCMD_SLOWNS	: result = (nameserver_is_slow = !nameserver_is_slow); break;
   case SCMD_AUTOX      : result = PRF_TOG_CHK(ch, PRF_AUTOX); break;
   case SCMD_INCOGNITO  : result = PRF_TOG_CHK(ch, PRF_INCOGNITO); break; 
   case SCMD_MORTLOG    : result = PRF_TOG_CHK(ch, PRF_MORTLOG); break;
   case SCMD_SHORTX     : result = PRF_TOG_CHK(ch, PRF_SHORTX); break;
   case SCMD_NOOOC      : result = PRF_TOG_CHK(ch, PRF_NOOOC); break;
   case SCMD_NOQA       : result = PRF_TOG_CHK(ch, PRF_NOQA); break;

   case SCMD_NOTELL	: result = PRF_TOG_CHK(ch, PRF_NOTELL); 
      if (IS_IMMORTAL(ch))
      {
	one_argument(argument, arg);
	if (!*arg) 
	  level = 0; 
	else
	  level = atoi(arg); 
	level = MIN(level, GET_LEVEL(ch));
	level = MAX(level, 0);
	TELL_LEV(ch) = level;
      }
	break;

   case SCMD_REQASS :
      if (PRF_FLAGGED(ch, PRF_ASSASSIN)) {
        send_to_char("You already are a member of the Circle of Assassins.\n\r",ch);
        return;
        break;
      } else {
        result = PRF_TOG_CHK(ch, PRF_REQASS);
        break;
      }
   default :
      return;
   }

   if (result)
      send_to_char(tog_messages[subcmd][TOG_ON], ch);
   else
      send_to_char(tog_messages[subcmd][TOG_OFF], ch);

   if (level)
   {
     sprintf(buf, "Level %d.\n\r",level);
     S2C();
   }
}


ACMD(do_ignore)  
{
  CharFileU tch;
  IdList *gag, *temp;
  int sortpos = 0, count = 0;
  extern char *get_name_by_id(long id), *num_to_word[];

  *buf = '\0';
  *buf2 = '\0';

  one_argument(argument, arg);

  if (!*arg) {
    send_to_char("%6You are currently ignoring:%0\r\n", ch);

    if (!ch->gagged)  
      send_to_char("  No-one.\r\n", ch);
    else {
      for (gag = ch->gagged; gag; gag = gag->next) {
        strcpy(buf2, get_name_by_id(gag->idnum));
        sprintf(buf, "%s%-12.12s", buf, CAP(buf2));
        sortpos++;
        count++;

        if (sortpos == 6) {
          sortpos = 0;
          strcat(buf, "\r\n");
        }
      }
      send_to_char(tprintf("%s\r\n%%6Total:%%0 %s\r\n", buf, num_to_word[count]), ch);
    }
    return;
  }
  if (load_char(arg, &tch) < 0) {
    send_to_char("There is no such player.\r\n", ch);
    return;
  }
  if (!strcmp(Name(ch), tch.name)) {
    send_to_char("You cannot ignore yourself!\r\n", ch);
    return;
  }
  for (gag = ch->gagged; gag; gag = gag->next)   
    if (tch.saved.idnum == gag->idnum)
      break;
        
  if (!gag) {
    if ((Shade(ch) && (tch.level <= Level(ch))) || (!Shade(ch) && (tch.level < LVL_ULUTIU))) {
      strcpy(buf2, tch.name);
      send_to_char(tprintf("You will now ignore %s.\r\n", CAP(buf2)), ch);
  
      CREATE(gag, IdList, 1);
 
      gag->idnum = tch.saved.idnum;
      gag->next = ch->gagged;
      ch->gagged = gag;
    } else
      send_to_char(tprintf("You are not powerful enough to ignore %s!\r\n", tch.name), ch);
    return;
  }

  /* Remove from gag list */
  send_to_char(tprintf("You are no longer ignoring %s.\r\n", tch.name), ch);
  REMOVE_FROM_LIST(gag, ch->gagged, next);
  
  // must free them... 3/18/98 -jtrhone
  FREENULL(gag);
  return;
}


ACMD(do_nogive)
{
  if(IS_NPC(ch)) return;
  TOGGLE_BIT(PRF2_FLAGS(ch), PRF2_NOGIVE);
  if(PRF2_FLAGGED(ch, PRF2_NOGIVE)) 
    send_to_char("NoGive on: Nobody can give you anything now.\r\n", ch);
  else 
    send_to_char("NoGive off.\r\n", ch);
}

ACMD(do_autogold)
{
  if(IS_NPC(ch)) return;

  TOGGLE_BIT(PRF_FLAGS(ch), PRF_AGOLD);

  if(PRF_FLAGGED(ch, PRF_AGOLD)) 
    sprintf(buf, "You will now automatically get %s from fallen enemies.\n\r", currency_name_plural);
  else 
    sprintf(buf, "You will no longer get %s from fallen enemies automatically.\n\r", currency_name_plural);
  S2C();
}

ACMD(do_autosplit)
{
  if(IS_NPC(ch)) return;
  TOGGLE_BIT(PRF_FLAGS(ch), PRF_ASPLIT);

  if(PRF_FLAGGED(ch, PRF_ASPLIT)) 
    sprintf(buf, "You will now automatically split %s from fallen enemies.\n\r", currency_name_plural);
  else 
    sprintf(buf, "You will no longer split %s from fallen enemies automatically.\n\r", currency_name_plural);
  S2C();
}

ACMD(do_autoloot)
{
  if(IS_NPC(ch)) return;
  TOGGLE_BIT(PRF_FLAGS(ch), PRF_ALOOT);
  if(PRF_FLAGGED(ch, PRF_ALOOT)) 
    send_to_char("You will now loot corpses automatically.\r\n", ch);
  else 
    send_to_char("You will no longer loot corpses automatically.\r\n", ch);
}

/* toggle the seperator bit on a player, used to seperate descrips */
/* makes stuff easier to read -roa*/
ACMD(do_line)
{
  if(IS_NPC(ch)) return;
  TOGGLE_BIT(PLR_FLAGS(ch), PLR_LINE);
  if(PLR_FLAGGED(ch, PLR_LINE)) 
    send_to_char("Line is ON.\r\n", ch);
  else 
    send_to_char("Line is OFF.\r\n", ch);
}

/* toggle legend bit for players who are level IMMORT-1 */
/* who list shows [Legend] for em if set -roa */
ACMD(do_legend)
{
  if(IS_NPC(ch)) return;
  if (GET_LEVEL(ch) != LEV_IMM -1)
  {
    send_to_char("You are no legend...\n\r",ch);
    return;
  }
  TOGGLE_BIT(PLR_FLAGS(ch), PLR_LEGEND);
  if(PLR_FLAGGED(ch, PLR_LEGEND)) 
    send_to_char("Legend is ON.\r\n", ch);
  else 
    send_to_char("Legend is OFF.\r\n", ch);
}

/********* assassin channel ********/
ACMD(do_asay)
{
  dsdata *d;
  char *argu = argument;
  char buf[20000];

  if (IS_NPC(ch)) return;

  if (!IS_ASSASSIN(ch))
  {
    send_to_char("You are not an assassin!\n\r",ch);
    return;
  }

  skip_spaces(&argu);

  if (!*argu)
  {
    send_to_char("What do you wish to assassin say??\n\r",ch);
    return;
  }

  if (*argu == '+')
  {
    SET_BIT(PRF_FLAGS(ch), PRF_ASSA_CH);
    send_to_char("You join the assassin channel ( - to turn off).\n\r",ch);
    return;
  }
  else
  if (*argu == '-')
  {
    REMOVE_BIT(PRF_FLAGS(ch), PRF_ASSA_CH);
    send_to_char("You turn the assassin channel off.\n\r",ch);
    return;
  }

  if (!PRF_FLAGGED(ch, PRF_ASSA_CH))
  {
    send_to_char("You have the assassin channel turned off! ( + to turn on)\n\r",ch);
    return;
  }

  if (*argu == '?')
  {
    sprintf(buf, "%%1Assassins%%0 online and on channel:\n\r"); 
    for (d = descriptor_list; d; d = d->next)
      if (D_CHECK(d) && IS_PC(d->character) &&
          IS_ASSASSIN(d->character) && PRF_FLAGGED(d->character,PRF_ASSA_CH) &&
          GET_LEVEL(ch) >= GET_INVIS_LEV(d->character))
      {
          sprintf(buf2, "   %s\n\r",GET_NAME(d->character));
          strcat(buf, buf2);
      }

    page_string(ch->desc, buf, 1);
    return;
  }

  sprintf(buf, "You assassin-say '%s'\n\r",argu);
  S2C();

  for (d = descriptor_list; d; d = d->next)
    if (D_CHECK(d) && d != ch->desc && IS_PC(d->character) && 
	IS_ASSASSIN(d->character) && SEND_OK(d->character) && 
	PRF_FLAGGED(d->character, PRF_ASSA_CH) &&
	!ROOM_FLAGGED2(d->character->in_room, SOUNDPROOF))
    {
        sprintf(buf, "[%%1Assassin%%0] %s: %s\n\r",GET_NAME(ch),argu);
        send_to_char(buf, d->character);
    }
}

/* command for player to see what levels certain zones are designed
   for using the mob chart calculations and level averages set into
   zone_levels[] at bootup... RoA  James Rhone */
ACMD(do_zonehelp)
{
  int real_zone(int zone);
  int zone;
  char zstr1[20];
  BOOL line;
  char buf[20000];
  extern int zone_levels[];
  extern zndata zone_table[NUM_ZONES];

  if (IS_NPC(ch)) return;

  sprintf(buf, "%%B%s Area Listing%%0\n\r", longmudname);
  S2C();

  underline(buf);
  sprintf(buf2, "%%B%s%%0", buf);
  send_to_char(buf2, ch);

  *buf = '\0';
  for (zone = 1, line = TRUE; zone < NUM_ZONES; zone++)
    if (REAL_ZONE(zone) && !ZONE_FLAGGED(zone, Z_CLOSED) &&
	!ZONE_FLAGGED(zone, Z_IMMORT) && !ZONE_FLAGGED(zone, Z_LOCKED)
        && !ZONE_FLAGGED(zone, Z_SYSTEM) && !ZONE_FLAGGED(zone, Z_HIDDEN))
    {
	if (zone_levels[zone] >= 70)
	  sprintf(zstr1, "Lord     ");
	else
	if (zone_levels[zone] >= 60)
	  sprintf(zstr1, "Very High");
	else
	if (zone_levels[zone] >= 50)
	  sprintf(zstr1, "High-Mid ");
	else
	if (zone_levels[zone] >= 40)
	  sprintf(zstr1, "Mid Level");
	else
	if (zone_levels[zone] >= 30)
	  sprintf(zstr1, "Mid-Low  ");
	else
	if (zone_levels[zone] >= 20)
	  sprintf(zstr1, "Low level");
	else
	  sprintf(zstr1, "Low-NewB ");
	
	sprintf(buf1, "%22.22s (%%B%s%%0)   ", zone_table[zone].name, zstr1);	
	if ((line = !line)) strcat(buf1, "\n\r");
	strcat(buf, buf1);
    }
  page_string(ch->desc, buf, 1);
}

/* if a gate is in the room, trans them to its location RoA*/
ACMD(do_enter_gate)
{
  obdata *gate;
  BOOL found = FALSE;
  int room;

  if (INVALID_ROOM(ch->in_room))
    return;

  for (gate = world[ch->in_room].contents; gate; gate = gate->next_content)
    if (ITEM_TYPE(gate) == ITEM_GATE)
    {
	found = TRUE;
	break;
    }

  if (!found)
  {
    send_to_char("You do not see a %Bportal%0 here.\n\r",ch);
    return;
  }

  if ((room = gate->value[0]) <= 0)
  {
    send_to_char("The %Bportal%0 doesn't seem to be functioning properly.\n\r",ch);
    return;
  }

  if (IS_NPC(ch) && ROOM_FLAGGED(room, NO_MOB))
  {
    send_to_char("Some unknown force prevents you from entering the portal.\n\r",ch);
    return;
  }

  if (MOB_FLAGGED(ch, MOB_NO_GATE))
  {
    send_to_char("Some unknown force prevents you from entering the portal.\n\r",ch);
    return;
  }

  act("You step into $p", FALSE, ch, gate, 0, TO_CHAR);
  act("$n steps into $p.", TRUE, ch, gate, 0, TO_ROOM);
  char_from_room(ch);
  char_to_room(ch, room);
  do_look_at_room(ch, 0, 0);
  act("$n steps out of $p.", TRUE, ch, gate, 0, TO_ROOM);

  if (check_room_affects(ch, ch->in_room) == CHAR_DIED)
    return;
  if (check_death_trap(ch, NULL))
    return;
  float_sink_char(ch);
}

// Modified to allow AFK messages 05/04/98 -callahan
ACMD(do_afk)
{
  char *argu = argument;

  if (IS_NPC(ch))
    return;

  if (strlen(argu) > 11) {
    send_to_char("AFK messages may be up to 10 characters in length.\r\n", ch);
    return;
  }

  if (*argu != '\0') {
    if (AFKString(ch))
      RECREATE(AFKString(ch), char, strlen(argu) + 1);
    else
      CREATE(AFKString(ch), char, strlen(argu) + 1);
    strcpy(AFKString(ch), argu);
  }

  SET_BIT(PLR_FLAGS(ch), PLR_AFK);
  send_to_char("You are now flagged %BAFK%0.\n\r",ch);
  return;
}

/* allows players to choose a hometown if they are in the right gateway */
/* RoA jtrhone */
ACMD(do_settle)
{
  int i;
  int vroom = world[ch->in_room].number;
  BOOL found = FALSE;

  if (IS_NPC(ch) || ch->in_room == NOWHERE) 
    return;

  for (i = 0; i < MAX_HTOWNS && htowns[i].name && *htowns[i].name; i++)
   if (htowns[i].rvnum == vroom)
   {
     found = TRUE;
     break;
   }

  if (!found)
  {
    send_to_char("You must be located in a %BGateway%0 to settle.\n\r",ch);
    return;
  }

  if (!htowns[i].races[GET_RACE(ch)])
  {
    sprintf(buf, "You, %s, are not allowed to call %s your home.\n\r",
	    rcarray[GET_RACE(ch)].race_name, htowns[i].name);
    S2C();
    return;
  }

  GET_HTOWN(ch) = i;
  GET_LOADROOM(ch) = htowns[i].rvnum;
  sprintf(buf, "You now call %s your home.\n\r",htowns[i].name);
  S2C();
}

// updated for slot revamp 5/28/98 -jtrhone
ACMD(do_light)
{
   obdata *obj;

   if (!(obj = EQ(ch, W_HOLD)) || !OBJ_LIGHT(obj))
   {
     send_to_char("You are not carrying a light source!\n\r",ch);
     return;
   }

   if (LIT(obj))
   {
     send_to_char("That's already emitting light!\n\r",ch);
     return;
   }

   if (!LIGHT_TIME(obj))
   {
     act("You discover that $p is useless.",TRUE,ch,obj,0,TO_CHAR);
     return;
   }

   if (ROOM_FLAGGED(ch->in_room, UWATER) && !OBJ_FLAGGED(obj, ITEM_WATERPROOF))
   {
     act("$p will not work underwater.", TRUE, ch, obj, 0, TO_CHAR);
     return;
   }

   obj->lit = TRUE;
   act("$p starts emitting light.", TRUE, ch, obj, 0, TO_CHAR);

   if (world[ch->in_room].light >= 0)
   {
     world[ch->in_room].light++;
     act("You light the area with $p.",TRUE,ch,obj,0,TO_CHAR);
     act("The area surrounding you gets slightly %Bbrighter%0.",FALSE,ch,0,0,TO_ROOM);
   }
}

ACMD(do_extinguish)
{
   obdata *obj;

   obj = EQ(ch, W_HOLD);

   if (!obj)
   {
     send_to_char("You are not carrying a light source!\n\r",ch);
     return;
   }

   if (!OBJ_LIGHT(obj))
   {
     send_to_char("You can't extinguish that.\n\r",ch);
     return;
   }

   if (!LIT(obj))
   {
     send_to_char("That's not emitting any light!\n\r",ch);
     return;
   }

   obj->lit = FALSE;

   if (world[ch->in_room].light > 0)
   {
     if ((world[ch->in_room].light--))
     {
       act("You extinguish $p and darken the area.",TRUE,ch,obj,0,TO_CHAR);
       act("The area around you gets slightly darker.",FALSE,ch,0,0,TO_ROOM);
     }
     else
     {
       act("The area surrounding you is suddenly dark!",FALSE,ch,0,0,TO_CHAR);
       act("The area surrounding you is suddenly dark!",FALSE,ch,0,0,TO_ROOM);
     }     
   }
}

// info channel stuff begins here, -RoA (jtrhone, as always :))
// every tick, broadcast a tidbit of useful info for those who are
// tuned into the info channel

// here is the meat, the info, the main stuff
void get_info_tidbit(char *str)
{
  switch(number(1, 50)) {
   case 1:
    strcpy(str, "For players level 5 and up, %Bmfinger%0 is available.");
    break;
   case 2:
    strcpy(str, "To see the who list with most flags, try %Bwho -f%0.");
    break;
   case 3:
    strcpy(str, "To see a shorter version of who, try %Bwho -s%0.");
    break;
   case 4:
    sprintf(str, "%s has VT100 emulation mode, try %%Bhelp vt100%%0.", shortmudname);
    break;
   case 5:
    strcpy(str, "The command %Bbars%0 works well with VT100 mode.");
    break;
   case 6:
    sprintf(str, "%s has a multitude of color support, help %%Bccodes%%0.", shortmudname);
    break;
   case 7:
    strcpy(str, "The command %Bafk%0 lets others know you are afk.");
    break;
   case 8:
    sprintf(str, "%s has over 250 socials, type %%Bsocials%%0 for a list.", shortmudname);
    break;
   case 9:
    strcpy(str, "Try %Bhelp%0 with no argument for a list of help topics.");
    break;
   case 10:
    strcpy(str, "Try %Bhelp arena%0 for more info on arena contests.");
    break;
   case 11:
    sprintf(str, "%s has %%Bautoloot, autogold and autosplit%%0.  See help.", shortmudname);
    break;
   case 12:
    strcpy(str, "Aliases make mudding easier, try %Bhelp alias%0 for more info on our alias system.");
    break;
   case 13:
    sprintf(str, "If you have a slow connection to %s, try %%Bbrief%%0.", shortmudname);
    break;
   case 14:
    sprintf(str, "To get a list of areas and their targetted levels on %s, type %%Bareas%%0.", 
	    shortmudname);
    break;
   case 15:
    strcpy(str, "If you're not sure about an enemy's strength, always %Bconsider%0 it first.");
    break;
   case 16:
    sprintf(str, "%s has customizeable equipment available, try %%Bhelp custom%%0.", shortmudname);
    break;
   case 17:
    strcpy(str, "Some items deterioriate over time and need to be %Brepair%0ed.");
    break;
   case 18:
    strcpy(str, "You can toggle your autoexit display by typing %Bautoexit%0.");
    break;
   case 19:
    strcpy(str, "If you use autoexits, try %Bshortx%0 for a compact display.");
    break;
   case 20:
    strcpy(str, "Try %Blevels%0 to see a list of your class's experience levels.");
    break;
   case 21:
    strcpy(str, "To seperate room descrips from characters and objects, type %Bline%0.");
    break;
   case 22:
    strcpy(str, "Some NPCs are mountable, try %Bhelp mount%0 for more info.");
    break;
   case 23:
    strcpy(str, "Try %Bmortlog%0 to see a log of players' advancements and deaths.");
    break;
   case 24:
    strcpy(str, "The command %Bincognito%0 hides your race and class from others.");
    break;
   case 25:
    strcpy(str, "You can empty containers by %Bpour%0ing them out.");
    break;
   case 26:
    strcpy(str, "Some races can %Bsettle%0 in a variety of hometowns.");
    break;
   case 27:
    strcpy(str, "For a break from the monotony, try %Btag%0.");
    break;
   case 28:
    strcpy(str, "Some races have unique languages, %Bhelp speak%0 for more info.");
    break;
   case 29:
    strcpy(str, "Try the command %Bskills%0 for all the skills available to your class.");
    break;
   case 30:
    strcpy(str, "To see the current mud time, type %Btime%0.");
    break;
   case 31:
    strcpy(str, "To see the current weather conditions, type %Bweather%0.");
    break;
   case 32:
    strcpy(str, "To break a spell of invisibility on yourself, type %Bvisible%0.");
    break;
   case 33:
    strcpy(str, "%BNochan%0 turns off all channels, %Ballchan%0 turns them on.");
    break;
   case 34:
    strcpy(str, "Type %Btoggle%0 to view your channel and preference status.");
    break;
   case 35:
    strcpy(str, "Words in %Bbold%0 represent help keywords or commands.");
    break;
   case 36:
    strcpy(str, "For a bit of insight on newbie areas, %Bhelp newbiearea%0.");
    break;
   case 37:
    strcpy(str, "Mentors are players who have offered to help newbies... %Bhelp mentor%0.");
    break;
   case 38:
    sprintf(str, "%s has an automated questing system... %%Bhelp qlist, qscore, qdescribe%%0.", 
            shortmudname);
    break;
   case 39:
    strcpy(str, "For general newbie information, try %Bhelp newbie%0.");
    break;
   case 40:
    strcpy(str, "To see what you are affected by, type %Baffects%0.");
    break;
   default:
    strcpy(str, "This channel can be toggled by typing %Binfochan%0.");
    break;
  }
  return;
}

void info_broadcast(void)
{
  dsdata *d;

  get_info_tidbit(buf2);

  for (d = descriptor_list; d; d = d->next)
    if (D_CHECK(d) && IS_PC(d->character) &&
	SEND_OK(d->character) && PLR_FLAGGED(d->character, PLR_INFOCH))
     {
        sprintf(buf, "[%%b%%5Info%%0] %s\n\r",buf2);
        send_to_char(buf, d->character);
     }
}

ACMD(do_infochannel)
{
  if(IS_NPC(ch)) return;
  TOGGLE_BIT(PLR_FLAGS(ch), PLR_INFOCH);
  if(PLR_FLAGGED(ch, PLR_INFOCH)) 
    send_to_char("%B%5Info channel on%0.\n\r",ch);
  else
    send_to_char("%B%5Info channel off%0.\n\r",ch);
}