6D/
6D/area/
6D/boards/
6D/city/
6D/color/
6D/corpses/
6D/councils/
6D/htowns/
6D/news/
6D/specials/
6D/src/specials/
6D/src/trades/
 /*
  * Yet another attempt to write a decent hometown code - Vladaar 
  */

#include "h/mud.h"
#include "h/files.h"
#include "h/hometowns.h"
#include "h/key.h"

HTOWN_DATA             *first_htown;
HTOWN_DATA             *last_htown;

/* local routines */
void                    fread_htown(HTOWN_DATA * htown, FILE * fp);
extern bool             load_htown_file(const char *htownfile);
void                    write_htown_list(void);

HTOWN_DATA             *get_htown(const char *name)
{
  HTOWN_DATA             *htown;

  for(htown = first_htown; htown; htown = htown->next)
    if(!str_cmp(name, htown->name))
      return htown;
  return NULL;
}

void write_htown_list(void)
{
  HTOWN_DATA             *thtown;
  FILE                   *fpout;
  char                    filename[256];

  snprintf(filename, 256, "%s%s", HTOWN_DIR, HTOWN_LIST);
  fpout = FileOpen(filename, "w");
  if(!fpout)
  {
    bug("FATAL: cannot open %s for writing!\r\n", filename);
    perror(filename);
    return;
  }
  for(thtown = first_htown; thtown; thtown = thtown->next)
    fprintf(fpout, "%s\n", thtown->filename);
  fprintf(fpout, "$\n");
  FileClose(fpout);
  return;
}

/* Save a htown's data to its data file */
void save_htown(HTOWN_DATA * htown)
{
  FILE                   *fp;
  char                    filename[256];

  if(!htown)
  {
    bug("%s", "save_htown: null htown pointer!");
    return;
  }
  if(!VLD_STR(htown->filename))
  {
    bug("save_htown: %s has no filename", htown->name);
    return;
  }
  snprintf(filename, 256, "%s%s", HTOWN_DIR, htown->filename);
  if((fp = FileOpen(filename, "w")) == NULL)
  {
    bug("save_htown: can't open %s for writing.", filename);
    perror(filename);
  }
  else
  {
    fprintf(fp, "#HTOWN\n");
    if(VLD_STR(htown->name))
      fprintf(fp, "Name        %s~\n", htown->name);
    if(VLD_STR(htown->filename))
      fprintf(fp, "Filename    %s~\n", htown->filename);
    if(VLD_STR(htown->description))
      fprintf(fp, "Description %s~\n", htown->description);
    if(VLD_STR(htown->ruler))
      fprintf(fp, "Ruler       %s~\n", htown->ruler);
    if(VLD_STR(htown->general))
      fprintf(fp, "General     %s~\n", htown->general);
    if(VLD_STR(htown->nation))
      fprintf(fp, "Nation      %s~\n", htown->nation);
    fprintf(fp, "Members     %d\n", htown->members);
    fprintf(fp, "Temple      %d\n", htown->temple);
    fprintf(fp, "Startroom   %d\n", htown->startroom);
    fprintf(fp, "Recall      %d\n", htown->recall);
    if(VLD_STR(htown->race))
      fprintf(fp, "Race        %s~\n", htown->race);
    fprintf(fp, "End\n\n");
    fprintf(fp, "#END\n");
  }
  FileClose(fp);
  return;
}

/* Read in actual htown data. */
void fread_htown(HTOWN_DATA * htown, FILE * fp)
{
  const char             *word;
  bool                    fMatch;

  for(;;)
  {
    word = feof(fp) ? "End" : fread_word(fp);
    fMatch = FALSE;

    switch (UPPER(word[0]))
    {
      case '*':
        fMatch = TRUE;
        fread_to_eol(fp);
        break;
      case 'D':
        KEY("Description", htown->description, fread_string(fp));
        break;
      case 'E':
        if(!str_cmp(word, "End"))
          return;
        break;
      case 'F':
        KEY("Filename", htown->filename, fread_string(fp));
        break;
      case 'G':
        KEY("General", htown->general, fread_string(fp));
        break;
      case 'M':
        KEY("Members", htown->members, fread_number(fp));
        break;
      case 'N':
        KEY("Name", htown->name, fread_string(fp));
        KEY("Nation", htown->nation, fread_string(fp));
        break;
      case 'R':
        KEY("Race", htown->race, fread_string(fp));
        KEY("Recall", htown->recall, fread_number(fp));
        KEY("Ruler", htown->ruler, fread_string(fp));
        break;
      case 'S':
        KEY("Startroom", htown->startroom, fread_number(fp));
      case 'T':
        KEY("Temple", htown->temple, fread_number(fp));
    }
    if(!fMatch)
    {
      bug("Fread_htown: no match: %s", word);
      fread_to_eol(fp);
    }
  }
}

/* Load a htown file */
bool load_htown_file(const char *htownfile)
{
  char                    filename[256];
  HTOWN_DATA             *htown;
  FILE                   *fp;
  bool                    found;

  CREATE(htown, HTOWN_DATA, 1);
  found = FALSE;
  snprintf(filename, 256, "%s%s", HTOWN_DIR, htownfile);
  if((fp = FileOpen(filename, "r")) != NULL)
  {
    found = TRUE;
    for(;;)
    {
      char                    letter;
      char                   *word;

      letter = fread_letter(fp);
      if(letter == '*')
      {
        fread_to_eol(fp);
        continue;
      }
      if(letter != '#')
      {
        bug("%s", "Load_htown_file: # not found.");
        break;
      }
      word = fread_word(fp);
      if(!str_cmp(word, "HTOWN"))
      {
        fread_htown(htown, fp);
        break;
      }
      else if(!str_cmp(word, "END"))
        break;
      else
      {
        bug("%s", "Load_htown_file: bad section.");
        break;
      }
    }
    FileClose(fp);
  }
  if(found)
    LINK(htown, first_htown, last_htown, next, prev);
  else
    DISPOSE(htown);
  return found;
}

/* Load in all the htown files. */
void load_htowns()
{
  FILE                   *fpList;
  const char             *filename;
  char                    htownlist[256];

  first_htown = NULL;
  last_htown = NULL;
  log_string("Loading htowns...");
  snprintf(htownlist, 256, "%s%s", HTOWN_DIR, HTOWN_LIST);
  if((fpList = FileOpen(htownlist, "r")) == NULL)
  {
    bug("load_htowns: can't open %s for reading.", htownlist);
    perror(htownlist);
    exit(1);
  }
  for(;;)
  {
    filename = feof(fpList) ? "$" : fread_word(fpList);
    log_string(filename);
    if(filename[0] == '$')
      break;
    if(!load_htown_file(filename))
      bug("Cannot load htown file: %s", filename);
  }
  FileClose(fpList);
  log_string(" Done htowns ");
  return;
}

void do_htown_outcast(CHAR_DATA *ch, char *argument)
{
  char                    arg[MIL];
  CHAR_DATA              *victim;
  HTOWN_DATA             *htown;

  if(IS_NPC(ch))
  {
    send_to_char("Huh?\r\n", ch);
    return;
  }
  htown = ch->pcdata->htown;
  if((htown->ruler == NULL || str_cmp(ch->name, htown->ruler)) && (htown->general == NULL || str_cmp(ch->name, htown->general)))
  {
    send_to_char("Huh?\r\n", ch);
    return;
  }
  argument = one_argument(argument, arg);
  if(!VLD_STR(arg))
  {
    send_to_char("Outcast whom from your htown?\r\n", ch);
    return;
  }
  if((victim = get_char_room(ch, arg)) == NULL)
  {
    send_to_char("That player is not here.\r\n", ch);
    return;
  }
  if(IS_NPC(victim))
  {
    send_to_char("Not on NPC's.\r\n", ch);
    return;
  }
  if(victim == ch)
  {
    send_to_char("Kick yourself out of your own htown?\r\n", ch);
    return;
  }
  if(victim->pcdata->htown != ch->pcdata->htown)
  {
    send_to_char("This player does not belong to your htown!\r\n", ch);
    return;
  }
  --htown->members;
  victim->pcdata->htown = NULL;
  if(VLD_STR(victim->pcdata->htown_name))
    STRFREE(victim->pcdata->htown_name);
  act(AT_MAGIC, "You outcast $N from $t", ch, htown->name, victim, TO_CHAR);
  act(AT_MAGIC, "$n outcasts $N from $t", ch, htown->name, victim, TO_ROOM);
  act(AT_MAGIC, "$n outcasts you from $t", ch, htown->name, victim, TO_VICT);
  save_char_obj(victim);
  save_htown(htown);
  return;
}

void do_sethtown(CHAR_DATA *ch, char *argument)
{
  char                    arg1[MIL];
  char                    arg2[MIL];
  HTOWN_DATA             *htown;

  set_char_color(AT_PLAIN, ch);
  if(IS_NPC(ch))
  {
    send_to_char("Huh?\r\n", ch);
    return;
  }
  argument = one_argument(argument, arg1);
  argument = one_argument(argument, arg2);
  if(!VLD_STR(arg1))
  {
    send_to_char("Usage: sethtown <htown> <field> <player>\r\n", ch);
    send_to_char("\r\nField being one of:\r\n", ch);
    send_to_char(" ruler general members recall race desc\r\n", ch);
    send_to_char(" startroom temple name filename nation\r\n", ch);
    return;
  }
  htown = get_htown(arg1);
  if(!htown)
  {
    send_to_char("No such htown.\r\n", ch);
    return;
  }
  if(!str_cmp(arg2, "ruler"))
  {
    if(VLD_STR(htown->ruler))
      STRFREE(htown->ruler);
    if(VLD_STR(argument))
      htown->ruler = STRALLOC(argument);
  }
  else if(!str_cmp(arg2, "general"))
  {
    if(VLD_STR(htown->general))
      STRFREE(htown->general);
    if(VLD_STR(argument))
      htown->general = STRALLOC(argument);
  }
  else if(!str_cmp(arg2, "nation"))
  {
    if(VLD_STR(htown->nation))
      STRFREE(htown->nation);
    if(VLD_STR(argument))
      htown->nation = STRALLOC(argument);
  }
  else if(!str_cmp(arg2, "members"))
    htown->members = atoi(argument);
  else if(!str_cmp(arg2, "recall"))
    htown->recall = atoi(argument);
  else if(!str_cmp(arg2, "startroom"))
    htown->startroom = atoi(argument);
  else if(!str_cmp(arg2, "temple"))
    htown->temple = atoi(argument);
  else if(get_trust(ch) < LEVEL_IMMORTAL)
  {
    do_sethtown(ch, (char *)"");
    return;
  }
  else if(!str_cmp(arg2, "name"))
  {
    if(VLD_STR(htown->name))
      STRFREE(htown->name);
    if(VLD_STR(argument))
      htown->name = STRALLOC(argument);
  }
  else if(!str_cmp(arg2, "filename"))
  {
    if(VLD_STR(htown->filename))
      STRFREE(htown->filename);
    if(VLD_STR(argument))
      htown->filename = STRALLOC(argument);
    write_htown_list();
  }
  else if(!str_cmp(arg2, "desc"))
  {
    if(VLD_STR(htown->description))
      STRFREE(htown->description);
    if(VLD_STR(argument))
      htown->description = STRALLOC(argument);
  }
  else if(get_trust(ch) < LEVEL_AJ_CPL)
  {
    do_sethtown(ch, (char *)"");
    return;
  }
  else if(!str_cmp(arg2, "race"))
  {
    if(VLD_STR(htown->race))
      STRFREE(htown->race);
    if(VLD_STR(argument))
      htown->race = STRALLOC(argument);
  }
  else
  {
    do_sethtown(ch, (char *)"");
    return;
  }
  send_to_char("Done.\r\n", ch);
  save_htown(htown);
  return;
}

void do_showhtown(CHAR_DATA *ch, char *argument)
{
  HTOWN_DATA             *htown;

  set_char_color(AT_PLAIN, ch);
  if(IS_NPC(ch))
  {
    send_to_char("Huh?\r\n", ch);
    return;
  }
  if(!VLD_STR(argument))
  {
    send_to_char("Usage: showhtown <htown>\r\n", ch);
    return;
  }
  htown = get_htown(argument);
  if(!htown)
  {
    send_to_char("No such htown.\r\n", ch);
    return;
  }
  ch_printf(ch, "\r\n&wHometown: &W%s\r\n&wFilename:  &W%s\r\n", htown->name, htown->filename);
  ch_printf(ch, "&wNation:       &W%s\r\n", htown->nation);
  ch_printf(ch, "&wRuler:        &W%s\r\n", htown->ruler);
  ch_printf(ch, "&wGeneral:      &W%s\r\n", htown->general);
  ch_printf(ch, "&wMembers:      &W%-d\r\n", htown->members);
  ch_printf(ch, "&wRecall:       &W%-5d\r\n&wRace:         &W%s\r\n", htown->recall, capitalize(htown->race));
  ch_printf(ch, "&wStartroom:    &W%-5d\r\n&wTemple:       &W%-5d\r\n", htown->startroom, htown->temple);
  ch_printf(ch, "&wDescription:\r\n&W%s\r\n", htown->description);
  return;
}

void do_makehtown(CHAR_DATA *ch, char *argument)
{
  char                    filename[256];
  HTOWN_DATA             *htown;
  bool                    found;

  set_char_color(AT_IMMORT, ch);
  if(!VLD_STR(argument))
  {
    send_to_char("Usage: makehtown <htown name>\r\n", ch);
    return;
  }
  found = FALSE;
  snprintf(filename, 256, "%s%s", HTOWN_DIR, strlower(argument));
  CREATE(htown, HTOWN_DATA, 1);
  LINK(htown, first_htown, last_htown, next, prev);
  htown->name = STRALLOC(argument);
  send_to_char("htown now made.\r\n", ch);
}

void do_htowns(CHAR_DATA *ch, char *argument)
{
  HTOWN_DATA             *htown;

  set_char_color(AT_CYAN, ch);
  if(!first_htown)
  {
    send_to_char("There are no htowns currently formed.\r\n", ch);
    return;
  }
  if(!VLD_STR(argument))
  {
    send_to_char("\r\n&WCurrent Home Towns Available in the &R6 Dragons &Wrealms\r\n", ch);
    send_to_char("&c----------------------------------------------------------------------------\r\n", ch);
    send_to_char("\r\n&cHome Town                Nation               Ruler             General\r\n", ch);
    for(htown = first_htown; htown; htown = htown->next)
      ch_printf(ch, "&C%-24s %-20s %-17s %-12s\r\n", htown->name, htown->nation, htown->ruler, htown->general);
    send_to_char("\r\n&cUse '&Whtowns &c<&Wname of htown&c>' for more detailed information.\r\n", ch);
    return;
  }
  htown = get_htown(argument);
  if(!htown)
  {
    send_to_char("&cNo such htown exists...\r\n", ch);
    return;
  }
  ch_printf(ch, "&c\r\n%s\r\n", htown->name);
  ch_printf(ch,
            "&cRuler:     &w%s\r\n&cGeneral:   &w%s\r\n&cRace:       &w%s\r\n&cNation   &w%s\r\n&cMembers:   &w%d\r\n",
            htown->ruler, htown->general, capitalize(htown->race), htown->nation, htown->members);
  ch_printf(ch, "&cDescription:\r\n&w%s\r\n", htown->description);
  return;
}