exodus2/
exodus2/area/mobscr/
exodus2/area/mobvoc/
exodus2/bin/
exodus2/clans/
exodus2/gods/
exodus2/player/A/
exodus2/player/B/
exodus2/player/D/
exodus2/player/E/
exodus2/player/L/
exodus2/player/M/
exodus2/player/O/
exodus2/player/R/
exodus2/src/obj/clans/
//
// new_clans_comm.c
//
// Programmer: Akamai
// Date: 7/10/98
// Version: 1.0
//

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "../include/merc.h"
#include "../include/olc.h"
#include "new_clans.h"
#include "new_clans_comm.h"
#include "new_clans_io.h"
#include "new_clans_util.h"

//
// some globals used by the rest of the clan code
//
int _clan_ident_ = 1;
int clan_number = 0;
struct clan_type clan_table[MAX_CLAN];

//
// Private functions that implement clan commands
//
void do_clan_imm (CHAR_DATA * ch);
void do_clan_dispatch (CHAR_DATA * ch, char *arg, char *argument);
void clan_who (CHAR_DATA * ch, char *argument);
void clan_list (CHAR_DATA * ch, char *argument);
void clan_help (CHAR_DATA * ch, char *argument);
void clan_loner (CHAR_DATA * ch);
void clan_apply (CHAR_DATA * ch, char *argument);
void clan_defect (CHAR_DATA * ch);
void clan_ally (CHAR_DATA * ch, char *argument);
void clan_enemy (CHAR_DATA * ch, char *argument);
void clan_declare (CHAR_DATA * ch, char *argument);
void clan_last (CHAR_DATA * ch);
void clan_wars (CHAR_DATA * ch);
void clan_info (CHAR_DATA * ch, char *argument);
void clan_accept (CHAR_DATA * ch, char *argument);
void clan_deny (CHAR_DATA * ch, char *argument);
void clan_prospects (CHAR_DATA * ch, char *argument);
void clan_expel (CHAR_DATA * ch, char *argument);
void clan_deputy (CHAR_DATA * ch, char *argument);
void clan_establish (CHAR_DATA * ch, char *argument);
void add_clan (CHAR_DATA * ch, char *argument);
void clan_donate (CHAR_DATA * ch, char *argument);
void clan_disband (CHAR_DATA * ch, char *argument);
void clan_leader (CHAR_DATA * ch, char *argument);
void clan_symbol (CHAR_DATA * ch, char *argument);
void clan_bye (CHAR_DATA * ch);
void clan_short_status (CHAR_DATA * ch, char *argument);
void clan_activate (CHAR_DATA * ch, char *argument);
void clan_list_imm (CHAR_DATA * ch, char *argument);
bool clan_list_status (CHAR_DATA * ch, int status);
void clan_altar (CHAR_DATA * ch, char *argument);
void list_allies (CHAR_DATA * ch, int slot);
void list_enemies (CHAR_DATA * ch, int slot);
void remove_clan_relations (int ident);

void cj_self args((CHAR_DATA *ch, char* argument));

//
// This const simplifies indexing though the different
// clan status values. Clan statuses are not contiguous
// numbers -- so this works as an indirect index table.
//
const int clan_statuses[CLAN_STATUSES] =
  { CLAN_INACTIVE, CLAN_DISBAND, CLAN_DISPERSED, CLAN_HISTORICAL,
  CLAN_PROPOSED, CLAN_RESTRICTED, CLAN_ACTIVE
};

// ==============================================================
//
//   Public Function Entry to clan Code
//
// ==============================================================
//
// This is a big dispatch for most of the clan commands
//
void do_clan (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  argument = one_argument (argument, arg);

  // this might need to change if we allow mob clans
  //act(ch->name,ch,NULL,NULL,TO_ROOM);
  //act(act_bit_name (ch->act),ch,NULL,NULL,TO_ROOM);
//  send_to_char(act_bit_name (ch->act),ch);
  if (IS_NPC (ch))
    {

      //act("HE's a FCUKING NPC!",ch,NULL,NULL,TO_ROOM);
      return;
    }
  if (IS_IMMORTAL (ch) && (arg[0] == '\0'))
    {

//           act("bitch-ass imm",ch,NULL,NULL,TO_ROOM);
      do_clan_imm (ch);
      return;
    }

  else if (arg[0] == '\0')
    {

      //    act("listing clan shit",ch,NULL,NULL,TO_ROOM);
      send_to_char ("Clan Syntax:\n\r", ch);
      send_to_char ("\tclan list\n\r", ch);
      send_to_char ("\tclan loner\n\r", ch);
      send_to_char ("\tclan wars\n\r", ch);
      if (((ch->clan == CLAN_BOGUS) && !is_any_clan_applicant (ch)))
	{
	  send_to_char
	    ("\tclan establish <clan name> <clan symbol> [pk/nopk]\r\n", ch);
	  send_to_char ("\tclan apply <clan name>\n\r", ch);
	}
      if (is_any_clan_applicant (ch) || (ch->clan != CLAN_BOGUS))
	{
	  send_to_char ("\tclan last\n\r", ch);
	  send_to_char ("\tclan defect\n\r", ch);
	  send_to_char ("\tclan donate\n\r", ch);
	}
      if (is_clan_leader (ch) || is_clan_deputy (ch))
	{
	  send_to_char ("\tclan ally [clan name]\n\r", ch);
	  send_to_char ("\tclan enemy [clan name]\n\r", ch);
	  send_to_char ("\tclan declare <clan name>\n\r", ch);
	  send_to_char ("\tclan prospects\n\r", ch);
	  send_to_char ("\tclan accept <player>\n\r", ch);
	  send_to_char ("\tclan deny <player>\r\n", ch);
	  send_to_char ("\tclan expel <player>\n\r", ch);
	}
      if (is_clan_leader (ch))
	{
	  send_to_char ("\tclan deputy <player>\n\r", ch);
	  send_to_char ("\tclan leader <player>\n\r", ch);
	  send_to_char ("\tclan symbol <symbol>\n\r", ch);
	  send_to_char ("\tclan disband\n\r", ch);
	  send_to_char ("\tclan altar\n\r", ch);
	  send_to_char ("\tclan help [clan name]\n\r", ch);
	}
      send_to_char ("\tclan info <clan name>\n\r", ch);
      send_to_char ("\tclan who <clan name>\n\r", ch);
      return;
    }
  do_clan_dispatch (ch, arg, argument);
}

void do_clan_imm (CHAR_DATA * ch)
{
  send_to_char ("Clan Syntax:\n\r", ch);
  send_to_char ("\tclan list [hidden] | [all]\n\r", ch);
  send_to_char ("\tclan loner\n\r", ch);
  send_to_char ("\tclan wars\n\r", ch);
  send_to_char ("\tclan cancel <war number>\n\r", ch);
  send_to_char ("\tclan establish <clan name> <clan symbol>\r\n", ch);
  send_to_char ("\tclan apply <clan name>\n\r", ch);
  send_to_char ("\tclan last\n\r", ch);
  send_to_char ("\tclan defect\n\r", ch);
  send_to_char ("\tclan donate\n\r", ch);
  send_to_char ("\tclan ally [clan name]\n\r", ch);
  send_to_char ("\tclan enemy [clan name]\n\r", ch);
  send_to_char ("\tclan declare <clan name>\n\r", ch);
  send_to_char ("\tclan prospects <clan name>\n\r", ch);
  send_to_char ("\tclan accept <player> <clan name>\n\r", ch);
  send_to_char ("\tclan deny <player>\r\n", ch);
  send_to_char ("\tclan expel <player> <clan name>\n\r", ch);
  send_to_char ("\tclan deputy <player>\n\r", ch);
  send_to_char ("\tclan leader <player> <clan name>\n\r", ch);
  send_to_char ("\tclan symbol <symbol>\n\r", ch);
  send_to_char ("\tclan disband <clan name>\n\r", ch);
  send_to_char ("\tclan altar <clan name>\n\r", ch);
  send_to_char ("\tclan help [clan name]\n\r", ch);

//   send_to_char("\tclan activate <clan name> [leader]\n\r",ch);
  send_to_char ("\tclan activate <clan name>\n\r", ch);
  send_to_char ("\tclan info <clan name>\n\r", ch);
  send_to_char ("\tclan who <clan name>\n\r", ch);
  send_to_char ("Related Commands:\n\r", ch);
  send_to_char ("\tsanctify <clan name>\n\r", ch);
  send_to_char ("\tdesecrate\n\r", ch);
  return;
}
void do_clan_dispatch (CHAR_DATA * ch, char *arg, char *argument)
{

//       act("clan dispatching on yo AZZ!",ch,NULL,NULL,TO_ROOM);
  if (!str_cmp (arg, "who"))
    {
      clan_who (ch, argument);
      return;
    }
  if (!str_cmp (arg, "list"))
    {
      clan_list (ch, argument);
      return;
    }
  if (!str_cmp (arg, "help"))
    {
      clan_help (ch, argument);
      return;
    }
  if (!str_cmp (arg, "info"))
    {
      clan_info (ch, argument);
      return;
    }
  if (!str_cmp (arg, "wars"))
    {
      clan_wars (ch);
      return;
    }
  if (!str_cmp (arg, "ally"))
    {
      clan_ally (ch, argument);
      return;
    }
  if (!str_cmp (arg, "last"))
    {
      clan_last (ch);
      return;
    }
  if (!str_cmp (arg, "deny"))
    {
      clan_deny (ch, argument);
      return;
    }
  if (!str_cmp (arg, "apply"))
    {
      if (ch->race == PC_RACE_AVATAR && ch->pcdata && 
		      (ch->pcdata->avatar_type != 2 && ch->pcdata->avatar_type != 4))
        {
           send_to_char("Sorry, you're a nopk avatar.  If you wish to loner, reincarnate as a pk avatar.\n\r",ch);
           return;				          
	}
      
      clan_apply (ch, argument);
      return;
    }
  if (!str_cmp (arg, "loner"))
    {
      if (ch->race == PC_RACE_AVATAR && ch->pcdata 
		      && (ch->pcdata->avatar_type != 2 && ch->pcdata->avatar_type != 4))
      {
        send_to_char("Sorry, you're a nopk avatar.  If you wish to loner, reincarnate as a pk avatar.\n\r",ch);
        return;
      }
      clan_loner (ch);
      return;
    }
  if (!str_cmp (arg, "enemy"))
    {
      clan_enemy (ch, argument);
      return;
    }
  if (!str_cmp (arg, "expel"))
    {
      clan_expel (ch, argument);
      return;
    }
  if (!str_cmp (arg, "donate"))
    {
      clan_donate (ch, argument);
      return;
    }
  if (!str_cmp (arg, "symbol"))
    {
      clan_symbol (ch, argument);
      return;
    }
  if (!str_cmp (arg, "accept"))
    {
      clan_accept (ch, argument);
      return;
    }
  if (!str_cmp (arg, "defect"))
    {
      clan_defect (ch);
      return;
    }
  if (!str_cmp (arg, "deputy"))
    {
      clan_deputy (ch, argument);
      return;
    }
  if (!str_cmp (arg, "leader"))
    {
      if (!is_clan_leader (ch) && !IS_IMMORTAL (ch))
        {
          send_to_char ("You are not the leader of your clan.\n\r", ch);
          return;
        }
	    
      if (!IS_NPC (ch))
        if ((time (NULL) - ch->pcdata->last_fight < 120) && (!IS_IMMORTAL(ch)))
        {
          send_to_char ("Hold your horses, punk.\n\r", ch);
          return;
        }
      clan_leader (ch, argument);
      return;
    }
  if (!str_cmp (arg, "declare"))
    {
      clan_declare (ch, argument);
      return;
    }
  if (!str_cmp (arg, "disband"))
    {
      clan_disband (ch, argument);
      return;
    }
  if (!str_cmp (arg, "altar"))
    {
      clan_altar (ch, argument);
      return;
    }
  if (!str_cmp (arg, "activate"))
    {
      clan_activate (ch, argument);
      return;
    }
  if (!str_cmp (arg, "prospects"))
    {
      clan_prospects (ch, argument);
      return;
    }
  if (!str_cmp (arg, "establish"))
    {
      if (ch->race == PC_RACE_AVATAR && ch->pcdata && 
		      (ch->pcdata->avatar_type != 2 && ch->pcdata->avatar_type != 4))
      {
        send_to_char("Sorry, you're a nopk avatar.  If you wish to loner, reincarnate as a pk avatar.\n\r",ch);
        return;
      }
      clan_establish (ch, argument);
      return;
    }
  // if we do not recognize any of the commands generate the message
  do_clan (ch, "");
}


//
// Allow a clan member to remove another clan's claim on an area
//
void do_desecrate (CHAR_DATA * ch, char *argument)
{

#ifdef VERBOSE_CLANS
  char buf[MAX_STRING_LENGTH];

#endif /*  */
  OBJ_DATA *obj;
  CHAR_DATA *lch;
  int area_clan;

#ifdef VERBOSE_CLANS
  log_player_command ("s:do_descecrate", ch, argument);

#endif /*  */

#ifdef VERBOSE_CLANS
  sprintf (buf, "desecrate: %s attempts to descecrate area %s",
	   ch->name, ch->in_room->area->name);
  log_string (buf);

#endif /*  */
  for (obj = ch->in_room->contents; obj; obj = obj->next_content)
    if (obj->pIndexData->vnum == OBJ_VNUM_CLAN_SYMBOL)
      break;
  if (obj == NULL)
    {
      send_to_char
	("No symbols declaring this area held exist here.\n\r", ch);
      return;
    }
  if (IS_IMMORTAL (ch))
    {

#ifdef VERBOSE_CLANS
      log_string ("desecrate: by immortal, bypassing checks");

#endif /*  */
    }

  else
    {

#ifdef VERBOSE_CLANS
      log_string ("desecrate: making sure char has a rune");

#endif /*  */
      if (!has_key (ch, OBJ_VNUM_RUNE_CONV))
	{
	  send_to_char
	    ("The desecration of this clan's domination over this area requires the mystical powers of a Rune.\n\r",
	     ch);
	  return;
	}
      lch = char_list;
      area_clan = ch->in_room->area->clan;

#ifdef VERBOSE_CLANS
      log_string ("desecrate: making sure area is clear");

#endif /*  */
      while (lch)
	{
	  if ((area_clan > CLAN_BOGUS) &&	// area is owned by some clan
	      (lch != ch) &&	// char is not same as me
	      (lch->clan == area_clan) &&	// char clan is same as this area clan
	      (lch->in_room->area == ch->in_room->area))
	    {
	      send_to_char
		("You must drive all clan members from this area before you can free it.\n\r",
		 ch);
	      return;
	    }
	  if (!IS_NPC (lch) || !lch->in_room)
	    {
	      lch = lch->next;
	      continue;
	    }
	  if ((lch->in_room->area == ch->in_room->area)
	      && !IS_SET (lch->in_room->room_flags, ROOM_SAFE)
	      && !IS_SET (lch->act, ACT_TRAIN)
	      && !IS_SET (lch->act, ACT_IS_HEALER)
	      && (lch->pIndexData->pShop == NULL))
	    {
	      send_to_char
		("You must first rid this area of all its creatures.\n\r",
		 ch);
	      return;
	    }
	  lch = lch->next;
	}			// end while loop   
    }				// end immortal test
  act
    ("$n traces arcane symbols in the air, desecrating the area in the name of $s clan.",
     ch, NULL, NULL, TO_ROOM);
  send_to_char
    ("You trace arcane symbols in the air, desecrating the area in the name of your clan.\n\r",
     ch);

  // this removes the object that contains the clan symbol from the area.
#ifdef VERBOSE_CLANS
  log_string ("desecrate: removing the symbol and resets");

#endif /*  */
  remove_symbol_resets (ch->in_room->area);
  extract_obj (obj);

  // only take runes from mortal chars
  if (!IS_IMMORTAL (ch))
    {

#ifdef VERBOSE_CLANS
      log_string ("desecrate: taking the rune from the char");

#endif /*  */
      for (obj = ch->carrying; obj != NULL; obj = obj->next_content)
	{
	  if (obj->pIndexData->vnum == OBJ_VNUM_RUNE_CONV)
	    {
	      extract_obj (obj);
	      break;
	    }
	}
    }
  // remove the clan number
  ch->in_room->area->clan = CLAN_BOGUS;
  save_area (ch->in_room->area);

#ifdef VERBOSE_CLANS
  log_player_command ("f:do_descecrate", ch, argument);

#endif /*  */
}


//
// Allow a clan member to claim an area for that clan
//
void do_sanctify (CHAR_DATA * ch, char *argument)
{
  char clanstr[MAX_STRING_LENGTH];

#ifdef VERBOSE_CLANS
  char buf[MAX_STRING_LENGTH];

#endif /*  */
  OBJ_INDEX_DATA *pObjIndex;
  OBJ_DATA *obj;
  CHAR_DATA *lch;
  RESET_DATA *pReset;
  int slot;
  int area_clan;

#ifdef VERBOSE_CLANS
  log_player_command ("s:do_sanctify", ch, argument);

#endif /*  */

#ifdef VERBOSE_CLANS
  sprintf (buf, "sanctify: %s attempts to sanctify area %s",
	   ch->name, ch->in_room->area->name);
  log_string (buf);

#endif /*  */
  if (ch->in_room->area->noclan)
    {
      send_to_char
	("You may not declare dominion over this area, for it is under the conservancy of the gods.\n\r",
	 ch);
      return;
    }
  if (IS_IMMORTAL (ch))
    {
      argument = one_argument (argument, clanstr);

      // the immortal eiter must be in the clan or supply a clan name
      if (clanstr[0] == '\0')
	{
	  slot = ch->clan;
	}

      else
	{
	  slot = clanname_to_slot (clanstr);
	}

      // validate the slot
      if (slot == CLAN_BOGUS)
	{
	  send_to_char
	    ("You must be in a clan or name a valid clan.\n\r", ch);
	  return;
	}
      // don't set two symbols in this area
      area_clan = clanident_to_slot (ch->in_room->area->clan);
      if (area_clan != CLAN_BOGUS)
	{
	  send_to_char
	    ("This area is already under another clan's dominion.\n\r", ch);
	  return;
	}
#ifdef VERBOSE_CLANS
      log_string ("Sanctify: by immortal, bypassing remaining checks");

#endif /*  */
    }

  else
    {
      slot = (ch->clan);
      if ((slot == CLAN_BOGUS) || (clan_table[slot].status < CLAN_PROPOSED))
	{
	  send_to_char ("You do not belong to a clan.\n\r", ch);
	  return;
	}
      if (!has_key (ch, OBJ_VNUM_RUNE_CONV))
	{
	  send_to_char
	    ("The assertion of your clan's dominance over this area requires the mystical energies of a Rune.\n\r",
	     ch);
	  return;
	}
      area_clan = clanident_to_slot (ch->in_room->area->clan);
      if (area_clan != CLAN_BOGUS)
	{
	  send_to_char
	    ("This area is already under another clan's dominion.\n\r", ch);
	  return;
	}
#ifdef VERBOSE_CLANS
      log_string ("Sanctify: checking that area is empty.");

#endif /*  */
      for (lch = char_list; lch; lch = lch->next)
	{
	  if (lch == NULL)
	    {
	      log_string ("Sanctify: char_list null?");
	      return;
	    }
	  if (!IS_NPC (lch) || !lch->in_room)
	    continue;
	  if ((lch->in_room->area == ch->in_room->area) &&
	      (!IS_SET (lch->in_room->room_flags, ROOM_SAFE)) &&
	      (!IS_SET (lch->in_room->room_flags, ROOM_TRANSPORT)) &&
	      (!IS_SET (lch->act, ACT_TRAIN)) &&
	      (!IS_SET (lch->act, ACT_IS_CHANGER)) &&
	      (!IS_SET (lch->in_room->room_flags, ROOM_BANK)) &&
	      (!IS_SET (lch->act, ACT_IS_HEALER)) &&
	      (lch->pIndexData->pShop == NULL))
	    {
	      send_to_char
		("You must first rid this area of all its creatures.\n\r",
		 ch);
	      return;
	    }
	}			// end for loop
    }				// end immortal test
  if ((pObjIndex = get_obj_index (OBJ_VNUM_CLAN_SYMBOL)) == NULL)
    {
      bug ("Sanctify: no clan symbol object - %d", OBJ_VNUM_CLAN_SYMBOL);
      return;
    }
#ifdef VERBOSE_CLANS
  log_string ("Sanctify: setting area clan slot");

#endif /*  */
  ch->in_room->area->clan = slot;
  obj = create_object (pObjIndex, 0);
  obj_to_room (obj, ch->in_room);

  // this object is the symbol that shows up when a player goes
  // into a clan marked area. This symbol stays in the room until
  // the room is desecrated by another clan. The area is saved later.
  pReset = new_reset_data ();
  pReset->command = 'O';
  pReset->arg1 = OBJ_VNUM_CLAN_SYMBOL;
  pReset->arg2 = 0;
  pReset->arg3 = ch->in_room->vnum;
  pReset->arg4 = -1;

#ifdef VERBOSE_CLANS
  log_string ("Sanctify: adding symbol object and reset to area");

#endif /*  */
  add_reset (ch->in_room, pReset, 0);
  act
    ("$n chants unintelligible words, sanctifying the area in the name of $s clan.",
     ch, NULL, NULL, TO_ROOM);
  send_to_char
    ("You chant unintelligible words, sanctifying the area in the name of your clan.\n\r",
     ch);

  // take the rune from mortal players only
  if (!IS_IMMORTAL (ch))
    {

#ifdef VERBOSE_CLANS
      log_string ("Sanctify: taking rune from character");

#endif /*  */
      for (obj = ch->carrying; obj != NULL; obj = obj->next_content)
	{
	  if (obj->pIndexData->vnum == OBJ_VNUM_RUNE_CONV)
	    {
	      extract_obj (obj);
	      break;
	    }
	}
    }
  // don't really save until we have the rune
  save_area (ch->in_room->area);

  // let them know it is finished
  send_to_char
    ("You have declared ascendancy over this area for your clan.\n\r", ch);
  act ("$n has declared ascendancy over this area for $s clan.", ch,
       NULL, NULL, TO_ROOM);

#ifdef VERBOSE_CLANS
  log_player_command ("f:do_sanctify", ch, argument);

#endif /*  */
}


//
// Send a message on a clan war channel
//
void do_clanwar (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_STRING_LENGTH];
  int slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:do_clanwar", ch, argument);

#endif /*  */

  // ok, make sure they are in a clan
  slot = (ch->clan);
  if (slot == CLAN_BOGUS)
    {
      send_to_char ("You are not in a clan.\n\r", ch);
      return;
    }
  // make sure that they are in a mortal visible clan
  if (clan_table[slot].status < CLAN_PROPOSED)
    {
      send_to_char ("You are not in a clan.\n\r", ch);
      return;
    }
  // their clan better be an active clan
  if (clan_table[slot].status < CLAN_ACTIVE)
    {
      send_to_char ("Your clan is not a full clan.\n\r", ch);
      return;
    }
  // what is the text
  if (argument[0] == '\0')
    {
      send_to_char ("What would you like to say to your allies?\n\r", ch);
      return;
    }

  // they better have allies
  if (!clan_has_allies (slot))
    {
      send_to_char ("But, your clan has no allies.\n\r", ch);
      return;
    }
  if (IS_SET (ch->comm, COMM_NOCHANNELS))
    {
      send_to_char ("The gods have revoked your channel privileges.\n\r", ch);
      return;
    }
  if (IS_SET (ch->comm2, COMM_RANTONLY))
  {
	  send_to_char("The gods have decreed you may only use the Rant Channel.\n\r", ch);
	  return;
  }
  if (ch->class == PC_CLASS_CHAOS_JESTER && !IS_IMMORTAL(ch))
	  cj_self(ch,argument);
  else
  {
    sprintf (buf, "[CLANWAR] %s `OYou`a: '`O%s`a'``\n\r",get_clan_symbol(ch->clan), argument);
    send_to_char (buf, ch);
  }

  send_allies_clanwar (ch, argument);

#ifdef VERBOSE_CLANS
  log_player_command ("f:do_clanwar", ch, argument);

#endif /*  */
}


//
// checks the status of any outstanding clan wars and
// if they have gone on long enough declares a winner.
//
void update_wars ()
{
  RELATIONS *us;
  RELATIONS *them;
  char us_buf[MAX_STRING_LENGTH];
  char tm_buf[MAX_STRING_LENGTH];
  time_t now;
  int slot, ident;
  int enemy_slot;
  bool waswar = FALSE;
  bool warring = FALSE;

#ifdef VERBOSE_CLANS
  log_string ("s:update_wars");

#endif /*  */
  now = time (NULL);

  // check to see if *any* clan war has ended
  for (slot = CLANS_START; slot < clan_number; slot++)
    {
      if (clan_table[slot].status < CLAN_ACTIVE)
	continue;
      us = clan_table[slot].relations;
      ident = clan_table[slot].ident;
      while (us)
	{

	  // if the war has lasted long enough then we need to declare a winner
	  if ((us->status >= CLAN_WAR) &&
	      ((now - (us->wartime)) >= CLAN_WAR_TIME))
	    {

	      // do not be fooled (us->ident) is really *their* identifier
	      enemy_slot = clanident_to_slot (us->ident);

	      // there was a war on when we started this routine
	      waswar = TRUE;

	      // if this clan/clanwar is one we have not yet processed
	      if (enemy_slot > slot)
		{

		  // look up their relationship with us
		  them =
		    find_relation (clan_table[enemy_slot].relations, ident);

		  // now declare a winner
		  if ((us->points) > (them->points))
		    {

		      // we *win* - they lost
		      if (us->status == CLAN_WAR_AGGR)
			{

			  // we were the agressor
			  sprintf (us_buf,
				   "Your clans aggressive diplomacy proved useful.\n\rYour clan wins the war as clan %s`` sues for peace.\n\r",
				   clan_table[enemy_slot].name);
			  sprintf (tm_buf,
				   "Alas, your clan has been beaten by the aggressive clan %s``.\n\rYour clan sues for peace.\n\r",
				   clan_table[slot].name);
			}

		      else
			{

			  // they were the agressor
			  sprintf (us_buf,
				   "Your clan proved victorious.\n\rClan %s`` sues for peace with your clan.\n\r",
				   clan_table[enemy_slot].name);
			  sprintf (tm_buf,
				   "Your clan's aggressive diplomacy proved disastrous.\n\rYour clan sues for peace with clan %s``.\n\r",
				   clan_table[slot].name);
			}

		      // give credit
		      // DO NOT reset kills or points
		      // they are needed by has_defeated_clan() function
		      (us->wins)++;
		      (them->loss)++;

		      // mark the end time of the war
		      us->wartime = now;
		      them->wartime = now;

		      // set them up as enemies
		      us->status = CLAN_ENEMY;
		      them->status = CLAN_ENEMY;
		      us->acttime = now;
		      them->acttime = now;
		    }

		  else if ((us->points) < (them->points))
		    {

		      // we *lost* - they win
		      if (us->status == CLAN_WAR_AGGR)
			{

			  // we were the agressor
			  sprintf (us_buf,
				   "Your clans aggressive diplomacy proved disastrous.\n\rYour clan sues for peace with clan %s``.\n\r",
				   clan_table[enemy_slot].name);
			  sprintf (tm_buf,
				   "Your clan proved victorious.\n\rClan %s`` sues for peace with your clan.\n\r",
				   clan_table[slot].name);
			}

		      else
			{

			  // they were the agressor
			  sprintf (us_buf,
				   "Alas, your clan has been beaten by the aggressive clan %s.``\n\rYour clan sues for peace.\n\r",
				   clan_table[enemy_slot].name);
			  sprintf (tm_buf,
				   "Your clans aggressive diplomacy proved useful.\n\rYour clan wins the war as clan %s`` sues for peace.\n\r",
				   clan_table[slot].name);
			}

		      // give credit
		      // DO NOT reset kills or points
		      // they are needed by has_defeated_clan() function
		      (us->loss)++;
		      (them->wins)++;

		      // mark the end time of the war
		      us->wartime = now;
		      them->wartime = now;

		      // set them up as enemies
		      us->status = CLAN_ENEMY;
		      them->status = CLAN_ENEMY;
		      us->acttime = now;
		      them->acttime = now;
		    }

		  else
		    {

		      // the fight was a stalemate
		      sprintf (us_buf,
			       "A tense armistice ensues between your clan and clan %s``.\n\r",
			       clan_table[enemy_slot].name);

		      // the fight was a stalemate
		      sprintf (tm_buf,
			       "A tense armistice ensues between your clan and clan %s``.\n\r",
			       clan_table[slot].name);

		      // mark the end time of the war
		      us->wartime = now;
		      them->wartime = now;

		      // set them up as enemies
		      us->status = CLAN_ENEMY;
		      them->status = CLAN_ENEMY;

		      // they can go to war very quickly, only 3/4 of the normal time
		      us->acttime =
			now - (CLAN_ENEMY_TIME - (CLAN_ENEMY_TIME / 4));
		      them->acttime =
			now - (CLAN_ENEMY_TIME - (CLAN_ENEMY_TIME / 4));
		    }

		  // save us and them
		  save_clan (slot);
		  save_clan (enemy_slot);

		  // notify the appropriate clans
		  send_clan_members (slot, us_buf);
		  send_clan_members (enemy_slot, tm_buf);
		}		// enemy_slot > slot
	    }			// end clan war test
	  us = us->next;
	}			// end the while( us )
    }

  // if there was a war and there are no more wars
  // declare a type of peace across the lands
  if (waswar)
    {
      slot = CLANS_START;
      while ((slot < clan_number) && !warring)
	{
	  warring = clan_is_warring (slot);
	  slot++;
	}
      if (!warring)
	{
	  send_all_players (NULL,
			    "\n\rA peace spreads across the realms...\n\r\n\r");
	}
    }
#ifdef VERBOSE_CLANS
  log_string ("f:update_wars");

#endif /*  */
}


//
// Allow a player with a rune, who defeats a clan leader to dispers a clan
//
void do_disperse (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_INPUT_LENGTH];
  char item[MAX_INPUT_LENGTH];
  int clan;
  int vclan;
  OBJ_DATA *obj;
  MEMBER *m;
  CHAR_DATA *c;

#ifdef VERBOSE_CLANS
  log_player_command ("s:do_disperse", ch, argument);

#endif /*  */
  clan = clanname_to_slot (argument);
  if (clan == CLAN_BOGUS)
    {
      sprintf (buf, "There is no clan named %s``.\n\r",
	       capitalize (argument));
      send_to_char (buf, ch);
      return;
    }
  if (!has_key (ch, OBJ_VNUM_RUNE_CONV))
    {
      send_to_char
	("The mystical energies of a Rune are required for this.\n\r", ch);
      return;
    }
  vclan = ch->clan;
  if (vclan == CLAN_BOGUS)
    {
      send_to_char
	("You must be in a clan to disperse another clan.\n\r", ch);
      return;
    }
  if (!is_clan_leader (ch) && !IS_IMMORTAL (ch))
    {
      send_to_char ("You must be a clan leader to disperse.\n\r", ch);
      return;
    }
  // they can not still be at war
  if (is_warring (vclan, clan))
    {
      sprintf (buf, "Your clan is still at war with clan %s``.\n\r",
	       clan_table[clan].name);
      send_to_char (buf, ch);
      send_to_char ("And the tides of war can change quickly.\n\r", ch);
      return;
    }
  // the clan of the person doing the disperse must be victorious
  // over the clan being dispersed
  if (!has_defeated_clan (get_clan_ident (vclan), get_clan_ident (clan)))
    {
      sprintf (buf, "Your clan has not recently defeated clan %s``.\n\r",
	       clan_table[clan].name);
      send_to_char (buf, ch);
      return;
    }
  // the person must be standing over the dead corpse of the
  // other clans clan leader
  sprintf (item, "corpse of %s", clan_table[clan].leader->name);

#ifdef VERBOSE_CLANS
  sprintf (buf, "do_disperse: need item - \"%s\"", item);
  log_string (buf);

#endif /*  */
  obj = ch->in_room->contents;
  while (obj != NULL)
    {

#ifdef VERBOSE_CLANS
      sprintf (buf, "do_disperse: room item - \"%s\"", obj->name);
      log_string (buf);

#endif /*  */
      if (is_name (item, obj->name))
	break;
      obj = obj->next_content;
    }
  if (obj == NULL)
    {
      send_to_char ("You need the corpse of the clan leader.\n\r", ch);
      return;
    }
  // take the rune from the character
  for (obj = ch->carrying; obj != NULL; obj = obj->next_content)
    {
      if (obj->pIndexData->vnum == OBJ_VNUM_RUNE_CONV)
	{
	  extract_obj (obj);
	  break;
	}
    }
  sprintf (buf,
	   "You call upon the power of the Rune to disperse clan %s``.\n\r",
	   clan_table[clan].name);
  send_to_char (buf, ch);
  sprintf (buf,
	   "$n calls upon the power of the Rune to disperse clan %s``.",
	   clan_table[clan].name);
  act (buf, ch, NULL, NULL, TO_ROOM);

  // update the clans status... now it's dispersed
  clan_table[clan].status = CLAN_DISPERSED;

  // remove every other clan's relations with us
  remove_clan_relations (clan_table[clan].ident);

  // for now a disperse does not remove any clan symbols
  // remove_clan_symbols();
  save_clan (clan);

  // notify the membership that they were dispersed
  sprintf (buf, "Your clan has been dispersed by %s.\n\r", ch->name);
  send_clan_members (clan, buf);

  // update the members to think they are not in the clan
  m = clan_table[clan].members;
  while (m)
    {
      c = find_character (m->name);
      if (c)
	c->clan = CLAN_BOGUS;
      m = m->next;
    }

#ifdef VERBOSE_CLANS
  log_player_command ("f:do_disperse", ch, argument);

#endif /*  */
}


//
// this use to rebuild the clan table, not the same now
//
void do_reclan (CHAR_DATA * ch, char *argument)
{
  send_to_char ("reclan is not necessary in the new_clan model.\n\r", ch);
}

// ==============================================================
//
//   Private Functions implement Clans
//
// ==============================================================

//
// List off who is in the clan
//
void clan_who (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_STRING_LENGTH];
  char arg[MAX_STRING_LENGTH];
  MEMBER *m;
  int slot = 0;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_who", ch, argument);

#endif /*  */
  argument = one_argument (argument, arg);

  // trap for an empty clan
  if (arg[0] == '\0')
    {
      send_to_char ("Syntax: clan who <clan name>\n\r", ch);
      return;
    }
  // look up the clan by the clan name
  slot = clanname_to_slot (arg);
  if (slot == CLAN_BOGUS)
    {
      sprintf (buf, "There is no clan named %s``.\n\r", capitalize (arg));
      send_to_char (buf, ch);
      return;
    }
  // check that the clan is a visible status
  if ((clan_table[slot].status < CLAN_PROPOSED) && !IS_IMMORTAL (ch))
    {
      sprintf (buf, "There is no clan named %s``.\n\r", capitalize (arg));
      send_to_char (buf, ch);
      return;
    }
  // for immortals list the real clan status
  if (IS_IMMORTAL (ch))
    clan_short_status (ch, arg);

  // list off the members, list the leader first
  send_to_char ("Clan Members:\n\r", ch);
  sprintf (buf, "\t%-12s (Leader)\n\r", clan_table[slot].leader->name);
  send_to_char (buf, ch);
  m = clan_table[slot].members;
  while (m)
    {
      if (m != clan_table[slot].leader)
	{
	  if (m->status >= CLAN_DEPUTY)
	    {
	      sprintf (buf, "\t%-12s (Deputy)\n\r", m->name);
	    }

	  else
	    {
	      sprintf (buf, "\t%-12s\n\r", m->name);
	    }
	  send_to_char (buf, ch);
	}
      m = m->next;
    }

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_who", ch, argument);

#endif /*  */
}


//
// List all the current and proposed clans
//
void clan_list (CHAR_DATA * ch, char *argument)
{
  int i = 0;
  bool found = FALSE;
  char buf[MAX_INPUT_LENGTH];

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_list", ch, argument);

#endif /*  */
  if (IS_IMMORTAL (ch) && (argument[0] != '\0'))
    {
      clan_list_imm (ch, argument);
      return;
    }
  // set up the table
  if (CLANS_START < clan_number)
    {
      if (IS_IMMORTAL (ch))
	{
	  sprintf (buf,
		   "Name         Symbol       Leader       PK/NonPK    Status       Levels Slot\n\r");
	}

      else
	{
	  sprintf (buf,
		   "Name         Symbol       Leader       PK/NonPK    Status\n\r");
	}
      send_to_char (buf, ch);
    }

  else
    {
      send_to_char ("None.\n\r", ch);
      return;
    }
  for (i = HIDDEN_STATUSES; i < CLAN_STATUSES; i++)
    {
      if (clan_list_status (ch, clan_statuses[i]))
	found = TRUE;
    }
  if (!found)
    send_to_char ("None.\n\r", ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_list", ch, argument);

#endif /*  */
}


//
// Edit the clan help message
//
void clan_help (CHAR_DATA * ch, char *argument)
{
  int slot = 0;
  char name[MAX_INPUT_LENGTH];
  char buf[MAX_INPUT_LENGTH];

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_help", ch, argument);

#endif /*  */
  argument = one_argument (argument, name);
  if (IS_IMMORTAL (ch))
    {
      if (name[0] == '\0')
	{
	  send_to_char ("Please be more specific, which clan?\n\r", ch);
	  return;
	}
      slot = clanname_to_slot (name);
      if (slot == CLAN_BOGUS)
	{
	  sprintf (buf, "There is no clan named %s``.\n\r",
		   capitalize (name));
	  send_to_char (buf, ch);
	  return;
	}
      // check that the clan is a visible status
      if (clan_table[slot].status < CLAN_PROPOSED)
	{
	  sprintf (buf, "Clan %s is currently in an inactive state.\n\r",
		   capitalize (name));
	  send_to_char (buf, ch);
	  return;
	}
    }

  else
    {
      slot = ch->clan;
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("You are not currently a clan member.\n\r", ch);
	  return;
	}
      // check that the clan is a visible status
      if (clan_table[slot].status < CLAN_PROPOSED)
	{
	  send_to_char ("No such clan exists.\n\r", ch);
	  return;
	}
      if (!is_clan_leader (ch))
	{
	  send_to_char ("You do not lead your clan.\n\r", ch);
	  return;
	}
    }

  // if they make it this far, then they get to edit the clan help
  // reset the help name
  if (ch->desc->help_name != NULL)
    free_string (ch->desc->help_name);
  ch->desc->help_name = str_dup (clan_table[slot].name);

  // reset the help description
  if (ch->desc->help_info != NULL)
    free_string (ch->desc->help_info);
  ch->desc->help_info =
    read_current_help (clan_table[slot].name, "clans.hlp");

  // now allow them to edit
  send_to_char
    ("Please use the Exodus Editor to enter your clan's help information.\n\r\n\r",
     ch);
  ch->desc->editor = SAVE_CLAN_HELP;
  edit_string (ch, &ch->desc->help_info);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_help", ch, argument);

#endif /*  */
}


//
// Allow a player to mark himself a loner
//
void clan_loner (CHAR_DATA * ch)
{
  char buf[MAX_STRING_LENGTH];
  int slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_loner", ch, ((char *) NULL));

#endif /*  */

  // Check for level requirement added by Morgan on June 29. 2000
  if (ch->level < 9)
    {
      send_to_char ("You are too young to become a loner.\n\r", ch);
      return;
    }
  slot = (ch->clan);

  // if their clan is not a bogus clan then they are in one already
  if ((slot != CLAN_BOGUS) && (clan_table[slot].status >= CLAN_PROPOSED))
    {
      sprintf (buf,
	       "You are already in clan %s``, you may become a loner by defecting.\n\r",
	       clan_table[slot].name);
      send_to_char (buf, ch);
      return;
    }
  // if they are an applicant, then they are almost in the clan
  if (is_clan_applicant (ch, slot)
      && (clan_table[slot].status >= CLAN_PROPOSED))
    {
      sprintf (buf,
	       "You have already applied to clan %s``, you must defect in order to become a loner.\n\r",
	       clan_table[slot].name);
      send_to_char (buf, ch);
      return;
    }
  if (ch->pcdata->loner == TRUE)
    {
      send_to_char ("You have already been marked as a loner.\n\r", ch);
      ch->clan = CLAN_BOGUS;
      ch->pcdata->deputy = FALSE;
      return;
    }
  send_to_char ("You are now marked as a loner.\n\r", ch);
  ch->pcdata->loner = TRUE;
  ch->pcdata->deputy = FALSE;
  ch->clan = CLAN_BOGUS;

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_loner", ch, ((char *) NULL));

#endif /*  */
}

//
// Allow a player to apply for clan membership
//
void clan_apply (CHAR_DATA * ch, char *argument)
{
  CHAR_DATA *leader;
  char arg[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  int slot, oldslot;
  MEMBER *m;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_apply", ch, argument);

#endif /*  */
  argument = one_argument (argument, arg);

  // do they have the right syntax
  if (arg[0] == '\0')
    {
      send_to_char ("Apply to which clan?\n\r", ch);
      return;
    }
  // Check for level requirement added by Morgan on June 29. 2000
  if (ch->level < 9)
    {
      send_to_char ("You are too young to apply to a clan.\n\r", ch);
      return;
    }
  // did they give a valid clan name
  slot = clanname_to_slot (arg);
  if (slot == CLAN_BOGUS)
    {
      sprintf (buf, "There is no clan named %s``.\n\r", capitalize (arg));
      send_to_char (buf, ch);
      return;
    }
  // check that the clan is a visible status
  if (clan_table[slot].status < CLAN_PROPOSED)
    {
      sprintf (buf, "There is no clan named %s``.\n\r", capitalize (arg));
      send_to_char (buf, ch);
      return;
    }
  // check that the clan is a visible status
  if (ch->level < MIN_MEMBER_LEVEL)
    {
      sprintf (buf, "You must be at least level %d to join a clan.\n\r",
	       MIN_MEMBER_LEVEL);
      send_to_char (buf, ch);
      return;
    }
  if (ch->pcdata->loner && clan_table[slot].ctype == CLAN_TYPE_EXPL)
    {
      send_to_char ("Loners can't join nopk clans.\n\r", ch);
      return;
    }
  // are they already in a clan
  oldslot = (ch->clan);
  if ((oldslot != CLAN_BOGUS)
      && (clan_table[oldslot].status >= CLAN_PROPOSED))
    {
      sprintf (buf,
	       "You are already in clan %s``, you must defect in order to apply.\n\r",
	       clan_table[oldslot].name);
      send_to_char (buf, ch);
      return;
    }
  // check that they are not applying to another clan too
  oldslot = is_any_clan_applicant (ch);
  if ((oldslot != CLAN_BOGUS)
      && (clan_table[oldslot].status >= CLAN_PROPOSED))
    {
      sprintf (buf,
	       "You applied to clan %s``, you must defect to apply to another clan.\n\r",
	       clan_table[oldslot].name);
      send_to_char (buf, ch);
      return;
    }
  // a just in case fix of the player record
  ch->clan = CLAN_BOGUS;
  ch->pcdata->deputy = FALSE;
  save_char_obj (ch);

  // allocated their entry into the applicant list
  m = new_member_elt ();
  strcpy ((m->name), (ch->name));
  m->status = CLAN_APPLIED;
  m->levels = ch->level;
  m->align = ch->alignment;
  m->race = ch->race;
  m->class = ch->class;
  m->initiative = CLAN_BOGUS;
  clan_table[slot].applicants =
    append_member (clan_table[slot].applicants, m);

  // now save the clan
  save_clan (slot);

  // notify player
  sprintf (buf, "You have applied for membership to clan %s``.\n\r",
	   clan_table[slot].name);
  send_to_char (buf, ch);

  // attempt notify the leader
  leader = find_character (clan_table[slot].leader->name);
  if (leader != NULL)
    {
      sprintf (buf, "%s has applied for membership into clan %s``.\n\r",
	       ch->name, clan_table[slot].name);
      send_to_char (buf, leader);
    }

  else
    {

      // This is where we should notify the leader by a note
    }

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_apply", ch, argument);

#endif /*  */
}


//
//  Allow a PC to remove themselves from a clan
//
void clan_defect (CHAR_DATA * ch)
{
  char buf[MAX_STRING_LENGTH];
  MEMBER *m;
  bool fixup = FALSE;
  int slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_defect", ch, ((char *) NULL));

#endif /*  */

  // can't defect while fighting
  if (ch->position == POS_FIGHTING)
    {
      send_to_char ("No way! You are fighting.\n\r", ch);
      return;
    }
  // check the amount of fight lag
  if ((time (NULL) - ch->pcdata->last_fight) < FIGHT_LAG)
    {
      send_to_char ("Nice try.  You can't defect so easily.\n\r", ch);
      return;
    }
  /*if (ch->clan != CLAN_BOGUS)
  {
    if ((clan_table[ch->clan].relations)->status >= CLAN_WAR)
    {
      send_to_char ("You may not defect during a war.  That is LAME.\n\r",ch);
      return;
    }
  }*/
  
  // can't defect if they are the clan leader
  if (is_clan_leader (ch))
    {
      send_to_char
	("Clan leaders may not defect, you must disband your clan.\n\r", ch);
      return;
    }
  // save the clan slot number
  slot = (ch->clan);

  // send the PC a message if they were in a bogus clan
  if (slot == CLAN_BOGUS)
    {
      slot = is_any_clan_applicant (ch);
      if (slot == CLAN_BOGUS)
	{
	  send_to_char
	    ("You are not currently in or applying to any clan.\n\r", ch);
	  return;
	}
    }
  // set the PC clan flags as appropriate and save them
  ch->clan = CLAN_BOGUS;
  ch->pcdata->deputy = FALSE;
  save_char_obj (ch);

  // send the PC a message if they were in a defunct clan
  if (clan_table[slot].status < CLAN_PROPOSED)
    {
      fixup = TRUE;
      send_to_char
	("You are not currently in or applying to any clan.\n\r", ch);

      // do not return in this case, because what we really want to do is remove
      // them from that clans membership list just below.
      //return;
    }
  // find the member record and remove it from the linked list
  m = find_member (clan_table[slot].members, ch->name);
  if (m == NULL)
    {
      m = find_member (clan_table[slot].applicants, ch->name);
      if (m == NULL)
	{
	  if (!fixup)
	    send_to_char
	      ("You are not currently in or applying to any clan.\n\r", ch);
	  return;
	}

      else
	{
	  clan_table[slot].applicants =
	    delete_member (clan_table[slot].applicants, ch->name);
	  if (!fixup)
	    {
	      sprintf (buf,
		       "You withdraw your application to clan %s``.\n\r",
		       clan_table[slot].name);
	      send_to_char (buf, ch);
	    }
	  save_clan (slot);

#ifdef VERBOSE_CLANS
	  log_player_command ("f:clan_defect", ch, "*just an applicant*");

#endif /*  */
	  return;
	}
    }

  else
    {
      clan_table[slot].members =
	delete_member (clan_table[slot].members, ch->name);
    }
  if (fixup)
    {

#ifdef VERBOSE_CLANS
      log_player_command ("f:clan_defect", ch, "*fixup defunct clan*");

#endif /*  */
      return;
    }
  // Now notify the membership that the player has defected
  sprintf (buf, "%s has defected from clan %s``.\n\r", ch->name,
	   clan_table[slot].name);
  send_clan_members (slot, buf);

  // m is not null, that means we found the player
  // this clan now loses all the levels of the PC, effective as of the
  // time they joined the clan. This clan may now have a status change
  clan_table[slot].levels -= m->levels;
  if ((clan_table[slot].levels < FULL_CLAN_LEVELS))
    {

      // if this clan has lost too many levels then we restrict 
      // it like a proposed clan
      clan_table[slot].status = CLAN_RESTRICTED;
      sprintf (buf,
	       "Clan %s`` has lost too many members and is now restricted.\n\r",
	       clan_table[slot].name);
      send_clan_members (slot, buf);
    }
  save_clan (slot);

  // notify the player of the action
  sprintf (buf, "You defect from clan %s``.\n\r", clan_table[slot].name);
  send_to_char (buf, ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_defect", ch, ((char *) NULL));

#endif /*  */
}

//
//  Allow a clan leader to ally this clan with another clan
//
void clan_ally (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_STRING_LENGTH];
  char wbuf[MAX_STRING_LENGTH];
  RELATIONS *ally = NULL;
  int slot, allies, levels;
  int ally_slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_ally", ch, argument);

#endif /*  */

  // validate clan identifier
  slot = (ch->clan);
  if (slot == CLAN_BOGUS)
    {
      send_to_char ("You are not in a clan.\n\r", ch);
      return;
    }
  // check that their clan is not dispersed or disbanded
  if (clan_table[slot].status < CLAN_PROPOSED)
    {
      send_to_char ("You are not in a clan.\n\r", ch);
      return;
    }
  // check clan leadership
  if (!is_clan_leader (ch) && !is_clan_deputy (ch) && !IS_IMMORTAL (ch))
    {
      send_to_char ("You do not lead your clan.\n\r", ch);
      return;
    }
  // check that their clan is not restricted
  if (clan_table[slot].status < CLAN_ACTIVE)
    {
      send_to_char ("Your clan is not currently a full clan.\n\r", ch);
      return;
    }
  // if they gave us no argument then list off the allies of this clan
  if (argument[0] == '\0')
    {
      list_allies (ch, slot);
      return;
    }
  // lookup this clan name
  ally_slot = clanname_to_slot (argument);
  if (ally_slot == CLAN_BOGUS)
    {
      sprintf (buf, "There is no clan named %s``.\n\r",
	       capitalize (argument));
      send_to_char (buf, ch);
      return;
    }
  // validate that it is a mortal visible clan
  if (clan_table[ally_slot].status < CLAN_PROPOSED)
    {
      sprintf (buf, "There is no clan named %s``.\n\r",
	       capitalize (argument));
      send_to_char (buf, ch);
      return;
    }
  // do not let them do something dumb
  if (ally_slot == slot)
    {
      send_to_char ("You can not mark your own clan as an ally.\n\r", ch);
      return;
    }
  // check that this clan is active
  if (clan_table[ally_slot].status < CLAN_ACTIVE)
    {
      send_to_char
	("You may not make allies of proposed or restricted clans.\n\r", ch);
      return;
    }
  // first if they are an ally then this works as a toggle and unsets
  // the ally flag. First find the record of the relations between
  // the players clan and the proposed ally clan.
  ally =
    find_relation (clan_table[slot].relations, clan_table[ally_slot].ident);

  // if there is no ally entry then we are neutral to them
  // allocate a relation record and set it to neutral, fix up below
  if (ally == NULL)
    {
      ally = new_relations_elt ();
      strcpy ((ally->name), clan_table[ally_slot].name);
      ally->ident = clan_table[ally_slot].ident;
      ally->status = CLAN_NEUTRAL;

      // add them to the relations list
      clan_table[slot].relations =
	append_relation (clan_table[slot].relations, ally);
    }
  // ok, only worry about the issue that they are trying to add a new ally
  if (ally->status != CLAN_ALLY)
    {

      // make sure that this clan does not exceed a hard value
      allies = count_clan_allies (slot);
      if (allies >= CLAN_ALLIES_MAX)
	{
	  send_to_char
	    ("Your clan cannot manage any more alliances.\n\r", ch);
	  return;
	}
      // validate that this clan has enough levels to add an ally,
      // every clan will be able to have at least one ally
      levels = clan_levels (slot);
      if (levels < (allies * LEVELS_PER_ALLY))
	{
	  send_to_char
	    ("Your clan is not powerful enough to add another ally.\n\r", ch);
	  return;
	}
    }
  // now given the current ally status shift to another status
  switch ((ally->status))
    {
    case CLAN_ALLY:
      ally->status = CLAN_NEUTRAL;
      ally->acttime = time (NULL);
      save_clan (slot);
      break;
    case CLAN_NEUTRAL:
      ally->status = CLAN_ALLY;
      ally->acttime = time (NULL);
      save_clan (slot);
      break;
    case CLAN_ENEMY:
      sprintf (buf,
	       "Clan %s`` can not be marked both an ally and an enemy.\n\r",
	       clan_table[ally_slot].name);
      send_to_char (buf, ch);
      return;
      break;
    case CLAN_WAR:
    case CLAN_WAR_AGGR:
    case CLAN_WAR_VICT:
      sprintf (buf, "But you are currently at war with %s``!\n\r",
	       clan_table[ally_slot].name);
      send_to_char (buf, ch);
      return;
      break;
    default:
      ally->status = CLAN_ALLY;
      ally->acttime = time (NULL);
      sprintf (buf,
	       "clan_ally() unrecognized clan status '%d' - clan '%s' tried to ally clan '%s'",
	       (ally->status), clan_table[slot].name,
	       clan_table[ally_slot].name);
      bug (buf, 0);
      save_clan (slot);
      break;
    }

  // set up a string for message notification
  if (is_ally (ally_slot, slot))
    {
      sprintf (buf,
	       "%s secures an alliance between clan %s`` and clan %s``.\n\r",
	       NAME (ch), clan_table[slot].name, clan_table[ally_slot].name);

      // notify allies if we are improving the relation ship
      send_clan_members (ally_slot, buf);
    }

  else if (is_requested_ally (slot, ally_slot))
    {
      sprintf (buf,
	       "%s petitions for an alliance between clan %s`` and clan %s``.\n\r",
	       NAME (ch), clan_table[slot].name, clan_table[ally_slot].name);

      // notify the other clan if we are attempting to improve the relationship
      send_clan_members (ally_slot, buf);
    }

  else
    {
      sprintf (buf,
	       "%s has worsened relations between clan %s`` and clan %s``.\n\r",
	       NAME (ch), clan_table[slot].name, clan_table[ally_slot].name);
    }

  // notify the clan membership
  send_clan_members_ch (ch, buf);

  // notify the wiznet subscribers of the player action
  sprintf (wbuf, "--> %s", buf);
  wiznet (wbuf, NULL, NULL, WIZ_CLAN, 0, 0);
  if (is_ally (ally_slot, slot))
    {
      sprintf (buf, "You secure an alliance with clan %s``.\n\r",
	       clan_table[ally_slot].name);
    }

  else if (is_requested_ally (slot, ally_slot))
    {
      sprintf (buf,
	       "You petition for clan %s`` to ally with your clan.\n\r",
	       clan_table[ally_slot].name);
    }

  else
    {				// neutral is all that is left
      sprintf (buf,
	       "You worsen your clans relations with clan %s``.\n\r",
	       clan_table[ally_slot].name);
    }
  send_to_char (buf, ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_ally", ch, argument);

#endif /*  */
}


//
// Allow a clan leader to make a clan an enemy
//
void clan_enemy (CHAR_DATA * ch, char *argument)
{
  char wbuf[MAX_STRING_LENGTH];
  char buf[MAX_STRING_LENGTH];
  RELATIONS *enemy = NULL;
  int slot, enemies, levels;
  int enemy_slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_enemy", ch, argument);

#endif /*  */
  slot = (ch->clan);
  if (slot == CLAN_BOGUS)
    {
      send_to_char ("You are not in a clan.\n\r", ch);
      return;
    }
  // validate that it is a mortal visible clan
  if (clan_table[slot].status < CLAN_PROPOSED)
    {
      send_to_char ("You are not in a clan.\n\r", ch);
      return;
    }
  if (!is_clan_leader (ch) && !is_clan_deputy (ch) && !IS_IMMORTAL (ch))
    {
      send_to_char
	("You must lead your clan in order to mark clan enemies.\n\r", ch);
      return;
    }
  // check that their clan is not restricted
  if (clan_table[slot].status < CLAN_ACTIVE)
    {
      send_to_char ("Your clan is not currently a full clan.\n\r", ch);
      return;
    }
  // if they gave us no clan name then list our enemies
  if (argument[0] == '\0')
    {
      list_enemies (ch, slot);
      return;
    }
  enemy_slot = clanname_to_slot (argument);
  if (enemy_slot == CLAN_BOGUS)
    {
      sprintf (buf, "There is no clan named %s.\n\r", capitalize (argument));
      send_to_char (buf, ch);
      return;
    }
  // validate that it is a mortal visible clan
  if (clan_table[enemy_slot].status < CLAN_PROPOSED)
    {
      sprintf (buf, "There is no clan named %s.\n\r", capitalize (argument));
      send_to_char (buf, ch);
      return;
    }
  if (enemy_slot == slot)
    {
      send_to_char ("You can not mark your own clan as an enemy.\n\r", ch);
      return;
    }
  if (is_requested_ally (slot, enemy_slot))
    {
      sprintf (buf,
	       "Clan %s`` may not be marked as both an ally and an enemy.\n\r",
	       clan_table[enemy_slot].name);
      send_to_char (buf, ch);
      return;
    }
  if (clan_table[enemy_slot].status < CLAN_ACTIVE)
    {
      send_to_char
	("You may not make enemies out of proposed or restricted clans.\n\r",
	 ch);
      return;
    }
  if (is_warring (slot, enemy_slot))
    {
      sprintf (buf, "You are already warring with clan %s.\n\r",
	       clan_table[enemy_slot].name);
      send_to_char (buf, ch);
      return;
    }
  // first if they are an enemy then this works
  // as a toggle and unsets the enemy status.
  enemy =
    find_relation (clan_table[slot].relations, clan_table[enemy_slot].ident);

  // if there is no enemy entry then we are neutral to them
  // allocate a relation record and set it to neutral, fix up below
  if (enemy == NULL)
    {
      enemy = new_relations_elt ();
      strcpy ((enemy->name), clan_table[enemy_slot].name);
      enemy->ident = clan_table[enemy_slot].ident;
      enemy->status = CLAN_NEUTRAL;

      // add them to the relations list
      clan_table[slot].relations =
	append_relation (clan_table[slot].relations, enemy);
    }
  // Check that they are not trying to add a new enemy
  if (enemy->status != CLAN_ENEMY)
    {

      // make sure that this clan does not exceed a hard value
      enemies = count_clan_enemies (slot);
      if (enemies >= CLAN_ENEMIES_MAX)
	{
	  send_to_char ("Your clan cannot manage any more enemies.\n\r", ch);
	  return;
	}
      // validate that this clan has enough levels to add an enemy,
      // every clan will be able to have at least one enemy
      levels = clan_levels (slot);
      if (levels < (enemies * LEVELS_PER_ENEMY))
	{
	  send_to_char
	    ("Your clan is not powerful enough to declare another enemy.\n\r",
	     ch);
	  return;
	}
    }
  // now given the current ally status shift to another status
  switch ((enemy->status))
    {
    case CLAN_ALLY:
      sprintf (buf,
	       "Clan %s`` can not be marked both an ally and an enemy.\n\r",
	       clan_table[enemy_slot].name);
      send_to_char (buf, ch);
      return;
      break;
    case CLAN_NEUTRAL:
      enemy->status = CLAN_ENEMY;
      enemy->acttime = time (NULL);
      save_clan (slot);
      break;
    case CLAN_ENEMY:
      enemy->status = CLAN_NEUTRAL;
      enemy->acttime = time (NULL);
      save_clan (slot);
      break;
    case CLAN_WAR:
    case CLAN_WAR_AGGR:
    case CLAN_WAR_VICT:
      sprintf (buf, "But you are currently at war with %s!\n\r",
	       clan_table[enemy_slot].name);
      send_to_char (buf, ch);
      return;
      break;
    default:
      enemy->status = CLAN_ENEMY;
      enemy->acttime = time (NULL);
      sprintf (buf,
	       "clan_enemy() unrecognized clan status %d - clan %s tried to enemy clan %s",
	       (enemy->status), clan_table[slot].name,
	       clan_table[enemy_slot].name);
      bug (buf, 0);
      save_clan (slot);
      break;
    }

  // set up a string for message notification
  if (is_enemy (enemy_slot, slot))
    {
      sprintf (buf, "%s declares clan %s`` an enemy of clan %s``.\n\r",
	       NAME (ch), clan_table[slot].name, clan_table[enemy_slot].name);
    }

  else if (is_requested_enemy (slot, enemy_slot))
    {
      sprintf (buf,
	       "%s worsens relations between clan %s`` and clan %s``.\n\r",
	       NAME (ch), clan_table[slot].name, clan_table[enemy_slot].name);
    }

  else
    {
      sprintf (buf,
	       "%s makes overtures to improve relations between clan %s`` and clan %s``.\n\r",
	       NAME (ch), clan_table[slot].name, clan_table[enemy_slot].name);

      // only notify this clan membership if they are attempting
      // to improve the relationship
      send_clan_members (enemy_slot, buf);
    }

  // notify the clan membership
  send_clan_members_ch (ch, buf);

  // notify the wiznet subscribers of the player action
  sprintf (wbuf, "--> %s", buf);
  wiznet (wbuf, NULL, NULL, WIZ_CLAN, 0, 0);
  if (is_enemy (enemy_slot, slot))
    {
      sprintf (buf, "You have made your clan an enemy of clan %s``.\n\r",
	       clan_table[enemy_slot].name);
    }

  else if (is_requested_enemy (slot, enemy_slot))
    {
      sprintf (buf,
	       "You worsen your clans relations with clan %s``.\n\r",
	       clan_table[enemy_slot].name);
    }

  else
    {				// neutral is all that is left
      sprintf (buf,
	       "You make overtures to improve relations with clan %s``.\n\r",
	       clan_table[enemy_slot].name);
    }
  send_to_char (buf, ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_enemy", ch, argument);

#endif /*  */
}


//
// Allow a declaration of war
//
void clan_declare (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_STRING_LENGTH];
  RELATIONS *us;
  RELATIONS *them;
  int slot, enemy_slot;
  time_t now;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_declare", ch, argument);

#endif /*  */

  // validate syntax
  if (argument[0] == '\0')
    {
      send_to_char ("Which clan would you like to declare war with?\n\r", ch);
      return;
    }
  // check that this player is in a  clan
  slot = (ch->clan);
  if (slot == CLAN_BOGUS)
    {
      send_to_char ("You must be in a clan to start a war.\n\r", ch);
      return;
    }
  // make sure its still a valid clan
  if (clan_table[slot].status < CLAN_PROPOSED)
    {
      send_to_char ("You must be in a clan to start a war.\n\r", ch);
      return;
    }
  // check that they are the leader of this clan
  if (!is_clan_leader (ch) && !IS_IMMORTAL (ch))
    {
      send_to_char
	("You must be the leader of your clan to start a war.\n\r", ch);
      return;
    }
  // check that their clan is not restricted
  if (clan_table[slot].status < CLAN_ACTIVE)
    {
      send_to_char ("Your clan is not currently a full clan.\n\r", ch);
      return;
    }
  // check that the clan they named is a valid clan
  enemy_slot = clanname_to_slot (argument);
  if (enemy_slot == CLAN_BOGUS)
    {
      sprintf (buf, "There is no clan by the name of %s``.\n\r", argument);
      send_to_char (buf, ch);
      return;
    }
  // check that the clan they named is a valid clan
  if (clan_table[enemy_slot].status < CLAN_PROPOSED)
    {
      sprintf (buf, "There is no clan by the name of %s``.\n\r", argument);
      send_to_char (buf, ch);
      return;
    }
  // check that the clan they named is an active clan
  if (clan_table[enemy_slot].status < CLAN_ACTIVE)
    {
      send_to_char
	("You cannot declare war on proposed or restricted clans.\n\r", ch);
      return;
    }

  if (enemy_slot == clanname_to_slot ("guttersnipes"))
  {
	  send_to_char("You're just a big meanie now.\n\r",ch);
	  return;
  }
  // check that the clan is a PK clan
  if (clan_table[slot].ctype == CLAN_TYPE_EXPL)
    {
      sprintf (buf, "That would make your clan a PK clan``.\n\r");
      send_to_char (buf, ch);
      return;
    }
  // check that the clan they named is a PK clan
  if (clan_table[enemy_slot].ctype == CLAN_TYPE_EXPL)
    {
      sprintf (buf, "You can't declare war against %s``.\n\r", argument);
      send_to_char (buf, ch);
      return;
    }
  // do not let them do something dumb
  if (enemy_slot == slot)
    {
      send_to_char ("You can not start a war with your own clan.\n\r", ch);
      return;
    }
  // make sure we have some kind of relation with them
  them =
    find_relation (clan_table[slot].relations, clan_table[enemy_slot].ident);
  if (them == NULL)
    {
      sprintf (buf,
	       "Your clan does not have any current relationship with clan %s``.\n\r",
	       clan_table[enemy_slot].name);
      send_to_char (buf, ch);
      return;
    }
  // make sure they have some kind of relation with us
  us = find_relation (clan_table[enemy_slot].relations,
		      clan_table[slot].ident);
  if (us == NULL)
    {
      us = new_relations_elt ();
      strcpy ((us->name), clan_table[slot].name);
      us->ident = clan_table[slot].ident;
      us->status = CLAN_NEUTRAL;
      clan_table[enemy_slot].relations =
	append_relation (clan_table[enemy_slot].relations, us);
    }
  // can't go to war twice
  if (is_warring (slot, enemy_slot))
    {
      sprintf (buf, "You are already warring with %s``.\n\r",
	       clan_table[enemy_slot].name);
      send_to_char (buf, ch);
      return;
    }
  // ok, can't move directly from ally to war
  if (is_requested_ally (slot, enemy_slot))
    {
      sprintf (buf,
	       "You can not war with %s`` as they are marked an ally.\n\r",
	       clan_table[enemy_slot].name);
      send_to_char (buf, ch);
      return;
    }
  // they better be marked as an enemy
  if (!is_requested_enemy (slot, enemy_slot))
    {
      sprintf (buf, "You must first mark clan %s`` as an enemy.\n\r",
	       clan_table[enemy_slot].name);
      send_to_char (buf, ch);
      return;
    }
  // check that the time of the last action happend long enough in the past
  now = time (NULL);
  if ((now - (them->acttime)) < CLAN_ENEMY_TIME)
    {
      sprintf (buf,
	       "Clan %s`` has not been your enemy long enough to start a war.\n\r",
	       clan_table[enemy_slot].name);
      send_to_char (buf, ch);
      return;
    }
  // in this case, us is their relations with us
  (us->warcount)++;
  us->status = CLAN_WAR_VICT;
  us->wartime = now;
  us->kills = 0;
  us->points = 0;

  // and them is our relations with them
  (them->warcount)++;
  them->status = CLAN_WAR_AGGR;
  them->wartime = now;
  them->kills = 0;
  them->points = 0;

  // better save both clans
  save_clan (enemy_slot);
  save_clan (slot);

  // notify all of the players of a war
  sprintf (buf, "War breaks out and rages across the realms...\n\r");
  send_all_players (ch, buf);

  // notify the wiznet subscribers of the player action
  sprintf (buf, "--> Clan %s`` declares war on clan %s``.\n\r",
	   clan_table[slot].name, clan_table[enemy_slot].name);
  wiznet (buf, NULL, NULL, WIZ_CLAN, 0, 0);

  // notify the members of this clan that their leader did the deed
  sprintf (buf,
	   "\n\rYour clan has declared war on clan %s``!\n\rMay the innocent be safe.\n\r",
	   clan_table[enemy_slot].name);
  send_clan_members_ch (ch, buf);

  // notify the individual
  sprintf (buf,
	   "\n\rYou have declared war on clan %s``!\n\rMay the innocent be safe.\n\r",
	   clan_table[enemy_slot].name);
  send_to_char (buf, ch);

  // let the members of the other clan know that things have gone sour
  sprintf (buf,
	   "\n\rClan %s`` has declared war on your clan!\n\rMay this act of treachery be avenged.\n\r",
	   clan_table[slot].name);
  send_clan_members (enemy_slot, buf);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_declare", ch, argument);

#endif /*  */
}


//
//  Simply list off the last wins or losses
//
void clan_last (CHAR_DATA * ch)
{
  RELATIONS *them;
  RELATIONS *us;
  char buf[MAX_STRING_LENGTH];
  char logbuf[MAX_STRING_LENGTH];
  time_t now;
  int ident;
  int slot;
  int enemy_slot;
  bool found = FALSE;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_last", ch, ((char *) NULL));

#endif /*  */

  // if this is an immortal checking, do a quick check of the existing wars
  if (IS_IMMORTAL (ch))
    update_wars ();
  now = time (NULL);
  send_to_char ("Recent clan wars:\n\r", ch);

  // run through all of the known clans
  for (slot = CLANS_START; slot < clan_number; slot++)
    {
      if (clan_table[slot].status < CLAN_ACTIVE)
	{

#ifdef VERBOSE_CLANS
	  sprintf (logbuf, "clan_last: skipping %s [%d] not active",
		   clan_table[slot].name, slot);
	  log_string (logbuf);

#endif /*  */
	  continue;
	}
      us = clan_table[slot].relations;
      ident = clan_table[slot].ident;
      while (us)
	{

	  // do not be fooled (us->ident) is really *their* identifier
	  enemy_slot = clanident_to_slot (us->ident);

	  // if the war was recent enough to count and they are not still at war
#ifdef VERBOSE_CLANS
	  sprintf (logbuf, "clan_last: %s [%d] relation with %s [%d]",
		   clan_table[slot].name, slot,
		   clan_table[enemy_slot].name, enemy_slot);
	  log_string (logbuf);
	  sprintf (logbuf, "clan_last: status: %d recent war: %ld < %d",
		   us->status, (now - (us->wartime)), RECENT_WAR_TIME);
	  log_string (logbuf);

#endif /*  */
	  if (((now - (us->wartime)) < RECENT_WAR_TIME) &&
	      (us->status < CLAN_WAR))
	    {

	      // if this clan is one we have not yet processed
	      if (enemy_slot > slot)
		{

		  // look up their relationship with us
		  them =
		    find_relation (clan_table[enemy_slot].relations, ident);
		  if (them != NULL)
		    {

		      // They better have a relation with us
		      if ((us->points) > (them->points))
			{
			  sprintf (buf,
				   "Clan %s`` (%d points in %d kill%s) defeated clan %s`` (%d points in %d kill%s).\n\r",
				   clan_table[slot].name, (us->points),
				   (us->kills),
				   (us->kills) == 1 ? "" : "s",
				   clan_table[enemy_slot].name,
				   (them->points), (them->kills),
				   (them->kills) == 1 ? "" : "s");
			}

		      else if ((us->points) < (them->points))
			{
			  sprintf (buf,
				   "Clan %s`` (%d points in %d kill%s) defeated clan %s`` (%d points in %d kill%s).\n\r",
				   clan_table[enemy_slot].name,
				   (them->points), (them->kills),
				   (them->kills) == 1 ? "" : "s",
				   clan_table[slot].name, (us->points),
				   (us->kills), (us->kills) == 1 ? "" : "s");
			}

		      else
			{
			  sprintf (buf,
				   "Clan %s`` fought to a stalemate with clan %s``.\n\r",
				   clan_table[slot].name,
				   clan_table[enemy_slot].name);
			}
		      send_to_char (buf, ch);
		      found = TRUE;
		    }

		  else
		    {

		      // uh, oh - the them relation is screwed
		      sprintf (logbuf,
			       "clan_last: %s [%d] relation with %s [%d]",
			       clan_table[slot].name, slot,
			       clan_table[enemy_slot].name, enemy_slot);
		      bug (logbuf, 0);
		      bug ("clan_last: them relation is NULL", 0);
		      sprintf (logbuf,
			       "clan_last: now: %ld us->wartime: %ld status: %d",
			       now, us->wartime, us->status);
		      bug (logbuf, 0);
		    }
		}
	    }
	  us = us->next;
	}
    }
  if (!found)
    send_to_char ("None.\n\r", ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_last", ch, ((char *) NULL));

#endif /*  */
}

//
// List off the active clan wars
//
void clan_wars (CHAR_DATA * ch)
{
  char logbuf[MAX_STRING_LENGTH];
  char buf[MAX_STRING_LENGTH];
  RELATIONS *us;
  RELATIONS *them;
  int slot;
  int enemy_slot;
  int ident;
  time_t timeleft;
  long hr, min, sec;
  bool found = FALSE;
  int war_number;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_wars", ch, ((char *) NULL));

#endif /*  */

  // if this is an immortal checking, do a quick check of the existing wars
  if (IS_IMMORTAL (ch))
    update_wars ();
  send_to_char ("Current clan wars: \n\r", ch);

  // run through all of the known clans
  for (slot = CLANS_START; slot < clan_number; slot++)
    {
      if (clan_table[slot].status < CLAN_ACTIVE)
	continue;
      us = clan_table[slot].relations;
      ident = clan_table[slot].ident;
      while (us)
	{

	  // if we are in a clan war
	  if ((us->status >= CLAN_WAR))
	    {

	      // do not be fooled (us->ident) is really *their* identifier
	      enemy_slot = clanident_to_slot (us->ident);

	      // if this clan is one we have not yet processed
	      if (enemy_slot > slot)
		{
		  them =
		    find_relation (clan_table[enemy_slot].relations, ident);
		  if (them != NULL)
		    {
		      war_number = (slot * 100) + enemy_slot;
		      sprintf (buf,
			       "Clan %s %d points (%d kill%s) vs. Clan %s %d points (%d kill%s)",
			       clan_table[slot].name, us->points,
			       us->kills, us->kills == 1 ? "" : "s",
			       clan_table[enemy_slot].name,
			       them->points, them->kills,
			       them->kills == 1 ? "" : "s");
		      if (IS_IMMORTAL (ch))
			{
			  timeleft =
			    ((us->wartime + CLAN_WAR_TIME) - time (NULL));
			  if (timeleft < 0)
			    timeleft = 0;
			  min = timeleft / 60;
			  sec = timeleft % 60;
			  hr = min / 60;
			  min = min % 60;
			  sprintf (buf + strlen (buf),
				   " (%ld:%ld:%ld) (War Number: %d) \n\r",
				   hr, min, sec, war_number);
			}

		      else
			{
			  sprintf (buf + strlen (buf), "\n\r");
			}
		      send_to_char (buf, ch);
		      found = TRUE;
		    }

		  else
		    {

		      // uh, oh - the them relationship is null
		      sprintf (logbuf,
			       "clan_wars: %s [%d] relation with %s [%d]",
			       clan_table[slot].name, slot,
			       clan_table[enemy_slot].name, enemy_slot);
		      bug (logbuf, 0);
		      bug ("clan_wars: them relation is NULL", 0);
		    }
		}
	    }
	  us = us->next;
	}
    }
  if (!found)
    send_to_char ("\tNone.\n\r", ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_wars", ch, ((char *) NULL));

#endif /*  */
}

//
//  List off a bunch of simple things about this clan
//
void clan_info (CHAR_DATA * ch, char *argument)
{
  MEMBER *m;
  RELATIONS *r;
  int twins = 0;
  int tloss = 0;
  int slot;
  int cnt;
  int members = 0;
  bool found = FALSE;
  char outbuf[MAX_STRING_LENGTH * 4];

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_info", ch, argument);

#endif /*  */

  // validate syntax
  if (argument[0] == '\0')
    {
      send_to_char ("Which clan would you like information about?\n\r", ch);
      return;
    }
  // validate the slot
  slot = clanname_to_slot (argument);
  if (slot == CLAN_BOGUS)
    {
      sprintf (outbuf, "There is no clan named %s``.\n\r",
	       capitalize (argument));
      send_to_char (outbuf, ch);
      return;
    }
  // validate clan status
  if ((clan_table[slot].status < CLAN_PROPOSED) && !IS_IMMORTAL (ch))
    {
      sprintf (outbuf, "There is no clan named %s``.\n\r",
	       capitalize (argument));
      send_to_char (outbuf, ch);
      return;
    }
  // the basics
  sprintf (outbuf, "Clan Name: %s``\n\rClan Symbol: %s``\n\r",
	   clan_table[slot].name, clan_table[slot].symbol);

  // count the number of members
  m = clan_table[slot].members;
  while (m)
    {
      members++;
      m = m->next;
    }
  sprintf (outbuf + strlen (outbuf), "Clan Members: %d\n\r", members);

  // run through their relation list and get the total wins and losses
  r = clan_table[slot].relations;
  twins = 0;
  tloss = 0;
  while (r)
    {
      twins += (r->wins);
      tloss += (r->loss);
      r = r->next;
    }
  sprintf (outbuf + strlen (outbuf),
	   "Clan War Wins: %d\tClan War Losses: %d\n\r", twins, tloss);
  page_to_char (outbuf, ch);

  // further information is reserved for clan members and immortals
  if ((!IS_IMMORTAL (ch)) && (slot != ch->clan))
    {

#ifdef VERBOSE_CLANS
      log_player_command ("f:clan_info", ch, "not a member exit");

#endif /*  */
      return;
    }
  if (IS_IMMORTAL (ch))
    clan_short_status (ch, argument);

  // list off the allies
  list_allies (ch, slot);

  // list off the enemies of this clan
  list_enemies (ch, slot);
  sprintf (outbuf, "Recently defeated by clan %s``:\n\r",
	   clan_table[slot].name);
  found = FALSE;
  r = clan_table[slot].relations;
  cnt = 0;
  while (r)
    {
      if (has_defeated_clan (get_clan_ident (slot), r->ident))
	{
	  sprintf (outbuf + strlen (outbuf), "%-12s``", r->name);
	  if (cnt % 3 == 0)
	    strcat (outbuf, "\n\r");
	  cnt++;
	  found = TRUE;
	}
      r = r->next;
    }
  if (!found)
    strcat (outbuf, "None.");
  strcat (outbuf, "\n\r");
  page_to_char (outbuf, ch);
  sprintf (outbuf, "Recent losses by clan %s``:\n\r", clan_table[slot].name);
  found = FALSE;
  r = clan_table[slot].relations;
  cnt = 0;
  while (r)
    {
      if (has_defeated_clan (r->ident, get_clan_ident (slot)))
	{
	  sprintf (outbuf + strlen (outbuf), "%-12s``", r->name);
	  if (cnt % 3 == 0)
	    strcat (outbuf, "\n\r");
	  cnt++;
	  found = TRUE;
	}
      r = r->next;
    }
  if (!found)
    strcat (outbuf, "None.");
  strcat (outbuf, "\n\r");
  page_to_char (outbuf, ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_info", ch, argument);

#endif /*  */
}


//
// Allow a deputy or leader to accept another player into the clan
//
void clan_accept (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  char clanstr[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  CHAR_DATA *vic;
  MEMBER *newm;
  MEMBER *oldm;
  int slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_accept", ch, argument);

#endif /*  */
  argument = one_argument (argument, arg);

  // check the syntax
  if (arg[0] == '\0')
    {
      send_to_char ("Accept which player into your clan?\n\r", ch);
      return;
    }
  if (IS_IMMORTAL (ch))
    {
      argument = one_argument (argument, clanstr);

      // the immortal eiter must be in the clan or supply a clan name
      if (clanstr[0] == '\0')
	{
	  slot = ch->clan;
	}

      else
	{
	  slot = clanname_to_slot (clanstr);
	}

      // validate the slot
      if (slot == CLAN_BOGUS)
	{
	  send_to_char
	    ("You must be in a clan or name a valid clan.\n\r", ch);
	  return;
	}
    }

  else
    {

      // check that we have a valid clan
      slot = ch->clan;
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("You are not in a clan.\n\r", ch);
	  return;
	}
      // offically if the clan is some status less than propsed then
      // it does not exist to players
      if (clan_table[slot].status < CLAN_PROPOSED)
	{
	  send_to_char ("You are not in a clan.\n\r", ch);
	  return;
	}
      // they need to be a leader or deputy
      if (!is_clan_leader (ch) && !is_clan_deputy (ch))
	{
	  send_to_char ("You do not lead a clan.\n\r", ch);
	  return;
	}
    }

  // look up this name in the applicant list
  oldm = find_member (clan_table[slot].applicants, arg);
  if (oldm == NULL)
    {
      sprintf (buf, "No player %s has applied to your clan.\n\r",
	       capitalize (arg));
      send_to_char (buf, ch);
      return;
    }
  vic = find_character (arg);
  if (vic == NULL)
    {
      send_to_char ("That character is not online.\n\r", ch);
      return;
    }
  if (vic->level < 9)
    {
      send_to_char ("That character is not level 9 or more.\n\r", ch);
      return;
    }
  // copy from the old member rec to the new one
  // unfortunate side effect of the way I coded the
  // the member list insert, delete and find functions
  newm = new_member_elt ();
  strcpy (newm->name, oldm->name);
  newm->levels = oldm->levels;
  newm->align = oldm->align;
  newm->status = CLAN_ACCEPTED;
  newm->initiative = CLAN_BOGUS;

  // if player is on line, update the victim's player record
  // notify the victim that they are now part of the clan
  vic = find_character (arg);
  if (vic != NULL)
    {
      if (clan_table[slot].ctype == CLAN_TYPE_EXPL)
	vic->pcdata->loner = FALSE;

      else
	vic->pcdata->loner = TRUE;
      vic->pcdata->deputy = FALSE;
      vic->clan = slot;
      save_char_obj (vic);
      sprintf (buf, "You have been accepted into clan %s``.\n\r",
	       clan_table[slot].name);
      send_to_char (buf, vic);
    }
  // notify membership
  sprintf (buf, "%s has been accepted into clan %s``.\n\r",
	   capitalize (arg), clan_table[slot].name);
  send_clan_members_ch (ch, buf);

  // finally delete the oldm record
  clan_table[slot].applicants =
    delete_member (clan_table[slot].applicants, arg);
  oldm = NULL;

  // append the new member record
  clan_table[slot].members = append_member (clan_table[slot].members, newm);

  // now check if the addition of this member changes the clan status
  clan_table[slot].levels += newm->levels;
/*  if (//((clan_table[slot].status == CLAN_PROPOSED) ||
       (clan_table[slot].status == CLAN_RESTRICTED)//)
      && clan_table[slot].levels >= FULL_CLAN_LEVELS)
    {
      clan_table[slot].status = CLAN_ACTIVE;
      sprintf (buf, "Clan %s`` has been promoted to a full clan.\n\r",
	       clan_table[slot].name);
      send_clan_members (slot, buf);
    }*/
  // save all of these updates
  save_clan (slot);
  sprintf (buf, "You accepted %s into clan %s``.\n\r", capitalize (arg),
	   clan_table[slot].name);
  send_to_char (buf, ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_accept", ch, argument);

#endif /*  */
}


//
// Allow a deputy or a leader to deny another player membership
//
void clan_deny (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  int clan;
  MEMBER *applicant;
  CHAR_DATA *vic;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_deny", ch, argument);

#endif /*  */
  argument = one_argument (argument, arg);

  // validate the syntax
  if (arg[0] == '\0')
    {
      send_to_char ("Deny which player membership to your clan?\n\r", ch);
      return;
    }
  // check that we have a valid clan
  clan = ch->clan;
  if (clan == CLAN_BOGUS)
    {
      send_to_char ("You are not in a clan.\n\r", ch);
      return;
    }
  // offically if the clan is some status less than propsed then
  // it does not exist to players
  if (clan_table[clan].status < CLAN_PROPOSED)
    {
      send_to_char ("You are not in a clan.\n\r", ch);
      return;
    }
  // they need to be a leader or deputy
  if (!is_clan_leader (ch) && !is_clan_deputy (ch))
    {
      send_to_char ("You do not lead a clan.\n\r", ch);
      return;
    }
  applicant = find_member (clan_table[clan].applicants, arg);
  if (applicant == NULL)
    {
      sprintf (buf, "No one named %s has applied to your clan.\n\r", arg);
      send_to_char (buf, ch);
      return;
    }
  // this is safe because if the applicant wasn't in the
  // list we wouldn't fall through to this section
  // wow, way shorter than it used to be, only two lines
  clan_table[clan].applicants =
    delete_member (clan_table[clan].applicants, arg);
  save_clan (clan);

  // they do not have to be online, but if they are they should be notified
  vic = find_character (arg);
  if (vic != NULL)
    {
      sprintf (buf, "You have been denied entry to clan %s``.\n\r",
	       clan_table[clan].name);
      send_to_char (buf, vic);
    }
  // let the person know their action was taken
  sprintf (buf, "You denied %s entry into clan %s``.\n\r",
	   capitalize (arg), clan_table[clan].name);
  send_to_char (buf, ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_deny", ch, argument);

#endif /*  */
}


//
//  Allow a deputy or a clan leader to check the applicants
//
void clan_prospects (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_STRING_LENGTH];
  char name[MAX_STRING_LENGTH];
  MEMBER *a;
  int slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_prospects", ch, argument);

#endif /*  */
  if (IS_IMMORTAL (ch))
    {
      argument = one_argument (argument, name);
      if (name[0] == '\0')
	{
	  send_to_char ("You need to specify a clan.\n\r", ch);
	  return;
	}
      slot = clanname_to_slot (name);
      if (slot == CLAN_BOGUS)
	{
	  sprintf (buf, "There is no clan named %s``.\n\r",
		   capitalize (name));
	  send_to_char (buf, ch);
	  return;
	}
      if (clan_table[slot].status < CLAN_PROPOSED)
	{
	  send_to_char
	    ("This clan is currently in an inactive state.\n\r", ch);
	}
    }

  else
    {
      slot = ch->clan;
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("You are not in a clan.\n\r", ch);
	  return;
	}
      if (clan_table[slot].status < CLAN_PROPOSED)
	{
	  send_to_char ("Your clan no longer exists.\n\r", ch);
	  return;
	}
      if (!is_clan_leader (ch) && !is_clan_deputy (ch))
	{
	  send_to_char ("You do not lead your clan.\n\r", ch);
	  return;
	}
    }

  // check that there are some applicants
  a = clan_table[slot].applicants;
  if (a == NULL)
    {
      send_to_char ("No players are applying to your clan.\n\r", ch);
      return;
    }
  send_to_char ("Players currently applying to your clan:\n\r", ch);
  while (a)
    {
      sprintf (buf, "\t%-12s [%3d] [%5d]\n\r", a->name, a->levels, a->align);
      send_to_char (buf, ch);
      a = a->next;
    }

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_prospects", ch, argument);

#endif /*  */
}


//
// Allow a deputy or a clan leader to expel a clan member
//
void clan_expel (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  char clanstr[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  CHAR_DATA *vic;
  MEMBER *oldm;
  int slot;
  int levels;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_expel", ch, argument);

#endif /*  */
  argument = one_argument (argument, arg);

  // check the syntax
  if (arg[0] == '\0')
    {
      send_to_char ("Expel which player from your clan?\n\r", ch);
      return;
    }
  /*if (ch->clan != CLAN_BOGUS)
  {
   if ((clan_table[ch->clan].relations)->status >= CLAN_WAR)
     {
       send_to_char ("You may not expel during a war.  That is LAME.\n\r",ch);
       return;
     }
  }*/
   
  if (IS_IMMORTAL (ch))
    {
      argument = one_argument (argument, clanstr);

      // the immortal eiter must be in the clan or supply a clan name
      if (clanstr[0] == '\0')
	{
	  slot = ch->clan;
	}

      else
	{
	  slot = clanname_to_slot (clanstr);
	}

      // validate the slot
      if (slot == CLAN_BOGUS)
	{
	  send_to_char
	    ("You must be in a clan or name a valid clan.\n\r", ch);
	  return;
	}
    }

  else
    {

      // validate the clan
      slot = ch->clan;
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("You are not in a clan.\n\r", ch);
	  return;
	}
      // make sure it's active
      if (clan_table[slot].status < CLAN_PROPOSED)
	{
	  send_to_char ("That clan does not exist.\n\r", ch);
	  return;
	}
      // validate that they are an appropriate type player
      if (!is_clan_leader (ch) && !is_clan_deputy (ch))
	{
	  send_to_char ("You do not lead a clan.\n\r", ch);
	  return;
	}
    }

  // if the names are the same, can't expel yourself
  if (!str_cmp (ch->name, arg))
    {
      send_to_char
	("You can not expel yourself, try defecting instead.\n\r", ch);
      return;
    }
  // Make sure there is someone named that
  oldm = find_member (clan_table[slot].members, arg);
  if (oldm == NULL)
    {
      sprintf (buf, "%s is not in your clan.\n\r", arg);
      send_to_char (buf, ch);
      return;
    }
  // ok, do not throw out the leader....
  if ((oldm->status == CLAN_LEADER))
    {
      send_to_char ("You can not expel the clan leader.\n\r", ch);
      return;
    }
  // special privilidges for a deputy, immortals and leaders only expel
  if (!IS_IMMORTAL (ch) &&
      (oldm->status >= CLAN_DEPUTY) && !is_clan_leader (ch))
    {
      send_to_char ("Only clan leaders may expel deputies.\n\r", ch);
      return;
    }
  // save the levels of this character
  levels = oldm->levels;

  // if the player is on line then fix their record and tell them
  vic = find_character (arg);
  if (vic != NULL)
    {
      if (clan_table[vic->clan].ctype == CLAN_TYPE_EXPL)
	vic->pcdata->loner = FALSE;

      else
	vic->pcdata->loner = TRUE;
      vic->clan = CLAN_BOGUS;
      vic->pcdata->deputy = FALSE;
      save_char_obj (vic);
      sprintf (buf, "You have been expelled from clan %s``.\n\r",
	       clan_table[ch->clan].name);
      send_to_char (buf, vic);
    }
  // Do the deletion
  clan_table[slot].members = delete_member (clan_table[slot].members, arg);
  save_clan (slot);

  // Notify the clan
  sprintf (buf, "%s has been expelled from clan %s`` by %s.\n\r",
	   capitalize (arg), clan_table[slot].name, ch->name);
  send_clan_members_ch (ch, buf);

  // subtract off the number of levels that this player
  // contributed to the establishment of the clan
  clan_table[slot].levels -= levels;
  if (clan_table[slot].levels < FULL_CLAN_LEVELS)
    {
      clan_table[slot].status = CLAN_RESTRICTED;
      sprintf (buf,
	       "Clan %s`` has lost too many levels and is now restricted.\n\r",
	       clan_table[slot].name);
      send_clan_members (slot, buf);
      save_clan (slot);
    }
  // Notify the player
  sprintf (buf, "You expelled %s from clan %s``.\n\r",
	   capitalize (arg), clan_table[slot].name);
  send_to_char (buf, ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_expel", ch, argument);

#endif /*  */
}


//
// Allow the clan leader to promote/demote a player to deputy
//
void clan_deputy (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  CHAR_DATA *vic;
  MEMBER *m;
  int clan;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_deputy", ch, argument);

#endif /*  */
  one_argument (argument, arg);

  // validate the syntax
  if (arg[0] == '\0')
    {
      send_to_char ("Promote which player to deputy?\n\r", ch);
      return;
    }
  // validate the clan slot
  clan = ch->clan;
  if (clan == CLAN_BOGUS)
    {
      send_to_char ("You are not in a clan.\n\r", ch);
      return;
    }
  // if their clan has been dispersed, disbanded or deactivated
  if ((clan_table[clan].status < CLAN_PROPOSED))
    {
      send_to_char ("You are not in a clan.\n\r", ch);
      return;
    }
  // they better be leader to make a deputy
  if (!is_clan_leader (ch))
    {
      send_to_char ("You do not lead your clan.\n\r", ch);
      return;
    }
  // the player better be on line too
  m = find_member (clan_table[clan].members, arg);
  if (m == NULL)
    {
      send_to_char ("They are not in your clan.", ch);
      return;
    }
  // well m had better not be null by the time we get here
  if (m->status < CLAN_DEPUTY)
    {

      // promote them
      m->status = CLAN_DEPUTY;
      save_clan (clan);

      // if the new deputy is on line let him know
      vic = find_character (arg);
      if (vic != NULL)
	{

	  // this deputy flag should not be used, always false now
	  vic->pcdata->deputy = FALSE;
	  save_char_obj (vic);
	  sprintf (buf, "You are now a deputy of clan %s``.\n\r",
		   clan_table[clan].name);
	  send_to_char (buf, vic);
	}
      // tell the player of his action
      sprintf (buf, "You have made %s a deputy of clan %s``.\n\r",
	       capitalize (arg), clan_table[clan].name);
      send_to_char (buf, ch);
    }

  else
    {

      // demote them
      m->status = CLAN_ACCEPTED;
      save_clan (clan);
      vic = find_character (arg);
      if (vic != NULL)
	{

	  // this deputy flag should not be used, always false now
	  vic->pcdata->deputy = FALSE;
	  save_char_obj (vic);
	  sprintf (buf, "You are no longer a deputy of clan %s``.\n\r",
		   clan_table[clan].name);
	  send_to_char (buf, vic);
	}
      // tell the player of his action
      sprintf (buf,
	       "You have revoked %s clan %s`` deputy privileges.\n\r",
	       capitalize (arg), clan_table[clan].name);
      send_to_char (buf, ch);
    }

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_deputy", ch, argument);

#endif /*  */
}


//
// Allow a player to attempt to establish a clan
//
void clan_establish (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_INPUT_LENGTH];
  int slot, oldslot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_establish", ch, argument);

#endif /*  */

//  if (!IS_IMMORTAL (ch))
  //   {
  //    send_to_char ("You must contact the immortal staff if you wish to create a new clan.\n\r", ch);
  //   return;
  //}

//  if (!IS_IMMORTAL (ch))
  //  {
  if (is_clan_leader (ch))
    {
      send_to_char ("You are already the leader of a clan.\n\r", ch);
      return;
    }
  slot = ch->clan;
  if (slot != CLAN_BOGUS)
    {
      sprintf (buf,
	       "You are a member of clan %s``, you must defect to establish clan.\n\r",
	       clan_table[slot].name);
      send_to_char (buf, ch);
      return;
    }
  oldslot = is_any_clan_applicant (ch);
  if ((oldslot != CLAN_BOGUS)
      && (clan_table[oldslot].status >= CLAN_PROPOSED))
    {
      sprintf (buf,
	       "You are already in clan %s``, you must defect in order to establish a clan.\n\r",
	       clan_table[oldslot].name);
      send_to_char (buf, ch);
      return;
    }
  if (ch->level < MIN_CLAN_LEVEL)
    {
      sprintf (buf,
	       "You must be at least level %d to establish a clan.\n\r",
	       MIN_CLAN_LEVEL);
      send_to_char (buf, ch);
      return;
    }
  // }
  if (clan_number >= (MAX_CLAN - 1))
    {
      send_to_char
	("Sorry, there are already too many clans in play.\n\r", ch);
      return;
    }
  add_clan (ch, argument);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_establish", ch, argument);

#endif /*  */
}


//
//  Finish the establishment functions
//
void add_clan (CHAR_DATA * ch, char *argument)
{
  MEMBER *m = NULL;
  char buf[MAX_INPUT_LENGTH];
  char name[MAX_INPUT_LENGTH];
  char symbol[MAX_INPUT_LENGTH];
  char status[MAX_INPUT_LENGTH];
  int i = 0;
  int slot = 0;

#ifdef VERBOSE_CLANS
  log_player_command ("s:add_clan", ch, argument);

#endif /*  */
  argument = one_argument_nl (argument, name);
  argument = one_argument_nl (argument, symbol);
  argument = one_argument_nl (argument, status);
  if (name[0] == '\0' || symbol[0] == '\0' || status[0] == '\0')
    {
      send_to_char
	("You must supply a clan name, a symbol and pk status.\r\n", ch);
      return;
    }
  if (color_strlen (name) > MAX_NAME_CH)
    {
      sprintf (buf, "The clan name may not exceed %d characters.\n\r",
	       MAX_NAME_CH);
      send_to_char (buf, ch);
      return;
    }
  if (strlen (name) > MAX_NAME)
    {
      send_to_char ("Try using less colors in your clan name.\n\r", ch);
      return;
    }
  if (color_strlen (symbol) > MAX_SYMB_CH)
    {
      sprintf (buf, "The clan symbol may not exceed %d characters.\n\r",
	       MAX_SYMB_CH);
      send_to_char (buf, ch);
      return;
    }
  if (strlen (symbol) > MAX_SYMB)
    {
      send_to_char ("Try using fewer colors in your clan symbol.\n\r", ch);
      return;
    }
  if (clan_lookup (name) != CLAN_BOGUS)
    {
      send_to_char ("That clan name is reserved or in use.\n\r", ch);
      return;
    }
  if (clan_symbol_lookup (symbol) != CLAN_BOGUS)
    {
      send_to_char ("That clan symbol is reserved or in use.\n\r", ch);
      return;
    }
  // names must be alphanumeric with no spaces
  for (i = 0; name[i] != '\0'; i++)
    {
      if (!isalnum ((int) name[i]) || isspace ((int) name[i]))
	{
	  send_to_char ("That is an illegal clan name.\n\r", ch);
	  return;
	}
    }

  // clan symbol with no spaces
  for (i = 0; symbol[i] != '\0'; i++)
    {
      if (isspace ((int) symbol[i]))
	{
	  send_to_char ("That is an illegal clan symbol.\n\r", ch);
	  return;
	}
    }

  // check that they are not trying to spoof the special clan symbol
  if (is_name_no_abbrev (symbol, CLAN_BOGUS_SYMB))
    {
      send_to_char ("That is an illegal clan symbol.\n\r", ch);
      return;
    }
  if (!IS_IMMORTAL (ch))
    {
      if (is_name_no_abbrev
	  (name,
	   "all auto withdraw immortal self someone something the you demise balance circle loner honor fuck satan angel whore christ bastard clan bogus"))
	{
	  send_to_char ("That is an illegal clan name.\n\r", ch);
	  return;
	}
    }
  // check that they are not trying to spoof the special clan name
  if (is_name_no_abbrev (name, CLAN_BOGUS_NAME))
    {
      send_to_char ("That is an illegal clan name.\n\r", ch);
      return;
    }
  // Akamai 02/21/00 - Clans named after players. BAD
  // check that they are not trying name their clan after an
  // existing player - send a simple error message.
  if (is_player_name (name))
    {
      send_to_char ("It is a bad idea to name clans after players.\n\r", ch);
      return;
    }
  // check if they have decided upon a life of the clan,
  // pk or nopk, only immortals can change that afterwards
  if (!str_cmp (status, "pk") && !str_cmp (status, "nopk"))
    {
      send_to_char
	("You must decide if your clan is a PK or a NoPK clan.\n\r", ch);
      return;
    }
  // Making a nopk clan when you are already a loner is a no no
  if (ch->pcdata->loner && (str_cmp (status, "pk")))
    {
      send_to_char
	("You can't make a nopk clan when you are a loner.\n\r", ch);
      return;
    }
  // establish this clan as a proposed clan
  slot = clan_number;

  // we now have one more clan to consider
  clan_number++;

  // fill in the clan data
  strcpy (clan_table[slot].name, name);
  strcpy (clan_table[slot].symbol, symbol);
  m = new_member_elt ();
  m->status = CLAN_LEADER;
  strcpy (m->name, ch->name);
  m->align = ch->alignment;
  m->levels = ch->level;
  clan_table[slot].members = m;
  clan_table[slot].leader = m;
  clan_table[slot].hall = ROOM_VNUM_ALTAR;
  clan_table[slot].levels = ch->level;
  if (IS_IMMORTAL (ch))
    {
      clan_table[slot].status = CLAN_ACTIVE;
    }

  else
    {

      // Ok, ok, this may seem absurd but for testing we check that a
      // new clan might actually start out as a full clan
      if (clan_table[slot].levels > FULL_CLAN_LEVELS)
	{
	  clan_table[slot].status = CLAN_ACTIVE;
	}

      else
	{
	  clan_table[slot].status = CLAN_PROPOSED;
	}
    }
  clan_table[slot].ident = CLAN_PC_IDENT_MIN + _clan_ident_;
  if (!str_cmp (status, "pk"))
    clan_table[slot].ctype = CLAN_TYPE_PC;

  else
    clan_table[slot].ctype = CLAN_TYPE_EXPL;
  _clan_ident_++;

  // save the clan info
  save_clan (slot);
  save_clanindex ();

  // update this as if he joined a clan
  if (!IS_IMMORTAL (ch))
    {
      if (clan_table[slot].ctype == CLAN_TYPE_EXPL)
	ch->pcdata->loner = FALSE;

      else
	ch->pcdata->loner = TRUE;
      ch->pcdata->deputy = FALSE;
      ch->clan = slot;
      save_char_obj (ch);
    }

  else
    {
      ch->clan = slot;
    }
  sprintf (buf, "You are now the leader of clan %s``.\r\n",
	   clan_table[slot].name);
  send_to_char (buf, ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:add_clan", ch, argument);

#endif /*  */
}


//
//  Allow a clan member to donate an item to a clan box
//
void clan_donate (CHAR_DATA * ch, char *argument)
{

#ifdef VERBOSE_CLANS
  char buf[MAX_INPUT_LENGTH];

#endif /*  */
  char arg1[MAX_INPUT_LENGTH];
  ROOM_INDEX_DATA *location;
  OBJ_DATA *obj, *container;
  int slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_donate", ch, argument);

#endif /*  */
  slot = ch->clan;
  if (slot == CLAN_BOGUS)
    {
      send_to_char ("You don't currently belong to a clan.\n\r", ch);
      return;
    }
  argument = one_argument (argument, arg1);
  if (arg1[0] == '\0')
    {
      send_to_char ("Donate what?\n\r", ch);
      return;
    }
  if ((obj = get_obj_carry (ch, arg1)) == NULL)
    {
      send_to_char ("You do not have that item.\n\r", ch);
      return;
    }
  if (obj->wear_loc != -1)
    {
      send_to_char
	("You will have to remove that before you can donate it.\n\r", ch);
      return;
    }
  if (ch->fighting != NULL)
  {
    send_to_char("You can't clan donate while fighting.  That is LAME.\n\r",ch);
    return;
  }
  // Adeon 7/18/03 -- can't donate nosave eq
  if (IS_OBJ_STAT (obj, ITEM_NOSAVE) || IS_SET(obj->extra_flags[1],ITEM_NODONATE)
		  || obj->item_type == ITEM_CARD)
    {
      send_to_char ("Strong magic forces prevent you...\n\r", ch);
      return;
    }
  if (IS_OBJ_STAT (obj, ITEM_NODROP))
    {
      send_to_char ("Sorry, you can't donate that.\n\r", ch);
      return;
    }
  // What the hell are these magic numbers... This is a straight copy
  // from the previous code... sheesh
  if (obj->pIndexData->vnum >= 23000 && obj->pIndexData->vnum <= 23100)
    {
      send_to_char ("Sorry, you can't donate that.\n\r", ch);
      return;
    }
#ifdef VERBOSE_CLANS
  sprintf (buf, "clan_donate: %s is allowed to donate %s", ch->name,
	   obj->name);
  log_string (buf);

#endif /*  */
  container = clan_table[slot].clan_box;

  // if the clan box is not yet set, look for it
  if (container == NULL)
    {

#ifdef VERBOSE_CLANS
      sprintf (buf,
	       "clan_donate: searching all objects for clan donation box");
      log_string (buf);

#endif /*  */
      container = object_list;
      while (container != NULL)
	{
	  if (((container->item_type == ITEM_CLAN_DONATION) ||
	       (container->item_type == ITEM_NEWCLANS_DBOX)) &&
	      (container->value[1] == slot))
	    break;
	  container = container->next;
	}

      // if we don't find the clan box then bail
      if (container == NULL)
	{
	  send_to_char ("Your clan does not have a donation box.\n\r", ch);
	  return;
	}
      // found it so set it, we won't have to do this again
      clan_table[slot].clan_box = container;
    }
  if (container == NULL)
    {
      send_to_char ("You clan does not have a donation box.\n\r", ch);
      return;
    }
  if (container->value[0] != -1)
    {
      if (get_obj_number (container) >= container->value[0])
	{
	  send_to_char ("Sorry, the clan donation box is full.\n\r", ch);
	  return;
	}
    }
#ifdef VERBOSE_CLANS
  sprintf (buf, "clan_donate: box is found and has room for the new item");
  log_string (buf);

#endif /*  */
  if (ch->in_room->vnum == container->in_room->vnum)
    {
      act ("$n puts $p in the clan donation box.", ch, obj, NULL, TO_ROOM);
      act ("You put $p in the clan donation box.", ch, obj, NULL, TO_CHAR);
    }

  else
    {
      location = container->in_room;
      if (location == NULL)
	return;
      act ("You send $p to your clan donation box.", ch, obj, container,
	   TO_CHAR);
      act
	("Something materializes from thin air and falls into the clan donation box.",
	 location->people, NULL, NULL, TO_ALL);
    }
  if ((container != NULL) &&
      ((container->item_type == ITEM_CLAN_DONATION) ||
       (container->item_type == ITEM_NEWCLANS_DBOX)))
    {
      obj->cost = 0;
      obj_from_char (obj);
      obj_to_obj (obj, container);

#ifdef VERBOSE_CLANS
      sprintf (buf, "clan_donate: item placed in box, saving box");
      log_string (buf);

#endif /*  */
      save_clan_box (container);
      save_char_obj (ch);
    }
#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_donate", ch, argument);

#endif /*  */
}


//
//  Allow the clan leader to disband a clan
//
void clan_disband (CHAR_DATA * ch, char *argument)
{
  MEMBER *m;
  CHAR_DATA *c;
  char buf[MAX_INPUT_LENGTH];
  char name[MAX_INPUT_LENGTH];
  int slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_disband", ch, argument);

#endif /*  */
  if (IS_IMMORTAL (ch))
    {
      argument = one_argument (argument, name);
      if (name[0] == '\0')
	{
	  send_to_char ("Disband which clan?\n\r", ch);
	  return;
	}
      slot = clanname_to_slot (name);
      if (slot == CLAN_BOGUS)
	{
	  sprintf (buf, "There is no clan named %s``.\n\r",
		   capitalize (name));
	  send_to_char (buf, ch);
	  return;
	}
      if (clan_table[slot].status < CLAN_PROPOSED)
	{
	  sprintf (buf,
		   "Clan %s`` is already in a deactivated state.\n\r",
		   capitalize (name));
	  send_to_char (buf, ch);
	  return;
	}
    }

  else
    {

      // ok not an immortal so validate
      slot = ch->clan;
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("You are not in a clan.\n\r", ch);
	  return;
	}
      if (clan_table[slot].status < CLAN_PROPOSED)
	{
	  send_to_char ("You are not in a clan.\n\r", ch);
	  return;
	}
      if (!is_clan_leader (ch))
	{
	  send_to_char ("You are not the leader of your clan.\n\r", ch);
	  return;
	}
    }

  // if the clan is in a war, don't allow a disband right now
  if (clan_is_warring (slot))
    {
      sprintf (buf,
	       "Clan %s`` is currently at war and cannot be disbanded.\r\n",
	       clan_table[slot].name);
      send_to_char (buf, ch);
      return;
    }
  // notify the membership that they were disbanded
  sprintf (buf, "Clan %s`` has been disbanded by %s.\r\n",
	   clan_table[slot].name, ch->name);
  if (IS_IMMORTAL (ch))
    {
      send_clan_members (slot, buf);
    }

  else
    {
      send_clan_members_ch (ch, buf);
    }

  // notify the player of his action
  sprintf (buf, "Clan %s`` was disbanded.\r\n", clan_table[slot].name);
  send_to_char (buf, ch);
  clan_table[slot].status = CLAN_DISBAND;

  // remove every other clans relation with us and save them
  remove_clan_relations (clan_table[slot].ident);

  // for now a disband does not remove any clan symbols
  // remove_clan_symbols();
  save_clan (slot);

  // update the members to think they are not in the clan
  m = clan_table[slot].members;
  while (m)
    {
      c = find_character (m->name);
      if (c)
	{
	  if (clan_table[c->clan].ctype == CLAN_TYPE_PC)
	    c->pcdata->loner = TRUE;

	  else
	    c->pcdata->loner = FALSE;
	  c->clan = CLAN_BOGUS;
	}
      m = m->next;
    }

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_disband", ch, argument);

#endif /*  */
}


//
// Allow a leader or an immortal to name a new clan leader
//
void clan_leader (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_STRING_LENGTH];
  char arg[MAX_STRING_LENGTH];
  char arg1[MAX_STRING_LENGTH];
  CHAR_DATA *victim;
  MEMBER *m;
  int slot = 0;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_leader", ch, argument);

#endif /*  */
  argument = one_argument (argument, arg);
  one_argument (argument, arg1);

  // validate syntax
  if (arg[0] == '\0')
    {
      send_to_char ("Make whom the clan leader?\r\n", ch);
      return;
    }
  // check for a valid clan
  if (arg1[0] != '\0')
    {
      slot = clanname_to_slot (arg1);
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("No such clan exists.\n\r", ch);
	  return;
	}
    }

  else
    {
      slot = ch->clan;
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("You are not in a clan.\n\r", ch);
	  return;
	}
    }

  // is this character a leader or an imm
  if (!is_clan_leader (ch) && !IS_IMMORTAL (ch))
    {
      send_to_char ("You are not the leader of your clan.\n\r", ch);
      return;
    }
/*  if (!IS_NPC (ch))
    if ((time (NULL) - ch->pcdata->last_fight < 120) && (!IS_IMMORTAL(ch)))
      {
        send_to_char ("Hold your horses, punk.\n\r", ch);
        return;
      }*/
  
  m = find_member (clan_table[slot].members, arg);
  if (m == NULL)
    {
      sprintf (buf, "%s is not a member of clan %s``.\n\r", arg,
	       clan_table[slot].name);
      send_to_char (buf, ch);
      return;
    }
  // this is safe, because we already checked that this
  // player is in this clan
  clan_table[slot].leader->status = CLAN_DEPUTY;
  clan_table[slot].leader = m;
  clan_table[slot].leader->status = CLAN_LEADER;

  // save this update
  save_clan (slot);

  // notify the membership of their new leader
  sprintf (buf, "Clan %s`` leader is now %s.\r\n",
	   clan_table[slot].name, clan_table[slot].leader->name);
  if (IS_IMMORTAL (ch))
    {
      send_clan_members (slot, buf);
    }

  else
    {
      send_clan_members_ch (ch, buf);
    }

  // notify the individual of their demotion
  sprintf (buf,
	   "You have made %s leader of clan %s``.\r\nYou are no longer leader.\n\r",
	   clan_table[slot].leader->name, clan_table[slot].name);
  send_to_char (buf, ch);
  victim = find_character (arg);
  if (victim != NULL)
    {
      sprintf (buf, "You are now the leader of clan %s``.\n\r",
	       clan_table[slot].name);
      send_to_char (buf, victim);
    }
#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_leader", ch, argument);

#endif /*  */
}


//
// Allow a clan leader to define a new clan symbol
//
void clan_symbol (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_STRING_LENGTH];
  char arg[MAX_STRING_LENGTH];
  char arg1[MAX_STRING_LENGTH];
  int slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_symbol", ch, argument);

#endif /*  */
  argument = one_argument (argument, arg);
  one_argument (argument, arg1);

  // check for valid syntax
  if (arg[0] == '\0')
    {
      send_to_char ("Change your clan symbol to what?\n\r", ch);
      return;
    }
  // check for a valid clan
  if (arg1[0] != '\0')
    {
      slot = clanname_to_slot (arg1);
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("No such clan exists.\n\r", ch);
	  return;
	}
    }

  else
    {
      slot = ch->clan;
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("You are not in a clan.\n\r", ch);
	  return;
	}
    }

  // check for leadership rights the character must either be the clan
  // leader or it better be an imm
  if (!is_clan_leader (ch) && !IS_IMMORTAL (ch))
    {
      send_to_char ("You are not the leader of your clan.\n\r", ch);
      return;
    }
  // Abusive behaviour has made it necessary to restrict changing of clan
  // Symbols to immortals only
/*  if (!IS_IMMORTAL (ch))
    {
      send_to_char ("Talk to an immortal to make a change in clan symbol.\n\r", ch);
      return;
    }*/
  if (color_strlen (arg) > MAX_SYMB_CH)
    {
      sprintf (buf,
	       "The clan symbol must be less than %d characters.\n\r",
	       MAX_SYMB_CH);
      send_to_char (buf, ch);
      return;
    }
  if (strlen (arg) > MAX_SYMB)
    {
      send_to_char ("Try using less colors in your clan symbol.\n\r", ch);
      return;
    }
  strcpy (clan_table[slot].symbol, arg);
  save_clan (slot);
  sprintf (buf, "Clan %s`` symbol is now %s``.\r\n",
	   clan_table[slot].name, clan_table[slot].symbol);
  send_to_char (buf, ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_symbol", ch, argument);

#endif /*  */
}


// removes a member record
void clan_bye (CHAR_DATA * ch)
{
  MEMBER *m;
  int slot;
  slot = ch->clan;
  if (slot != CLAN_BOGUS)
    {
      m = clan_table[slot].members;
      clan_table[slot].members = delete_member (m, ch->name);
    }
}


//
// List clans all and hidded for immortals
//
void clan_list_imm (CHAR_DATA * ch, char *argument)
{
  int i = 0;
  int statuses = CLAN_STATUSES;
  bool found = FALSE;
  char buf[MAX_INPUT_LENGTH];

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_list_imm", ch, argument);

#endif /*  */
  if (!IS_IMMORTAL (ch))
    return;
  if (!str_cmp (argument, "hidden"))
    {
      send_to_char ("Clan list hidden:\n\r", ch);
      statuses = HIDDEN_STATUSES;
    }

  else if (!str_cmp (argument, "all"))
    {
      send_to_char ("Clan list all:\n\r", ch);
      statuses = CLAN_STATUSES;
    }

  else
    {
      send_to_char ("Options to clan list are \"hidden\" or \"all\"\n\r", ch);
      return;
    }
  if (CLANS_START < clan_number)
    {
      sprintf (buf,
	       "Name         Symbol       Leader       PK/NonPK    Status       Levels Slot\n\r");
      send_to_char (buf, ch);
    }

  else
    {
      send_to_char ("None.\n\r", ch);
      return;
    }

  // do the list in status order - see the clan_statuses const table
  for (i = 0; i < statuses; i++)
    {
      if (clan_list_status (ch, clan_statuses[i]))
	found = TRUE;
    }
  if (!found)
    send_to_char ("None.\n\r", ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_list_imm", ch, argument);

#endif /*  */
}
bool clan_list_status (CHAR_DATA * ch, int status)
{
  int i = 0;
  bool found = FALSE;
  char buf[MAX_STRING_LENGTH];
  char buf2[MAX_STRING_LENGTH];
  char symb[MAX_STRING_LENGTH];

  // now run through the clans putting stuff in the table
  for (i = CLANS_START; i < clan_number; i++)
    {
      if (clan_table[i].status == status)
	{
	  found = TRUE;
	  format_clan_symbol (i, symb, 12);
	  sprintf (buf, "%-12s`` %-12s`` %-12s %-12s",
		   clan_table[i].name, symb, clan_table[i].leader->name,
		   clan_table[i].ctype == CLAN_TYPE_PC ? "PK" : "NonPK");
	  switch (clan_table[i].status)
	    {
	    case CLAN_INACTIVE:
	      strcat (buf, "Inactive    ");
	      break;
	    case CLAN_DISBAND:
	      strcat (buf, "Disbanded   ");
	      break;
	    case CLAN_DISPERSED:
	      strcat (buf, "Dispersed   ");
	      break;
	    case CLAN_PROPOSED:
	      strcat (buf, "Proposed    ");
	      break;
	    case CLAN_RESTRICTED:
	      strcat (buf, "Restricted  ");
	      break;
	    case CLAN_HISTORICAL:
	      strcat (buf, "Historical  ");
	      break;
	    case CLAN_ACTIVE:
	      strcat (buf, "Active      ");
	      break;
	    default:
	      strcat (buf, "Unknown     ");
	      break;
	    }
	  if (IS_IMMORTAL (ch))
	    {
	      sprintf (buf2, "%s %6d [%2d]\n\r", buf,
		       clan_table[i].levels, i);
	    }

	  else
	    {

	      // regular characters do not get the extra status information
	      sprintf (buf2, "%s\n\r", buf);
	    }
	  send_to_char (buf2, ch);
	}
    }
  return (found);
}


//
// Allow immortals to reactivate a clan that was deactivated
//
void clan_activate (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_INPUT_LENGTH];
  char clan_name[MAX_INPUT_LENGTH];
  MEMBER *m = NULL;
  MEMBER *list = NULL;
  CHAR_DATA *c = NULL;
  bool found = FALSE;
  int i = 0;
  int slot = 0;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_activate", ch, argument);

#endif /*  */
  if (!IS_IMMORTAL (ch))
    return;
  argument = one_argument (argument, clan_name);

  // check for a valid clan
  if (clan_name[0] == '\0')
    {
      send_to_char ("You must specify a clan to reactivate.\n\r", ch);
      return;
    }
  slot = clanname_to_slot (clan_name);
  if (slot == CLAN_BOGUS)
    {
      sprintf (buf, "There is no clan named %s``.\n\r",
	       capitalize (clan_name));
      send_to_char (buf, ch);
      return;
    }
  if (clan_table[slot].status < CLAN_PROPOSED)
    {

      // ok, make the clan active - but because the membership has not
      // been managed, we need to check the consistency of the membership
      // First, we'll just dump all applicants
      list = clan_table[slot].applicants;
      clan_table[slot].applicants = NULL;
      m = list;
      while (m)
	{
	  list = m->next;
	  m->next = NULL;
	  free (m);
	  m = list;
	}

      // scan the members list and see if any of them are members in another
      // clan - if they are members else where then remove them from this
      // clans membership list
      list = clan_table[slot].members;
      clan_table[slot].members = NULL;
      m = list;
      while (m)
	{
	  list = m->next;
	  m->next = NULL;

	  // check all of the existing clans to see if this guy is a member
	  // of any of them -- ignore the clan we are currently fixing
	  i = CLANS_START;
	  while ((i < clan_number) && m)
	    {
	      if (i != slot)
		{
		  if (find_member (clan_table[i].members, m->name))
		    {

		      // ok, m has already switched to another clan
		      free (m);
		      m = NULL;
		    }
		}
	      i++;
	    }

	  // if m != NULL then they guy is *not* in another clan,
	  // so add him to the members list of this clan
	  if (m)
	    {
	      clan_table[slot].members =
		append_member (clan_table[slot].members, m);
	    }
	  m = list;
	}

      // now make one of the clan members the leader
      clan_table[slot].leader = NULL;
      m = clan_table[slot].members;
      while (m && !found)
	{
	  if (m->status == CLAN_LEADER)
	    {
	      found = TRUE;
	    }

	  else
	    {
	      m = m->next;
	    }
	}

      // if we found the clan leader great, if we didn't find him then he
      // joined another clan, just pick the first member in the list and make
      // that guy the clan leader -- an imm can fix it using the leader command
      if (found)
	{
	  clan_table[slot].leader = m;
	}

      else
	{
	  clan_table[slot].leader = clan_table[slot].members;
	  clan_table[slot].leader->status = CLAN_LEADER;
	}

      // finally, don't actually make the clan active yet, keep it restricted
      // and hope they accept a new member or something to fix up the levels
      clan_table[slot].status = CLAN_RESTRICTED;
      save_clan (slot);

      // run through all of the members, if we find one on-line update them
      m = clan_table[slot].members;
      while (m)
	{
	  c = find_character (m->name);
	  if (c)
	    c->clan = slot;
	  m = m->next;
	}
      sprintf (buf,
	       "Clan %s`` was resurected to a restricted status.\n\r",
	       clan_table[slot].name);
      send_to_char (buf, ch);
      sprintf (buf, "Member %s was made leader of clan %s``.\n\r",
	       clan_table[slot].leader->name, clan_table[slot].name);
      send_to_char (buf, ch);
    }

  else if (clan_table[slot].status < CLAN_ACTIVE)
    {

      // the membership has already been under appropriate restrictions
      // will allow the imms to promote a clan temporarily for some reason
      clan_table[slot].status = CLAN_ACTIVE;
      sprintf (buf,
	       "Clan %s`` was temporarily promoted to active status.\n\r",
	       clan_table[slot].name);
      send_to_char (buf, ch);
    }

  else
    {
      sprintf (buf, "Clan %s`` is already an active clan.\n\r",
	       clan_table[slot].name);
      send_to_char (buf, ch);
    }

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_activate", ch, argument);

#endif /*  */
}
void clan_altar (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_INPUT_LENGTH];
  char name[MAX_INPUT_LENGTH];
  int slot;

#ifdef VERBOSE_CLANS
  log_player_command ("s:clan_altar", ch, argument);

#endif /*  */
  if (IS_IMMORTAL (ch))
    {
      argument = one_argument (argument, name);

      // check for a valid clan
      if (name[0] == '\0')
	{
	  send_to_char
	    ("You must specify a clan to set their altar.\n\r", ch);
	  return;
	}
      slot = clanname_to_slot (name);
      if (slot == CLAN_BOGUS)
	{
	  sprintf (buf, "There is no clan named %s``.\n\r",
		   capitalize (name));
	  send_to_char (buf, ch);
	  return;
	}
      if (clan_table[slot].status < CLAN_PROPOSED)
	{
	  sprintf (buf, "Clan %s`` is not an active clan.\n\r",
		   clan_table[slot].name);
	  send_to_char (buf, ch);
	  return;
	}
    }

  else
    {
      slot = ch->clan;
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("You are not currently in a clan.\n\r", ch);
	  return;
	}
      if (!is_clan_leader (ch))
	{
	  send_to_char
	    ("You must be a clan leader to set the clan altar.\n\r", ch);
	  return;
	}
      if (clan_table[slot].hall != ROOM_VNUM_ALTAR)
	{
	  send_to_char ("You have already set your clan altar.\n\r", ch);
	  return;
	}
      if (ch->in_room->clan != slot)
	{
	  sprintf (buf, "This room is not owned by clan %s``.",
		   clan_table[slot].name);
	  send_to_char (buf, ch);
	  return;
	}
    }

  // get the vnum of this room and save the clan
  clan_table[slot].hall = ch->in_room->vnum;
  save_clan (slot);
  sprintf (buf, "You invoke spirits, opening a passage to the netherworld.");
  send_to_char (buf, ch);
  sprintf (buf, "Your make %s`` your clan altar.", ch->in_room->name);
  send_to_char (buf, ch);

#ifdef VERBOSE_CLANS
  log_player_command ("f:clan_altar", ch, argument);

#endif /*  */
}
void clan_short_status (CHAR_DATA * ch, char *argument)
{
  char buf[MAX_INPUT_LENGTH];
  char name[MAX_INPUT_LENGTH];
  int slot;
  argument = one_argument (argument, name);

  // check for a valid clan
  if (name[0] == '\0')
    {
      slot = ch->clan;
      if (slot == CLAN_BOGUS)
	{
	  send_to_char ("You are not currently in a clan.\n\r", ch);
	  return;
	}
    }

  else
    {
      slot = clanname_to_slot (name);
      if (slot == CLAN_BOGUS)
	{
	  sprintf (buf, "There is no clan named %s``.\n\r",
		   capitalize (name));
	  send_to_char (buf, ch);
	  return;
	}
    }
  switch (clan_table[slot].status)
    {
    case CLAN_INACTIVE:
      sprintf (buf, "Clan %s`` is currently inactive.\n\r",
	       clan_table[slot].name);
      break;
    case CLAN_DISBAND:
      sprintf (buf, "Clan %s`` is currently disbanded.\n\r",
	       clan_table[slot].name);
      break;
    case CLAN_DISPERSED:
      sprintf (buf, "Clan %s`` is currently dispersed.\n\r",
	       clan_table[slot].name);
      break;
    case CLAN_PROPOSED:
      sprintf (buf, "Clan %s`` is currently proposed.\n\r",
	       clan_table[slot].name);
      break;
    case CLAN_RESTRICTED:
      sprintf (buf, "Clan %s`` is currently restricted.\n\r",
	       clan_table[slot].name);
      break;
    case CLAN_HISTORICAL:
      sprintf (buf, "Clan %s`` is a historically significant clan.\n\r",
	       clan_table[slot].name);
      break;
    case CLAN_ACTIVE:
      sprintf (buf, "Clan %s`` is currently active.\n\r",
	       clan_table[slot].name);
      break;
    default:
      sprintf (buf, "Clan %s`` is currently <status_unknown>.\n\r",
	       clan_table[slot].name);
      break;
    }
  send_to_char (buf, ch);
}
void list_allies (CHAR_DATA * ch, int slot)
{
  RELATIONS *r;
  int cnt = 0;
  bool found = FALSE;
  char outbuf[MAX_STRING_LENGTH * 2];

  // list off the allies
  sprintf (outbuf, "Allies of clan %s``:\n\r", clan_table[slot].name);
  r = clan_table[slot].relations;
  while (r)
    {
      if (r->status == CLAN_ALLY)
	{

	  // ok, we marked them as an ally, did they also mark us as an ally?
	  if (is_requested_ally (clanident_to_slot (r->ident), slot))
	    {

	      // if then are in the clan, let them know if the other clan is
	      // a full ally or just a friend
	      if ((ch->clan == slot) || IS_IMMORTAL (ch))
		{
		  sprintf (outbuf + strlen (outbuf), "A: %-12s``", r->name);
		}

	      else
		{
		  sprintf (outbuf + strlen (outbuf), "%-15s``", r->name);
		}
	      cnt++;
	      found = TRUE;

	      // every three clans go to a new line
	      if (cnt % 3 == 0)
		strcat (outbuf, "\n\r");
	    }

	  else
	    {

	      // only tell friend status to people in this clan
	      if ((ch->clan == slot) || IS_IMMORTAL (ch))
		{
		  sprintf (outbuf + strlen (outbuf), "F: %-12s``", r->name);
		  cnt++;
		  found = TRUE;

		  // every three clans go to a new line
		  if (cnt % 3 == 0)
		    strcat (outbuf, "\n\r");
		}
	    }
	}
      r = r->next;
    }
  if (!found)
    strcat (outbuf, "None.");
  strcat (outbuf, "\n\r");
  page_to_char (outbuf, ch);
}
void list_enemies (CHAR_DATA * ch, int slot)
{
  RELATIONS *r;
  int cnt = 0;
  bool found = FALSE;
  char outbuf[MAX_STRING_LENGTH * 2];

  // list off the enemies of this clan
  sprintf (outbuf, "Enemies of clan %s``:\n\r", clan_table[slot].name);
  r = clan_table[slot].relations;
  while (r)
    {
      if (r->status == CLAN_ENEMY)
	{

	  // we have marked them as an enemy of us
	  if (is_requested_enemy (clanident_to_slot (r->ident), slot))
	    {

	      // they also marked us as an enemy of them
	      if ((ch->clan == slot) || IS_IMMORTAL (ch))
		{
		  sprintf (outbuf + strlen (outbuf), "E: %-12s``", r->name);
		}

	      else
		{
		  sprintf (outbuf + strlen (outbuf), "%-15s``", r->name);
		}
	      cnt++;
	      found = TRUE;

	      // every three clans go to a new line
	      if (cnt % 3 == 0)
		strcat (outbuf, "\n\r");
	    }

	  else
	    {

	      // only tell hostile status to people in this clan
	      if ((ch->clan == slot) || IS_IMMORTAL (ch))
		{
		  sprintf (outbuf + strlen (outbuf), "H: %-12s``", r->name);
		  cnt++;
		  found = TRUE;

		  // every three clans go to a new line
		  if (cnt % 3 == 0)
		    strcat (outbuf, "\n\r");
		}
	    }
	}

      else if (r->status >= CLAN_WAR)
	{

	  // actually it's worse there is a war going on
	  if ((ch->clan == slot) || IS_IMMORTAL (ch))
	    {

	      // only be explicit to members of this clan
	      sprintf (outbuf + strlen (outbuf), "W: %-12s``", r->name);
	    }

	  else
	    {

	      // not a member then you just see a name
	      sprintf (outbuf + strlen (outbuf), "%-15s``", r->name);
	    }
	  cnt++;
	  found = TRUE;

	  // every three clans go to a new line
	  if (cnt % 3 == 0)
	    strcat (outbuf, "\n\r");
	}
      r = r->next;
    }
  if (!found)
    strcat (outbuf, "None.");
  strcat (outbuf, "\n\r");
  page_to_char (outbuf, ch);
}


// remove this clans relations with all the other clans
void remove_clan_relations (int ident)
{
  int i;
  for (i = CLANS_START; i < clan_number; i++)
    {
      clan_table[i].relations =
	delete_relation (clan_table[i].relations, ident);
      save_clan (i);
    }
}