Logo Search packages:      
Sourcecode: aime version File versions  Download package

mud.cpp

/**********************************************************************
 ** Mud class function: These functions manipulate the high level mud
 **                     items like loading the mud into memory and
 **                     opening the listening socket. When you create
 **                     this class it more or less creates the entire
 **                     mud.
 **
 ** Reviewed through: version 0.14
 **
 **
 ** Copyright (C) 2000 George Noel (Slate), Ed Boraas
 **
 **   This program is free software; you can redistribute it and/or modify
 **   it under the terms of the GNU General Public License as
 **   published by the Free Software Foundation; either version 2 of the 
 **   License, or any later version. 
 **
 **   This program is distributed in the hope that it will be useful, but 
 **   WITHOUT ANY WARRANTY; without even the implied warranty of 
 **   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 **   General Public License for more details. 
 ** 
 **   You should have received a copy of the GNU General Public License 
 **   along with this program (in the docs dir); if not, write to the Free
 **   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 **
 **********************************************************************/

#ifndef MUD_C
#define MUD_C

#include "config.h"
#include "sysdep.h"
#include "objtype.h"
#include "strings.h"
#include "mudtypes.h"
#include "mudobject.h"
#include "location.h"
#include "individual.h"
#ifdef WIN32
#include "../win32/winconnection.h"
#else
#include "connection.h"
#endif
#include "player.h"
#include "verb.h"
#include "verbs.h"
#include "verb_list.h"
#include "lexer.h"
#include "btree.h"
#include "area_dbase.h"
#include "logs.h"
#include "errlog.h"
#include "syslog.h"
#include "object_list.h"
#ifdef WIN32
#include "../win32/winport.h"
#include "../win32/Aime_w32.h"
#include "../win32/Aime_w32Dlg.h"
#include "../win32/AskConvert.h"
#include "../win32/Converter.h"
#else
#include "port.h"
#endif
#include "mud.h"
#include "global.h"
#include "timespan.h"
#include "mobile.h"
#include "gameflags.h"
#include "syslog.h"
#include "adminflags.h"
#include "locflags.h"
#include "code.h"
#include "indflags.h"
#include "specials.h"
#include "marker.h"
#include "door.h"
#include "moveable.h"
#include "key.h"
#include "pager.h"
#include "book.h"
#include "merger.h"
#include "money.h"
#include "weapon.h"
#include "wearable.h"
#include "food.h"
#include "entity.h"
#include "data_log.h"
#include "rope.h"
#include "level_list.h"
#include "newfuncts.h"
#include "memchk.h"
#include "race.h"
#include "inclination.h"
#include "talent.h"
#include "utils.h"
#include "mask.h"
#include "access_list.h"
#include "user_dbase.h"
#include "lineflags.h"
#include "chatline.h"
#include "action.h"

#ifdef WIN32
extern CAime_w32Dlg *main_dlg;
#endif

/***********************************************************************
 ** Mud (constructor) - Starts up the mud, booting up the system and
 **                     opening up a listening socket for accepting
 **                     connections
 **
 ** Paramters: None
 **
 ** Returns: Nothing
 **
 ***********************************************************************/

Mud::Mud(bool quiet_mode)
{

   /* turn off shutdown */
   shutdwn = 0;
   boot_locked = 0;
   srand(time(0));

   status = STAT_FRESH;

   /* create the hostname string */
   player_list = NULL;
   builder_list = NULL;
   fight_list = NULL;
   cur_fighter = NULL;

#ifndef WIN32 
   startup(quiet_mode);
#endif

   time_of_day = Dawn;

   max_cycle = avg_cycle = num_cycle = 0;
   min_cycle = 10000;
   lagged_cycle = 0;
   combined_ports = FALSE;
}

/***********************************************************************
 ** startup_stage - starts up a particular stage of the startup sequence
 **
 ** Paramters: stage - the stage to start up
 **            quiet_mode - if we should display output
 **
 ** Returns: -1 for failed, 1 for success
 **
 ***********************************************************************/

int Mud::startup_stage(int stage, bool quiet_mode)
{
  unsigned short int the_port;

  switch(stage)
  {
     case STAGE_ERRLOG:
       error_log = new_ErrLog();
       break;

     case STAGE_SYSLOG:
       sys_log = new_SysLog();
       break;

     case STAGE_SUGGLOG:
       suggest_log = new_Data_Log("Suggestions Log", SUGGESTLOGNAME);
       break;

     case STAGE_BUGLOG:
       bug_log = new_Data_Log("Bug Log", BUGLOGNAME);
       break;

     case STAGE_TYPOLOG:
       typo_log = new_Data_Log("Typo Log", TYPOLOGNAME);
       break;

     case STAGE_BOOTSTRAP:
       if (bootstrap(quiet_mode) <= 0)
       return -1;
       break;

     case STAGE_USERDBASE:
       user_database = new_User_Dbase();
       break;

     case STAGE_GAMEPORT:
       the_port = the_config.gameport;
       game_port = new_Port(the_port, quiet_mode);
       if (!game_port->is_valid())
       {
                  sysmessage("Error opening game port.\n");
                  return -1;
       }
       break;

     case STAGE_BUILDPORT:
       the_port = the_config.buildport;

         // Check if the game port and builder port are identical
         if (the_port == the_config.gameport)
         {
                  sysmessage("Builder Port combined with Game Port.\r\n");
                  combined_ports = TRUE;
                  break;
         }

       build_port = new_Port(the_port, quiet_mode);
       if (!build_port->is_valid())
       {
                   sysmessage("Error opening builder port.\n");
                   return -1;
       }
       break;

     case STAGE_ACCESSLIST:
       builder_access_list = new_Access_List(BLDR_ACCESS_NAME);
       game_access_list = new_Access_List(GAME_ACCESS_NAME);
       break;

     default:
       break;
  }
  return 1;
}

/***********************************************************************
 ** startup - starts up the mud and establishes connections
 **
 ** Paramters: quiet_mode - if we should display output
 **
 ** Returns: Nothing
 **
 ***********************************************************************/

void Mud::startup(bool quiet_mode)
{
  for (int i=0; i<=STAGE_ACCESSLIST; i++)
  {
    if (startup_stage(i, quiet_mode) == -1)
      exit(0);
  }
}

/***********************************************************************
 ** -Mud (destructor) - Closes down the mud
 **
 ** Parameters: None
 **
 ** Returns: Nothing
 **
 ***********************************************************************/

Mud::~Mud(void)
{
#ifndef WIN32   
   /* first close the listening port */
   shutdown_stage(STAGE_GAMEPORT);
   shutdown_stage(STAGE_BUILDPORT);

   /* remove all players and builders */
   shutdown_stage(STAGE_ACCESSLIST);

   shutdown_stage(STAGE_USERDBASE);

   /* close down the mudobject database */
   shutdown_stage(STAGE_BOOTSTRAP);

   shutdown_stage(STAGE_TYPOLOG);
   shutdown_stage(STAGE_SUGGLOG);
   shutdown_stage(STAGE_BUGLOG);
   shutdown_stage(STAGE_SYSLOG);
   shutdown_stage(STAGE_ERRLOG);

#endif

   // Free all tokens so we don't have memory leaks on closing
   free_all();
}

/***********************************************************************
 ** shutdown_stage - shuts down the particular stage, cleaning things up
 **
 ** Parameters: stage - the stage we should shut down
 **
 ** Returns: 1 if successful
 **
 ***********************************************************************/

int Mud::shutdown_stage(int stage)
{

  switch(stage)
  {
     case STAGE_ERRLOG:
       delete_ErrLog(error_log);
       break;

     case STAGE_SYSLOG:
       delete_SysLog(sys_log);
       break;

     case STAGE_SUGGLOG:
       delete_Data_Log(suggest_log);
       break;

     case STAGE_BUGLOG:
       delete_Data_Log(bug_log);
       break;

     case STAGE_TYPOLOG:
       delete_Data_Log(typo_log);
       break;

     case STAGE_BOOTSTRAP:
       shutdown_mud();
       break;

     case STAGE_USERDBASE:
       remove_all_players();
       remove_all_builders();
       delete_User_Dbase(user_database);
       break;

     case STAGE_GAMEPORT:
       delete_Port(game_port);
         break;

     case STAGE_BUILDPORT:
         if (combined_ports)
               break;
       delete_Port(build_port);
         break;

     case STAGE_ACCESSLIST:
       delete_Access_List(builder_access_list);
       delete_Access_List(game_access_list);
       break;

    default:
      break;
  }
  return 1;
}


/***********************************************************************
 ** bootstrap - loads all mud data into memory, and configures the mud
 ** (private)   for gameplay
 **
 ** Parameters: quiet_mode - bootstrap quietly, with no output?
 **
 ** Returns: 1 for success
 **
 **
 ***********************************************************************/

int Mud::bootstrap(bool quiet_mode)
{
   int i;

   if (!quiet_mode)
   {
      sysmessage("Bootstrapping\n");
      fflush(stdout);
   }

   for (i=(status+1); i<=STAT_GAMEREADY; i++)
   {
      if (bootstrap(quiet_mode, i) == -1)
      return -1;
   } 

   if (!quiet_mode)
   {
     sysmessage("Mud loaded\n");
   }
   status = i;
   return 1;
}


/***********************************************************************
 ** bootstrap - loads all mud data into memory, and configures the mud
 ** (private)   for gameplay
 **
 ** Parameters: quiet_mode - bootstrap quietly, with no output?
 **             stage - the stage we are to bootstrap
 **
 ** Returns: 1 for success, 0 for locked
 **
 **
 ***********************************************************************/

int Mud::bootstrap(bool quiet_mode, int stage)
{
   Strings failed_on;
   Strings holder;
   int stage_complete = 0;

   if (boot_locked)
      return 0;

   boot_locked = 1;
#ifdef WIN32
  char *newline = "\r\n";
#else
  char *newline = "\n";
#endif

  switch(stage)
  {
     case STAT_GAMEPLAY:
       if (!quiet_mode)
       {
            sysmessage("\tLoading gameplay data...");
       }

       if (load_game_data(error_log) == -2)
       {
#ifndef WIN32
            char answer[5];

            BZERO(answer, 5);
            sysmessage("Game data file does not exist, create? (y/n)  ");
            fgets(answer, 4, stdin);
            if (answer[0] == 'y')
              {
#endif
               set_tod(Dawn);
               day_of_year = 1;
               year_of_age = 1;
               def_start_loc.sprintf("%s@%s", the_config.entry_locname.str_show(), 
                                   the_config.hardcoded_areaname.str_show());
               save_game_data(error_log);
#ifndef WIN32
               sysmessage("Created.\n");
              }
            else
              {
               sysmessage("\nCan't continue bootstrap, exiting!\n");
               boot_locked = 0;
               return -1;
              }  
#endif
         }
       else if (!quiet_mode)
            sysmessage("loaded.%s", newline);
         stage_complete = 1;
       break;

     case STAT_VERBS_GAMEVERBS:
       if (!quiet_mode)
       {
            sysmessage("\tLoading verbs...");
       }
       verbs = new_Verb_List(&playerverb[0]); 
         stage_complete = 1;
         break;

     case STAT_VERBS_ACTIONS:

       if (load_actions() == -2)
         {
               holder.sprintf("%s%s%s%sactions.dat", the_config.basedir.str_show(), DSEP, DATA_DIR, DSEP);
               start_convert(holder.str_show());
               stage--;
               break;
         }
         stage_complete = 1;
         break;

     case STAT_VERBS_ABILITIES:

       if (load_abilities() == -2)
         {
               holder.sprintf("%s%s%s%sabilities.dat", the_config.basedir.str_show(), DSEP, DATA_DIR, DSEP);
               start_convert(holder.str_show());
               stage--;
               break;
         }
         stage_complete = 1;
         break;

       case STAT_VERBS_BUILDVERBS:
       buildverbs = new_Verb_List(&builderverb[0]); 
         stage_complete = 1;
         break;

       case STAT_VERBS_CHATLINES:

         if (load_chatlines() == -2)
         {
               holder.sprintf("%s%s%s%schatlines.dat", the_config.basedir.str_show(), DSEP, DATA_DIR, DSEP);
               start_convert(holder.str_show());
               stage--;
               break;
         }

       if (!quiet_mode)
       {
            sysmessage("loaded.%s", newline);
       }
         stage_complete = 1;
       break;

     case STAT_AREAS:

       if (!quiet_mode)
       {
            sysmessage("\tLoading areas.%s", newline);
       }
       mudobjects = new_Object_List(error_log, quiet_mode);

       failed_on = mudobjects->get_status();
         if (failed_on.str_show() != NULL)
         {
               delete_Object_List(mudobjects);
               mudobjects = NULL;
               holder.sprintf(failed_on.str_show());
               start_convert(holder.str_show());
               stage--;
               break;
         }

       if (!quiet_mode)
       {
            sysmessage("\tLoaded.                %s", newline);
       }
         stage_complete = 1;

       break;

     case STAT_LEVELS:
       if (!quiet_mode)
       {
         sysmessage("\tLoading levels...");
       }
       game_levels = new_Level_List(error_log, mudobjects); 
 
         if (game_levels->get_status() == -2)
         {
               delete_Level_List(game_levels);
               game_levels = NULL;
               holder.sprintf("%s%s%s%slevels.dat", the_config.basedir.str_show(), DSEP, DATA_DIR, DSEP);
               start_convert(holder.str_show());
               stage--;
               break;
         }

       if (!quiet_mode)
       {
          sysmessage("loaded.%s", newline);
       }
         stage_complete = 1;
       break;

     case STAT_GAMEREADY:
         stage_complete = 1;
       break;

     default:
         boot_locked = 0;
       return -1;
  }
  this->status = stage; 
  if (stage_complete)
       boot_locked = 0;
  return 1;   
}

/***********************************************************************
 ** shutdown_mud - shuts down the mud, cleaning things up
 **
 ** Parameters: None
 **
 ** Returns: 1 if successful
 **
 ***********************************************************************/

int Mud::shutdown_mud(void)
{
#ifndef WIN32
  for (; status>STAT_FRESH; status--)
  {
     shutdown_mud(status);
  }
  status = STAT_FRESH;

#else

  shutdown_mud(status);
  status--;
#endif

  return 1;
}

/***********************************************************************
 ** shutdown_mud - shuts down the mud, cleaning things up
 **
 ** Parameters: stage - the stage we should shut down
 **
 ** Returns: 1 if successful
 **
 ***********************************************************************/

int Mud::shutdown_mud(int stage)
{

  switch(stage)
  {
     case STAT_FRESH:
       return 0;

     case STAT_GAMEPLAY:
       return 0;

     case STAT_VERBS_GAMEVERBS:
       sysmessage("\tStoring game data...");
       save_game_data(error_log);
       sysmessage("Done.%s", NEWLINE);
         stage = STAT_VERBS_GAMEVERBS;
         break;

     case STAT_VERBS_ACTIONS:
         break;

     case STAT_VERBS_ABILITIES:
         break;

     case STAT_VERBS_BUILDVERBS:
         break;

       case STAT_VERBS_CHATLINES:
         break;

     case STAT_AREAS:
       sysmessage("\tDeleting verb list...");
       delete_Verb_List(verbs);
       delete_Verb_List(buildverbs);
         verbs = buildverbs = NULL;
       sysmessage("Done.%s", NEWLINE);
         break;

     case STAT_LEVELS:
       sysmessage("\tRemoving the object database from memory...");
       delete_Object_List(mudobjects);
         mudobjects = NULL;
       sysmessage("Done.%s", NEWLINE);
       break;

     case STAT_GAMEREADY:
       sysmessage("\tDeleting levels list...");
       delete_Level_List(game_levels);
       sysmessage("Done.%s", NEWLINE);
         game_levels = NULL;
       break;
       
     default:
       return -1;
  }

   return 1;
}

/***********************************************************************
 ** add_player - adds a player to the list of players
 **
 ** Parameters: None
 **
 ** Returns: a pointer to the new player
 **
 ***********************************************************************/

int Mud::add_player(Player *the_player)
{
   Player   *temp_ptr;   /* used to traverse the player list */

   /* if this is the first one */
   temp_ptr = player_list;
   if (temp_ptr == NULL)
   {
      player_list = the_player;
      return 1;
   }

   /* find the end of the list */
   while (temp_ptr->get_next_player() != NULL)
   {
      temp_ptr = temp_ptr->get_next_player();
   }
   
   /* make the new player and add it to the list */
   temp_ptr->set_next_player(the_player);
   return 1;
}


/***********************************************************************
 ** add_player - adds a player to the list of players
 **
 ** Parameters: None
 **
 ** Returns: a pointer to the new player
 **
 ***********************************************************************/

Player *Mud::add_player()
{
   Player   *new_player; /* holds the new player */

   new_player = new_Player();
   add_player(new_player);
   return new_player;
}


/***********************************************************************
 ** add_builder - adds a builder to the list of builders
 **
 ** Parameters: the_conn - the connection to set this builder to
 **
 ** Returns: a pointer to the new builder
 **
 ***********************************************************************/
Builder *Mud::add_builder()
{
      return add_builder(NULL);
}

Builder *Mud::add_builder(Connection *the_conn)
{
   Builder  *temp_ptr;    /* used to traverse the player list */
   Builder  *new_builder; /* holds the new player */
   Timespan the_time;

   /* if this is the first one */
   temp_ptr = builder_list;
   if (temp_ptr == NULL)
   {
        if (the_conn == NULL)
             builder_list = new_Builder();
        else
             builder_list = new_Builder(the_conn);
      return builder_list;
   }

   /* find the end of the list */
   while (temp_ptr->get_next_builder() != NULL)
   {
      temp_ptr = temp_ptr->get_next_builder();
   }
   
   /* make the new player and add it to the list */
   if (the_conn != NULL)
         new_builder = new_Builder(the_conn);
   else
         new_builder = new_Builder();

   temp_ptr->set_next_builder(new_builder);
   return new_builder;
}

/***********************************************************************
 ** remove_all_player - deletes all player from the linked list
 **
 ** Parameters: None
 **
 ** Returns: num removed if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mud::remove_all_players(void)
{
   Player   *the_list;
   Player   *delete_ptr;
   int      count = 0;
   Timespan the_time;

   the_list = player_list;
   player_list = NULL;
   while (the_list != NULL)
   {
      count++;
      delete_ptr = the_list;
      mainstruct->save_player(the_list);
      the_list = the_list->get_next_player();
      delete_Player(delete_ptr);
   }

   player_list = NULL;
   return count;
}


/***********************************************************************
 ** remove_all_builders - deletes all builders from the linked list
 **
 ** Parameters: None
 **
 ** Returns: num removed if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mud::remove_all_builders(void)
{
   Builder  *the_list;
   Builder  *delete_ptr;
   int      count = 0;
   Timespan the_time;

   the_list = builder_list;
   while (the_list != NULL)
   {
      count++;
      delete_ptr = the_list;
      the_list = the_list->get_next_builder();
      delete_Builder(delete_ptr);
   }
   builder_list = NULL;
   return count;
}


/***********************************************************************
 ** remove_player - deletes a player from the linked list
 **
 ** Parameters: the_name - the name of the player to remove
 **
 ** Returns: 1 if successful, -1 if failed
 **
 ***********************************************************************/

int Mud::remove_player(char *the_name)
{
   Player   *temp_ptr;
   Player   *prev_ptr;
   Timespan the_time;

   /* if they sent us an empty one, return -1 */
   if (player_list == NULL)
      return -1;

   /* if the first one is the one we are looking for, do this */
   if (!STRCASECMP(the_name, player_list->get_name()))
   {
      temp_ptr = player_list;
      player_list = player_list->get_next_player();
      delete_Player(temp_ptr);
      return 1;
   }
 
   /* set up to move along list */
   prev_ptr = player_list;
   temp_ptr = player_list->get_next_player();

   /* while we havent reached the bottom of the list */
   while (temp_ptr != NULL)
   {
      if (!STRCASECMP(the_name, temp_ptr->get_name()))
      {
         prev_ptr->set_next_player(temp_ptr->get_next_player());
         delete_Player(temp_ptr);
         return 1;
      }
      prev_ptr = temp_ptr;
      temp_ptr = temp_ptr->get_next_player();
   }
   return -1;
}


/***********************************************************************
 ** remove_builder - deletes a builder from the linked list
 **
 ** Parameters: the_name - the name of the player to remove
 **
 ** Returns: 1 if successful, -1 if failed
 **
 ***********************************************************************/

int Mud::remove_builder(char *the_name)
{
   Builder  *temp_ptr;
   Builder  *prev_ptr;
   Timespan the_time;

   /* if they sent us an empty one, return -1 */
   if (builder_list == NULL)
      return -1;

   /* if the first one is the one we are looking for, do this */
   if (!STRCASECMP(the_name, builder_list->get_name()))
   {
      temp_ptr = builder_list;
      builder_list = builder_list->get_next_builder();
      delete_Builder(temp_ptr);
      return 1;
   }
 
   /* set up to move along list */
   prev_ptr = builder_list;
   temp_ptr = builder_list->get_next_builder();

   /* while we havent reached the bottom of the list */
   while (temp_ptr != NULL)
   {
      if (!STRCASECMP(the_name, temp_ptr->get_name()))
      {
         prev_ptr->set_next_builder(temp_ptr->get_next_builder());
         delete_Builder(temp_ptr);
         return 1;
      }
      prev_ptr = temp_ptr;
      temp_ptr = temp_ptr->get_next_builder();
   }
   return -1;
}

/***********************************************************************
 ** handle_quits - looks for any quit players, and closes their link and
 **                removes their player
 **
 ** Parameters: None
 **
 ** Returns: number of players removed
 **          -1 if an error
 **
 ***********************************************************************/

int Mud::handle_quits(void)
{
   Player *tmp_p_list;  /* the list to check for player quittings */ 
   Player *remove_pl; /* the player to remove */
   Builder *tmp_b_list;
   Builder *remove_bl;
   int    count = 0;  /* the number of players that have been removed */ 
   Strings holder;

   
   tmp_p_list = player_list;

   while (tmp_p_list != NULL)
   {
      if (tmp_p_list->is_on() == 0)
      {
         Location *the_loc;

         remove_pl = tmp_p_list;
         tmp_p_list = tmp_p_list->get_next_player();

       // If this player is lacking a connection, then they have died
       // Don't save them as it has already been done
       if (remove_pl->get_connection() != NULL)
         mainstruct->save_player(remove_pl);

         holder.sprintf("Log &+Roff&* game port by player: %s.", 
                                                  remove_pl->get_title());
         mainstruct->log_event(holder.str_show());
         the_loc = remove_pl->get_loc();
         if (the_loc != NULL)
           holder.
            sprintf("&+Y[&+WPlayer &+M%s&+W has quit from &+c%s&+c.&+Y]&*\n",
                       remove_pl->get_name(), the_loc->get_title());
         else
           holder.
            sprintf("&+Y[&+WPlayer &+M%s&+W has disconnected.&+Y]&*\n",
             remove_pl->get_name());

         mainstruct->send_all_players(holder.str_show(), remove_pl, 
                                                 ADMINFLAG_SEELOGIN);

         if (remove_player(remove_pl->get_name()) <= 0)
         {   
            log_error("Error removing player!", "handle_quits");
            return -1;
         }
         count++;
      }
      else
         tmp_p_list = tmp_p_list->get_next_player();
   }

   tmp_b_list = builder_list;

   while (tmp_b_list != NULL)
   {
      if (tmp_b_list->is_on() == 0)
      {
         remove_bl = tmp_b_list;
         tmp_b_list = tmp_b_list->get_next_builder();

         holder.sprintf("Log &+Roff&* bldr port by builder: %s.", 
                                                  remove_bl->get_name());
         mainstruct->log_event(holder.str_show());
         holder.sprintf("&+Y[&+WBuilder &+M%s&+W has logged "
            "off from the builder port.&+Y]&*\n", remove_bl->get_name());
         mainstruct->send_all_players(holder.str_show(), NULL, 
                                                   ADMINFLAG_SEELOGIN);

         if (remove_builder(remove_bl->get_name()) <= 0)
         {   
            log_error("Error removing builder!", "handle_quits");
            return -1;
         }
         count++;
      }
      else
         tmp_b_list = tmp_b_list->get_next_builder();
   }
   return count;
}


/***********************************************************************
 ** get_verb_list - gets the verb list from the object
 **
 ** Parameters: None
 **
 ** Returns: pointer to the verb list
 **
 ***********************************************************************/

Verb_List *Mud::get_player_verb_list(void) {
   return verbs;
}


/***********************************************************************
 ** get_build_verb_list - gets the verb list from the object
 **
 ** Parameters: None
 **
 ** Returns: pointer to the verb list
 **
 ***********************************************************************/

Verb_List *Mud::get_builder_verb_list(void) {
   return buildverbs;
}


/***********************************************************************
 ** get_player - given the character name, gets a pointer to a player
 **              object
 **
 ** Parameters: the_name - the name of the player to get
 **
 ** Returns: pointer to the player object or NULL if none found
 **
 ***********************************************************************/

Player *Mud::get_player(char *the_name) {
   Player   *temp_ptr;  /* used to move along the player linked list */
   Timespan the_time;
   
   if (the_name == NULL)
      return NULL;

   temp_ptr = player_list;

   /* move along the list, getting players till we find the right one */
   while ((temp_ptr != NULL) && (STRCASECMP(the_name, temp_ptr->get_name())))
   {
      temp_ptr = temp_ptr->get_next_player();
   }
   return temp_ptr;
}


/***********************************************************************
 ** get_builder - given the character name, gets a pointer to a builder
 **              object
 **
 ** Parameters: the_name - the name of the player to get
 **
 ** Returns: pointer to the builder object or NULL if none found
 **
 ***********************************************************************/

Builder *Mud::get_builder(char *the_name) {
   Builder  *temp_ptr;  /* used to move along the builder linked list */
   Timespan the_time;
   
   if (the_name == NULL)
      return NULL;

   temp_ptr = builder_list;
   
   /* move along the list, getting builders till we find the right one */
   while ((temp_ptr != NULL) && (STRCASECMP(the_name, temp_ptr->get_name())))
   {
      temp_ptr = temp_ptr->get_next_builder();
   }
   return temp_ptr;
}


/***********************************************************************
 ** get_first_player - gets the first player on the list
 **
 ** Parameters: None
 **
 ** Returns: pointer to the first player object
 **
 ***********************************************************************/

Player *Mud::get_first_player()
{
   return player_list;   
}


/***********************************************************************
 ** get_first_builder - gets the first builder on the list
 **
 ** Parameters: None
 **
 ** Returns: pointer to the first builder object
 **
 ***********************************************************************/

Builder *Mud::get_first_builder()
{
   return builder_list;   
}

/***********************************************************************
 ** get_object - gets an object given the object name
 **
 ** Parameters: obj_name - the object name to get
 **
 ** Returns: pointer to the object if success
 **          NULL if failure
 **
 ***********************************************************************/

MudObject *Mud::get_object(char *obj_name)
{
   char temp_str[(MAXNAMELEN*2)+2];  /* holds the object name@area */
   char *temp_ptr;  /* used to move along the string searching */

   if (obj_name == NULL)
      return NULL;

   BZERO(temp_str, (MAXNAMELEN*2)+2);   
   strncpy(temp_str, obj_name, (MAXNAMELEN*2)+1);

   /* look for the @, if found, parse out before and after */
   temp_ptr = &temp_str[0];
   while (*temp_ptr != '@')
   {
      if (*temp_ptr == '\0')
      {
         return NULL;
      }
      temp_ptr++;
   }
   *temp_ptr = '\0';
   temp_ptr++;

   if ((temp_str == NULL) || (temp_ptr == NULL) ||
       (*temp_str == '\0') || (*temp_ptr == '\0'))   
      return NULL;

   return mudobjects->get_mudobject(temp_ptr, temp_str);
}


/***********************************************************************
 ** get_special - gets the special given the object name
 **
 ** Parameters: obj_name - the object name to get
 **
 ** Returns: pointer to the object if success
 **          NULL if failure
 **
 ***********************************************************************/

Specials *Mud::get_special(char *obj_name)
{
   char temp_str[(MAXNAMELEN*2)+2];  /* holds the object name@area */
   char *temp_ptr;  /* used to move along the string searching */

   if (obj_name == NULL)
      return NULL;
   
   strncpy(temp_str, obj_name, (MAXNAMELEN*2)+1);

   /* look for the @, if found, parse out before and after */
   temp_ptr = &temp_str[0];
   while (*temp_ptr != '@')
   {
      if (*temp_ptr == '\0')
      {
         return NULL;
      }
      temp_ptr++;
   }
   *temp_ptr = '\0';
   temp_ptr++;
   
   return mudobjects->get_special_obj(temp_ptr, temp_str);
}


/***********************************************************************
 ** get_ability - gets the ability given the object name
 **
 ** Parameters: obj_name - the object name to get
 **
 ** Returns: pointer to the object if success
 **          NULL if failure
 **
 ***********************************************************************/

Ability *Mud::get_ability(char *obj_name)
{
   if (obj_name == NULL)
      return NULL;
      
   return mudobjects->get_ability_obj(obj_name);
}

/***********************************************************************
 ** get_race - gets the race given the object name
 **
 ** Parameters: obj_name - the object name to get
 **
 ** Returns: pointer to the object if success
 **          NULL if failure
 **
 ***********************************************************************/

Race *Mud::get_race(char *obj_name)
{
   if (obj_name == NULL)
      return NULL;
      
   return mudobjects->get_race_obj(obj_name);
}



/***********************************************************************
 ** log_error - logs an error in the errorlog
 **
 ** Parameters: the_error - the error to send to the log
 **             the_funct - the function the error occurred in
 **
 ** Returns:  1 if success
 **          -1 if failure
 **
 ***********************************************************************/

int Mud::log_error(char *the_error, char *the_funct)
{  
   return error_log->log_err(the_error, the_funct);
}


/***********************************************************************
 ** log_event - logs an event in the syslog
 **
 ** Parameters: the_error - the error to send to the log
 **
 ** Returns:  1 if success
 **          -1 if failure
 **
 ***********************************************************************/

int Mud::log_event(char *the_event)
{  
   return sys_log->log_event(the_event);
}



/***********************************************************************
 ** get_log - returns a pointer to the error log
 **
 ** Parameters: None
 **
 ** Returns:  a pointer to the error log if successful,
 **           NULL if failed
 **
 ***********************************************************************/

ErrLog *Mud::get_log()
{
   return error_log;
}


/***********************************************************************
 ** get_syslog - returns a pointer to the sys log
 **
 ** Parameters: None
 **
 ** Returns:  a pointer to the system log if successful,
 **           NULL if failed
 **
 ***********************************************************************/

SysLog *Mud::get_syslog()
{
   return sys_log;
}


/***********************************************************************
 ** get_suggestlog - returns a pointer to the suggestions log
 **
 ** Parameters: None
 **
 ** Returns:  a pointer to the suggestions log if successful,
 **           NULL if failed
 **
 ***********************************************************************/

Data_Log *Mud::get_suggestlog()
{
   return suggest_log;
}


/***********************************************************************
 ** get_buglog - returns a pointer to the bug log
 **
 ** Parameters: None
 **
 ** Returns:  a pointer to the bug log if successful,
 **           NULL if failed
 **
 ***********************************************************************/

Data_Log *Mud::get_buglog()
{
   return bug_log;
}


/***********************************************************************
 ** get_typolog - returns a pointer to the typo log
 **
 ** Parameters: None
 **
 ** Returns:  a pointer to the typo log if successful,
 **           NULL if failed
 **
 ***********************************************************************/

Data_Log *Mud::get_typolog()
{
   return typo_log;
}


/***********************************************************************
 ** get_dbase - returns the pointer to the mud database
 **
 ** Parameters: None
 **
 ** Returns: pointer to the mudobject that it recovered
 **
 ***********************************************************************/

Object_List *Mud::get_dbase()
{
   return mudobjects;
}


/***********************************************************************
 ** check_sockets - check and handles any connections at the sockets
 **
 ** Parameters: None
 **
 ** Returns:  1 if successful
 **          -1 if failure checking player listening socket
 **          -2 if failure checking builder listening socket
 **
 ***********************************************************************/

int Mud::check_sockets()
{

// We don't use this in win32
#ifndef WIN32
   if (game_port->check_socket(NULL) < 0)
      return -1;

   if (build_port->check_socket(&the_timer) < 0)
      return -2;

#endif
   return 1;
}


/***********************************************************************
 ** get_game_socket - gets the listening port socket for the game
 **
 ** Parameters: None
 **
 ** Returns: the socket if successful
 **          -1 if failure 
 **
 ***********************************************************************/

Port *Mud::get_game_socket()
{
   return game_port;
}


/***********************************************************************
 ** get_build_socket - gets the listening port socket for the build port
 **
 ** Parameters: None
 **
 ** Returns: the socket if successful
 **          -1 if failure 
 **
 ***********************************************************************/

//int Mud::get_build_socket()
//{
//  return build_port->get_socket();
//}

Port *Mud::get_build_socket()
{
   return build_port;
}



/***********************************************************************
 ** get_user_database - gets a pointer to the user database object
 **
 ** Parameters: None
 **
 ** Returns: the pointer to the user database object
 **
 ***********************************************************************/

User_Dbase *Mud::get_user_database()
{
   return user_database;
}


/***********************************************************************
 ** is_shutdown - are we shutting down?
 **
 ** Parameters: None
 **
 ** Returns: 1 for shutting down, 0 for not
 **
 ***********************************************************************/

int Mud::is_shutdown()
{
   return shutdwn;
}


/***********************************************************************
 ** shutdown - shut down the mud carefully
 **
 ** Parameters: None
 **
 ** Returns: returns 1 for success
 **
 ***********************************************************************/

int Mud::shutdown()
{
#ifdef WIN32
   main_dlg->initiate_halt();
#endif
   shutdwn = 1;
   return shutdwn;
}


/***********************************************************************
 ** get_bldr_access_list - gets the access list file object for the
 **                        builder port
 **
 ** Parameters: None
 **
 ** Returns: returns the pointer to the list
 **
 ***********************************************************************/

Access_List *Mud::get_bldr_access_list()
{
   return builder_access_list;
}


/***********************************************************************
 ** get_game_access_list - gets the access list file object for the
 **                        game port
 **
 ** Parameters: None
 **
 ** Returns: returns the pointer to the list
 **
 ***********************************************************************/

Access_List *Mud::get_game_access_list()
{
   return game_access_list;
}


/***********************************************************************
 ** clear_associations - causes the player to drop all objects and clears
 **                      the player's pointer to their location, preparing
 **                      for reloading all areas
 **
 ** Parameters: None
 **
 ** Returns: num cleared if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mud::clear_associations(void)
{
   Player   *the_list;
   int      count = 0;
   Timespan the_time;

   the_list = player_list;
   while (the_list != NULL)
   {
      count++;
      the_list->drop_all();
      the_list->clr_curr_loc();
      the_list = the_list->get_next_player();
   }
   return count;
}


/***********************************************************************
 ** reset_associations - resets all associations that were cleared
 **
 ** Parameters: None
 **
 ** Returns: num modified if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mud::reset_associations(void)
{
   Player   *the_list;
   int      count = 0;
   Timespan the_time;

   the_list = player_list;

   while (the_list != NULL)
   {
      Strings holder;

      count++;
      if (the_list->reset_curr_loc() == -1)
      {
         holder.sprintf("Could not reset location on player %s!\n", 
                                              the_list->get_name());         
         mainstruct->log_error(holder.str_show(), "reset_associations");
         holder.sprintf("%s@%s", the_config.backup_locname.str_show(), 
                                      the_config.hardcoded_areaname.str_show());
         the_list->set_loc_str(holder.str_show());
         the_list->reset_curr_loc();
      }
      the_list = the_list->get_next_player();
   }
   return count;
}
 

/***********************************************************************
 ** reload_verbs - reloads the verbs, actions, abilities, and chatlines
 **
 **
 ***********************************************************************/

int Mud::reload_verbs(void)
{
   delete_Verb_List(verbs);

   verbs = new_Verb_List(&playerverb[0]); 
   load_actions();
   load_abilities();
   load_chatlines();

   return 1;
}

/***********************************************************************
 ** reload_races - reloads the races into the database
 **
 ** Returns: 1 for successful, -1 for failed
 **
 ***********************************************************************/

int Mud::reload_races(void)
{
   return mudobjects->reload_races();
}

/***********************************************************************
 ** reload_inclinations - reloads the inclinations into the database
 **
 ** Returns: 1 for successful, -1 for failed
 **
 ***********************************************************************/

int Mud::reload_inclinations(void)
{
   return mudobjects->reload_inclinations();
}

/***********************************************************************
 ** reload_talents - reloads the talents into the database
 **
 ** Returns: 1 for successful, -1 for failed
 **
 ***********************************************************************/

int Mud::reload_talents(void)
{
   return mudobjects->reload_talents();
}

/***********************************************************************
 ** reload_abilities - reloads the abilities into the database
 **
 ** Returns: 1 for successful, -1 for failed
 **
 ***********************************************************************/

int Mud::reload_abilities(void)
{
   return mudobjects->reload_abilities();
}

/***********************************************************************
 ** reload_bulletins - reloads the bulletins into the database
 **
 ** Returns: 1 for successful, -1 for failed
 **
 ***********************************************************************/

int Mud::reload_bulletins(void)
{
   return mudobjects->reload_bulletins();
}

/***********************************************************************
 ** reload_masks - reloads the masks into the database
 **
 ** Returns: 1 for successful, -1 for failed
 **
 ***********************************************************************/

int Mud::reload_masks(void)
{
   return mudobjects->reload_masks();
}

/***********************************************************************
 ** reload_all - reloads all areas in the mud
 **
 ** Parameters: None
 **
 ** Returns: 1 if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mud::reload_all(void)
{
   save_all_players();

   if (clear_associations() <= 0)
      return -1;

   sysmessage("Deleting old objects...");
   mudobjects->empty_objects();  // Remove everything from all objects
   delete_Object_List(mudobjects);
   sysmessage("deleted.%s", NEWLINE);

   sysmessage("  Reloading areas...");
   mudobjects = new_Object_List(error_log, 1);
   sysmessage("loaded.%s", NEWLINE);

   if (reset_associations() <= 0)
      return -1;

   read_all_inventories();

   return 1;   
}


/***********************************************************************
 ** send_all_players - sends a message to all players on the mud
 **
 ** Parameters: the_message - the message to be sent to all
 **
 ** Returns: num sent to if success, -1 if failed
 **
 ***********************************************************************/

int Mud::send_all_players(char *the_message){
   Player *players_list;
   int count = 0;
   Flags *gameflag;

   players_list = mainstruct->get_first_player();

   /* go through all players sending the message */
   while (players_list != NULL)
   {
      gameflag = players_list->get_gameflags();
      if ((gameflag->get_flag(GAMEFLAG_ONGAME)) &&
          (!players_list->is_asleep()))
      {
         count++;
         players_list->send_plr(the_message);
      }
      /* go to next player */
      players_list = players_list->get_next_player();
      
   }
   return count;
}


/***********************************************************************
 ** send_all_builders - sends a message to all buiders on the builder port
 **
 ** Parameters: the_message - the message to be sent to all
 **
 ** Returns: num sent to if success, -1 if failed
 **
 ***********************************************************************/

int Mud::send_all_builders(char *the_message){
   Builder *builders_list;
   int count = 0;

   builders_list = mainstruct->get_first_builder();

   /* go through all builders sending the message */
   while (builders_list != NULL)
   {
      count++;
      builders_list->send_bldr(the_message);
 
      /* go to next builder */
      builders_list = builders_list->get_next_builder();
      
   }
   return count;
}


/***********************************************************************
 ** send_all_builders - sends a message to all buiders on the builder port
 **
 ** Parameters: the_message - the message to be sent to all
 **             the_builder - the builder not to send this to
 **
 ** Returns: num sent to if success, -1 if failed
 **
 ***********************************************************************/

int Mud::send_all_builders(char *the_message, Builder *the_builder){
   Builder *builders_list;
   int count = 0;

   builders_list = mainstruct->get_first_builder();

   /* go through all builders sending the message */
   while (builders_list != NULL)
   {
      if (the_builder != builders_list)
      {
         count++;
         builders_list->send_bldr(the_message);
      }

      /* go to next builder */
      builders_list = builders_list->get_next_builder();
      
   }
   return count;
}


/***********************************************************************
 ** send_all_outside - sends a message to all who are outside
 **
 ** Parameters: the_message - the message to be sent to all
 **
 ** Returns: num sent to if success, -1 if failed
 **
 ***********************************************************************/

int Mud::send_all_outside(char *the_message){
   Player *players_list;
   int count = 0;
   Flags *gameflag;
   Flags *locflag;

   players_list = mainstruct->get_first_player();

   /* go through all players sending the message */
   while (players_list != NULL)
   {
      gameflag = players_list->get_gameflags();
      if (gameflag->get_flag(GAMEFLAG_ONGAME)) 
      {
         locflag = (players_list->get_loc())->get_locflags();
         if (locflag->get_flag(LOCFLAG_OUTSIDE))
             {
            count++;
            players_list->send_plr(the_message);
         }
      }
      /* go to next player */
      players_list = players_list->get_next_player();
      
   }
   return count;
}


/***********************************************************************
 ** send_all_players - sends a message to all players on the mud
 **
 ** Parameters: the_message - the message to be sent to all
 **             the_player - who not to send this to
 **             with_adm_flag - the admin flag they must have to see this
 **
 ** Returns: num sent to if success, -1 if failed
 **
 ***********************************************************************/

int Mud::send_all_players(char *the_message, Player *the_player, 
                                                    int with_adm_flag)
{
   Player *players_list;
   int count = 0;
   Flags *gameflag;
   Flags *admflags;

   players_list = mainstruct->get_first_player();

   /* go through all players sending the message */
   while (players_list != NULL)
   {
      gameflag = players_list->get_gameflags();
      admflags = players_list->get_admflags();
      if ((gameflag->get_flag(GAMEFLAG_ONGAME)) && 
          (admflags->get_flag(with_adm_flag)))
      {
         /* if the players is not the orig. of the message, send to them */
         if (((the_player == NULL) || 
           (STRCASECMP(the_player->get_name(), players_list->get_name()))) && 
              (!players_list->is_asleep()))
         {
            count++;
            players_list->send_plr(the_message);
         }
      }
      /* go to next player */
      players_list = players_list->get_next_player();
      
   }
   return count;
}

/***********************************************************************
 ** send_all_builders - sends a message to all builders on the mud
 **
 ** Parameters: the_message - the message to be sent to all
 **             the_builder - who not to send this to
 **             with_adm_flag - the admin flag they must have to see this
 **
 ** Returns: num sent to if success, -1 if failed
 **
 ***********************************************************************/

int Mud::send_all_builders(char *the_message, Builder *the_builder, 
                                                    int with_adm_flag)
{
   Builder *builders_list;
   int count = 0;
   Flags *gameflag;
   Flags *admflags;

   builders_list = mainstruct->get_first_builder();

   /* go through all players sending the message */
   while (builders_list != NULL)
   {
      gameflag = builders_list->get_gameflags();
      admflags = builders_list->get_adminflags();
      if ((gameflag->get_flag(GAMEFLAG_ONGAME)) && 
          (admflags->get_flag(with_adm_flag)))
      {
         /* if the players is not the orig. of the message, send to them */
         if ((the_builder == NULL) || 
            (STRCASECMP(the_builder->get_name(), builders_list->get_name())))
         {
            count++;
            builders_list->send_bldr(the_message);
         }
      }
      /* go to next builder */
      builders_list = builders_list->get_next_builder();
   }
   return count;
}


/***********************************************************************
 ** send_all_players - sends a message to all players on the mud
 **
 ** Parameters: the_message - the message to be sent to all
 **             the_player - the player not to send it to
 **
 ** Returns: num sent to if success, -1 if failed
 **
 ***********************************************************************/

int Mud::send_all_players(char *the_message, Player *the_player){
   Player *players_list;
   int count = 0;
   Flags *gameflag;

   players_list = mainstruct->get_first_player();

   /* go through all players sending the message */
   while (players_list != NULL)
   {
      gameflag = players_list->get_gameflags();
      if (gameflag->get_flag(GAMEFLAG_ONGAME))
      {
         /* if the players is not the orig. of the message, send to them */
         if (((the_player == NULL) || (STRCASECMP(the_player->get_name(), 
              players_list->get_name()))) && (!players_list->is_asleep()))
         {
            count++;
            players_list->send_plr(the_message);
         }
      }

      /* go to next player */
      players_list = players_list->get_next_player();
   }
   return count;
}


/***********************************************************************
 ** cycle_mudobjects - goes through the list of mudobjects, looking for
 **                    any events that are supposed to happen
 **
 ** Parameters: None
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mud::cycle_mudobjects(void)
{
   Area_Dbase      *tmp_area;
   Entity          *tmp_obj;
   special_holder  *timer_special;
   in_params       fill_param;
   MudObject       *tmp_mudobj;

   mudobjects->reset_list();
   tmp_area = mudobjects->get_next_area();
   while (tmp_area != NULL)
   {
      /* first look if we need to reload */
      tmp_area->try_reload();

      tmp_area->reset_list();
      tmp_obj = tmp_area->get_next_obj();
      while (tmp_obj != NULL)
      {
         switch(tmp_obj->get_type())
       {
          case OBJ_TYPE_MOBILE:
             {
                  Mobile *tmp_mob;
                  Mobile *ghost_mob;
                  int    health;       
                  Flags  *tmp_indflags;
                  Location *tmp_loc;
                  Strings holder;

                  tmp_mob = (Mobile *) tmp_obj;
                  tmp_indflags = tmp_mob->get_indflags();
                  if (tmp_indflags->get_flag(INDFLAG_CORPSE))
              {
                 /* if the corpse has finally rotted away, make it go away */
                     if (tmp_mob->rot_corpse() == 0)
                     {
                        tmp_obj = tmp_area->get_next_obj();
                        tmp_loc = tmp_mob->get_loc();
                        holder.sprintf("%s@%s", tmp_mob->get_clones(), 
                                      the_config.hardcoded_areaname.str_show());
                        tmp_mob->drop_all();
                        tmp_loc->remove_contained(tmp_mob);
                        mudobjects->delete_obj(tmp_mob);
                        tmp_loc->send_location(
                              "The corpse finally crumbles to dust.\n", NULL);

                        /* do away with the ghost if there is one here */
                        if ((ghost_mob = (Mobile *) mainstruct->
                                       get_object(holder.str_show())) != NULL)
                  {
                           tmp_loc = ghost_mob->get_loc();
                           tmp_loc->remove_contained(ghost_mob);
                           if (tmp_obj == (Entity *) ghost_mob)
                              tmp_obj = tmp_area->get_next_obj();
                           mudobjects->delete_obj(ghost_mob);
                           tmp_loc->send_location(
                              "The ghost fades into nothingness.\n", NULL);
                  }
                        continue;
                 }
              }
                  else
              {
                     tmp_mob->check_mobile();

                     /* heal if its time */
                     if (the_timer.mob_TimeSinceHealed() >= 
                                                  the_config.secs_mobile_heal)
                     {
                        health = tmp_mob->get_health();
                        if (health < tmp_mob->get_maxhealth())
                      {
                           health++;
                           tmp_mob->set_health(health);
                      }
                 }
              }
               }
               break;

          default:
               break;
         }
         if (tmp_obj->is_a_mudobject())
       {
            tmp_mudobj = (MudObject *) tmp_obj;

            if ((timer_special = 
                    tmp_mudobj->find_special("eachsecond")) != NULL)
          {
               fill_param.primary_obj = NULL;
               fill_param.secondary_obj = NULL;
               fill_param.this_obj = tmp_mudobj;

               if ((timer_special->the_special)->run_special(
                        NULL, &fill_param, &timer_special->environment) == 2)
               {
                  MudObject *container;
                  MudObject *obj_holder;

                  container = tmp_mudobj->get_contained_by();
                  if (container != NULL)
                  {
                     container->remove_contained(tmp_mudobj);
                  }
                  obj_holder = tmp_mudobj;
                  tmp_obj = tmp_area->get_next_obj();
                  mainstruct->delete_object(obj_holder);
               }
               else
                  tmp_obj = tmp_area->get_next_obj();
          }
            else
               tmp_obj = tmp_area->get_next_obj();
         }
         else
            tmp_obj = tmp_area->get_next_obj();
      }
      tmp_area = mudobjects->get_next_area();
   }
   return 1;
}


/***********************************************************************
 ** cycle_players - cycles through the players, handling stuff
 **
 ** Parameters: None
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mud::cycle_players(void)
{
   Player *players_list;
   int   num;

   players_list = mainstruct->get_first_player();

   /* go through all players sending the message */
   while (players_list != NULL)
   {

      check_specials("eachsecond", players_list, players_list, NULL, 
                                                players_list, players_list);

      /* first see if they get healed a bit this turn */
      if (the_timer.plr_TimeSinceHealed() >= the_config.secs_player_heal)
      {
         num = players_list->get_health();
         if (num < players_list->get_maxhealth())
             {
            if (players_list->is_asleep())
               num += 3;
            if (players_list->is_sitting())
               num += 2;
            else
               num += 1;

            players_list->set_health(num);
            if (players_list->get_health() > players_list->get_maxhealth())
               players_list->set_health(players_list->get_maxhealth());

            if (num == players_list->get_maxhealth())
                  {
               players_list->send_plr("You feel fully healed.\n");
            }
             }
      }

      if (the_timer.plr_TimeSinceMagic() >= the_config.secs_player_magic)
      {
         num = players_list->get_magic();
         if (num < players_list->get_max_magic())
             {
            num++;
            players_list->set_magic(num);
            if (num == players_list->get_max_magic())
          {
               players_list->
                         send_plr("Your magic has been fully restored.\n");
            }
       }
      }

      if (the_timer.plr_TimeSinceEndur() >= the_config.secs_player_endur)
      {
         num = players_list->get_endurance();
         if (num < players_list->get_max_endurance())
       {
            num++;
            players_list->set_endurance(num);
            if (num == players_list->get_max_endurance())
          {
               players_list->
                      send_plr("Your endurance has been fully restored.\n");
            }
       }
      }

      if (the_timer.plr_TimeSinceLevel() >= the_config.secs_level_check)
      {
        game_levels->check_levels(players_list);
      }
      
      /* go to next player */
      players_list = players_list->get_next_player();
   }
   return 1;
}


/***********************************************************************
 ** cycle_world - runs the world through another cycle. This searches
 **               and executes events if they require it
 **
 ** Parameters: None
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mud::cycle_world(void)
{
   long timespan;

#if defined( AIME_WIN32 )
   FILETIME time_start, time_end;

   GetSystemTimeAsFileTime( &time_start );

#else // AIME_WIN32
   struct timeval time_start, time_end;

   gettimeofday(&time_start, NULL);
#endif // AIME_WIN32


   cycle_players();
   cycle_mudobjects();
   handle_fights();


#if defined( AIME_WIN32 )
      GetSystemTimeAsFileTime( &time_end );

      if( time_start.dwHighDateTime != time_end.dwHighDateTime )
      {
         timespan = ( long )( ( time_end.dwHighDateTime
                                - time_start.dwHighDateTime )
                              * 4294.967296 );
      }
      else
      {
         timespan = 0;
      }

      timespan += ( time_end.dwLowDateTime
                    - time_start.dwLowDateTime ) / 1000000;

#else // AIME_WIN32
     gettimeofday(&time_end, NULL);

     if (time_start.tv_sec != time_end.tv_sec)
     {
        timespan = ((1000000 - time_start.tv_usec) + 
                   ((time_end.tv_sec - (time_start.tv_sec+1)) * 1000000) +
                   (time_end.tv_usec));
     }
     else
        timespan = time_end.tv_usec - time_start.tv_usec;
#endif // AIME_WIN32


   num_cycle++;
   if (timespan > max_cycle)
      max_cycle = timespan;

   if (timespan < min_cycle)
      min_cycle = timespan;

   avg_cycle = ((avg_cycle*(num_cycle-1)) + timespan) / num_cycle;

   return 1;
}


/***********************************************************************
 ** handle_fights - runs through all ongoing fights, handling anything
 **                 that needs to be taken care of, such as swings,
 **                 deaths, etc
 **
 ** Parameters: None
 **
 ** Returns:  num counted if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mud::handle_fights(void)
{
   fighting_ind *fighter_focus;
   Individual   *the_fighter;
   int          count = 0;
   Player   *tmp_fighter_player;

   mainstruct->reset_fight_list();
   fighter_focus = mainstruct->get_next_fighter();

   while (fighter_focus != NULL)
   {
      fighter_focus->turn = !fighter_focus->turn;
      if (!fighter_focus->turn)
      {
       the_fighter = fighter_focus->the_fighter;
       /* take a swing, and if we are still fighting the person
            after the swing (we dont kill them or anything, then try
            to back away if we have a range weapon (a bow or something) */
       the_fighter->attack(the_fighter->get_target());
         if (the_fighter->is_alive())
         {
          if ((the_fighter->get_type() == OBJ_TYPE_PLAYER) &&
            (the_fighter->get_target() != NULL))
            {
               tmp_fighter_player = (Player *) the_fighter;

               if ((tmp_fighter_player->get_gameflags()->
                                       get_flag(GAMEFLAG_AUTODIAGNOSE)) &&
                   ((tmp_fighter_player->get_loc())->is_lit(tmp_fighter_player)))
                  the_fighter->get_target()->
                                            display_health(tmp_fighter_player);
            }
            the_fighter->try_step_away();
         }
      }
      count++;
      fighter_focus = mainstruct->get_next_fighter();
   }

   return count;
}



/***********************************************************************
 ** delete_object - deletes the mudobject from the database
 **
 ** Parameters: the_object - a pointer to the obj to be deleted
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mud::delete_object(MudObject *the_object) 
{ 
   return mudobjects->delete_obj(the_object); 
}
 

/***********************************************************************
 ** check_players - checks all the players for input and handles it
 **
 ** Parameters: - None
 **
 ** Returns:  num players checked if successful, -1 if not
 **
 ***********************************************************************/

int Mud::check_players(void) 
{ 
   Player *the_list;
   Player *del_ptr;
   int count = 0;

   the_list = player_list;
   while (the_list != NULL)
   {
      count++;
      if (the_list->check_player() == -2)
        {
           del_ptr = the_list;
             the_list = the_list->get_next_player();
             delete_Player(del_ptr);
        }
        else
             the_list = the_list->get_next_player();
   }
   return count;
}


/***********************************************************************
 ** check_builders - checks all the builders for input and handles it
 **
 ** Parameters: - None
 **
 ** Returns:  num players checked if successful, -1 if not
 **
 ***********************************************************************/

int Mud::check_builders(void) 
{ 
   Builder *the_list;
   int count = 0;

   the_list = builder_list;
   while (the_list != NULL)
   {
      the_list->check_builder();
      count++;
      the_list = the_list->get_next_builder();
   }
   return count;
}


/***********************************************************************
 ** flush_players - flushes the sockets of the players
 **
 ** Parameters: - None
 **
 ** Returns:  num players flushed
 **
 ***********************************************************************/

int Mud::flush_players(void) 
{
   Player *tmp_ptr;
   int count = 0;

   tmp_ptr = player_list;
   while (tmp_ptr != NULL)
   {
      count++;
      tmp_ptr->flush_player();
      tmp_ptr = tmp_ptr->get_next_player();
   }
   return count;
}


/***********************************************************************
 ** load_actions - loads the actions into this structure
 **
 ** Parameters: - None
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/

int Mud::load_actions(void) 
{
   FILE *actions_file = NULL;
   Strings filename;

   filename.sprintf("%s/%s/actions.dat", the_config.basedir.str_show(), DATA_DIR);
   if ((actions_file = xfopen(filename.str_show(), "r", 
                                                   "action_file")) == NULL)
   {
#ifndef WIN32
      char    user_input[11];
      sysmessage("The Actions data file is missing.  "
             "Would you like to create it? (y/n) ");
      fflush(stdout);

      fgets(user_input, 10, stdin);
      if (user_input[0] == 'n')
      {
         sysmessage("Actions data file must exist.  Exiting.\n");
         exit(0);
      }      

#endif

      if ((actions_file = xfopen(filename.str_show(), "w",
                                           "actions_create")) == NULL)
      {
         sysmessage("Fatal Error, could not create actions file!\n");
         exit(0);
      }

      fprintf(actions_file, "^%s^\n^^\n^^\n\n", FULLVERSION);
      xfclose(actions_file, "actions_create");

      if ((actions_file = xfopen(filename.str_show(), "r", 
                                            "action_file")) == NULL)
      {
         error_log->log_err("Error, could not open actions file!", 
                                            "load_actions");
         return -1;
      }
   }

   return verbs->load_actions(actions_file, NULL, error_log, 0);
}


/***********************************************************************
 ** load_chatlines - loads the chatlines into the verb list structure
 **
 ** Parameters: - None
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/

int Mud::load_chatlines(void) 
{
   FILE *chatlines_file = NULL;
   Strings filename;

   filename.sprintf("%s/%s/chatlines.dat", the_config.basedir.str_show(), DATA_DIR);
   if ((chatlines_file = xfopen(filename.str_show(), "r", 
                                                   "chatline_file")) == NULL)
   {
#ifndef WIN32
      char    user_input[11];
      sysmessage("The ChatLine data file is missing.  "
             "Would you like to create it? (y/n) ");
      fflush(stdout);

      fgets(user_input, 10, stdin);
      if (user_input[0] == 'n')
      {
         sysmessage("ChatLine data file must exist.  Exiting.\n");
         exit(0);
      }      
#endif

      if ((chatlines_file = xfopen(filename.str_show(), "w",
                                           "chatlines_create")) == NULL)
      {
         sysmessage("Fatal Error, could not create chatlines file!\n");
         exit(0);
      }

      fprintf(chatlines_file, "^%s^\n^^\n^^\n\n", FULLVERSION);
      xfclose(chatlines_file, "chatlines_create");

      if ((chatlines_file = xfopen(filename.str_show(), "r", 
                                            "chatline_file")) == NULL)
      {
         error_log->log_err("Error, could not open chatlines file!", 
                                            "load_chatlines");
         return -1;
      }
   }

   if (verbs->load_chatlines(chatlines_file, NULL, error_log, 0, LINEFLAG_PLAYER) == -2)
         return -2;

   if ((chatlines_file = xfopen(filename.str_show(), "r",
                                           "chatlines_file")) == NULL)
   {
      sysmessage("Fatal Error, could not create chatlines file!\n");
      exit(0);
   }

   buildverbs->load_chatlines(chatlines_file, NULL, error_log, 0, 
                                                           LINEFLAG_BUILDER);

   return 1;
}



/***********************************************************************
 ** load_abilities - loads the abilities into this structure
 **
 ** Parameters: - None
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/

int Mud::load_abilities(void) 
{
   FILE *abilities_file = NULL;
   Strings filename;

   filename.sprintf("%s/%s/abilities.dat", the_config.basedir.str_show(), 
                                                                   DATA_DIR);
   if ((abilities_file = xfopen(filename.str_show(), "r", 
                                            "abilities_file")) == NULL)
   {
#ifndef WIN32
      char    user_input[11];
      sysmessage("The Abilities data file is missing.  "
             "Would you like to create it? (y/n) ");
      fflush(stdout);

      fgets(user_input, 10, stdin);
      if (user_input[0] == 'n')
      {
         sysmessage("Abilities data file must exist.  Exiting.\n");
         exit(0);
      }      

#endif
      if ((abilities_file = xfopen(filename.str_show(), "w",
                                           "abilities_create")) == NULL)
      {
         sysmessage("Fatal Error, could not create abilities file!\n");
         exit(0);
      }

      fprintf(abilities_file, "^%s^\n^^\n^^\n\n", FULLVERSION);
      xfclose(abilities_file, "abilities_create");

      if ((abilities_file = xfopen(filename.str_show(), "r", 
                                            "abilities_file")) == NULL)
      {
         error_log->log_err("Error, could not open abilities file!", 
                                            "load_abilities");
         return -1;
      }
   }

   return verbs->load_abilities(abilities_file, NULL, error_log, 0);
}


/***********************************************************************
 ** start_timers - initializes all the timers
 **
 ** Parameters: - None
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/

int Mud::start_timers(void) 
{
   return the_timer.init_times();
}


/***********************************************************************
 ** check_events - checks the timer for any events that need to be
 **                executed
 **
 ** Parameters: - None
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/

int Mud::check_events(void) 
{
   return the_timer.handle_events();
}


/***********************************************************************
 ** get_tod - gets the time of day
 **
 ** Parameters: - None
 **
 ** Returns:  a time of day enumerated type
 **
 ***********************************************************************/

TimeOfDay Mud::get_tod()
{
   return time_of_day;
}


/***********************************************************************
 ** get_doy - gets the day of year
 **
 ** Parameters: - None
 **
 ** Returns:  the day of the year
 **
 ***********************************************************************/

int Mud::get_doy()
{
   return day_of_year;
}


/***********************************************************************
 ** get_yoa - gets the year of the age
 **
 ** Parameters: - None
 **
 ** Returns:  the year of age
 **
 ***********************************************************************/

int Mud::get_yoa()
{
   return year_of_age;
}

/***********************************************************************
 ** is_summer - is it summer or winter
 **
 ** Parameters: - None
 **
 ** Returns:  0 for winter, 1 for summer
 **
 ***********************************************************************/

int Mud::is_summer()
{
   if (day_of_year > the_config.first_day_winter)
   {
      if (day_of_year > the_config.first_day_summer)
      {
         if (the_config.first_day_winter > the_config.first_day_summer)
            return 0;
         else
            return 1;
      }
      return 0;
   }
   else
   {
      if (day_of_year > the_config.first_day_summer)
      {
         return 1;
      }
   }
   if (the_config.first_day_winter > the_config.first_day_summer)
      return 0;
   return 1;
}

/***********************************************************************
 ** increment_tod - increments the time of day
 **
 ** Parameters: - None
 **
 ** Returns:  Nothing
 **
 ***********************************************************************/

void Mud::increment_tod()
{
   switch(time_of_day)
   {
      case Night:
         time_of_day = Dawn;
         day_of_year++;
         if (day_of_year == the_config.days_in_year)
       {
            day_of_year = 1;
            year_of_age++;
         }
         save_game_data(mainstruct->get_log());
         break;

      case Dawn:
         time_of_day = Morning;
         break;

      case Morning:
         time_of_day = Afternoon;
         break;

      case Afternoon:
         time_of_day = Dusk;
         break;

      case Dusk:
         time_of_day = Night;
         break;

      default: break;
   }
}


/***********************************************************************
 ** set_tod - sets the time of day
 **
 ** Parameters: - the_time - time we are setting it to
 **
 ** Returns:  Nothing
 **
 ***********************************************************************/

void Mud::set_tod(TimeOfDay the_time)
{
   time_of_day = the_time;
   the_timer.set_tod_time(the_time);
}


/***********************************************************************
 ** set_doy - sets the day of the year
 **
 ** Parameters: - the_day - time we are setting it to
 **
 ** Returns:  Nothing
 **
 ***********************************************************************/

void Mud::set_doy(int the_day)
{
   day_of_year = the_day;
}


/***********************************************************************
 ** set_yoa - sets the year of the age
 **
 ** Parameters: - the_year - time we are setting it to
 **
 ** Returns:  Nothing
 **
 ***********************************************************************/

void Mud::set_yoa(int the_year)
{
   year_of_age = the_year;
}

/***********************************************************************
 ** show_tod - shows the time of day the mud is currently in
 **
 ** Parameters: - the_player - the person we send the message to
 **
 ** Returns:  Nothing
 **
 ***********************************************************************/

void Mud::show_tod(Player *the_player)
{
   char *tod[5] = {"night", "dawn", "morning", "afternoon", "dusk"};

   the_player->send_plr("It is currently %s.\n", tod[time_of_day]);
}


/***********************************************************************
 ** save_player - saves a player to the user database
 **
 **
 ***********************************************************************/

void Mud::save_player(Player *the_player)
{
   user_database->write_user(the_player);
}

/***********************************************************************
 ** save_all_player - saves all players in the game to the user database
 **
 **
 ***********************************************************************/

void Mud::save_all_players()
{
   Player *tmp_player;

   tmp_player = player_list;
   while (tmp_player != NULL)
   {
      save_player(tmp_player);
      tmp_player = tmp_player->get_next_player();
   }

}


/***********************************************************************
 ** read_all_inventory - reads all of the player's inventories back in
 **
 **
 ***********************************************************************/

void Mud::read_all_inventories()
{
   Player       *tmp_player;
   FILE         *the_file = NULL;
   char         user_dir;
   Strings      username;
   Strings      filename;
   token_record *the_token;

   tmp_player = player_list;
   while (tmp_player != NULL)
   {
      user_dir = (*(tmp_player->get_name()));
      user_dir = (char) tolower(user_dir);   

      username = tmp_player->get_name();
      username.lowercase();

      filename.sprintf("%s/%s/%c/%s%s", the_config.basedir.str_show(),
                   USERDATADIR, user_dir, username.str_show(), USEREXTENTION);

      /* if we can't open their user file, they carry nothing */
      if ((the_file = xfopen(filename.str_show(), "r", 
                                                    "inv_file")) == NULL)
      {
      printf("error opening file.\n");
         continue;
      }

      the_token = get_token(the_file, '\0');
      while ((the_token->token_type > 0) && 
             (STRCASECMP(the_token->the_string, "inv")))
      {
      if (the_token->token_type == T_CARROT)
      {
        the_token = get_token(the_file, '^');
      }
      the_token = get_token(the_file, '\0');
      }

      if (the_token->token_type > 0)
         tmp_player->read_inventory(the_file);

      xfclose(the_file, "inv_file");

      tmp_player = tmp_player->get_next_player();
   }

}

/***********************************************************************
 ** reload_area - reloads an area into the database
 **
 **
 ***********************************************************************/

int Mud::reload_area(char *areaname)
{
   FILE    *area_file = NULL;
   Strings area_filename;

   Area_Dbase *tmp_area;
   /* search all objects for issues */
      
   mudobjects->reset_list();
   tmp_area = mudobjects->get_next_area();
   while (tmp_area != NULL)
   {
      if (!STRCASECMP(tmp_area->get_areaname(), areaname))
      {
         area_filename.sprintf("%s/%s/%s.area", the_config.basedir.str_show(), 
                                                             AREADIR, areaname);
         area_filename.lowercase();
         if ((area_file = xfopen(area_filename.str_show(), "r", 
                                                "reload_area_file")) == NULL)
            return -1;

         tmp_area->reload_area(area_file);

         return 1;
      }
      tmp_area = mudobjects->get_next_area();      
   }
   return -1;
}

/***********************************************************************
 ** delete_entity - deletes an entity object from the dbase
 **
 **
 ***********************************************************************/

int Mud::delete_entity(Entity *the_entity)
{
#ifdef DEBUG_RELOAD
   return delete_entity(the_entity, 1);
#else
   return delete_entity(the_entity, 0);
#endif
}


/***********************************************************************
 ** delete_entity - deletes an entity object from the dbase
 **
 ** Parameters: the_entity - the entity we will delete
 **             debug_check - shall we check for things still pointing to it?
 **
 ***********************************************************************/

int Mud::delete_entity(Entity *the_entity, int debug_check)
{
   Area_Dbase      *tmp_area;
   Entity          *tmp_obj;
   Player          *tmp_player;

   if (the_entity == NULL)
      return -1;

   if (debug_check)
   {
      if ((the_entity->is_a_mudobject()) && (
          ((MudObject *)the_entity)->get_contained_by() != NULL))
      {
         sysmessage("eep! tried to delete a contained object!\n");
         RAISE(1);
      }

      /* make sure this contains nothing */
   
      mudobjects->save_state();
      mudobjects->reset_list();
      tmp_area = mudobjects->get_next_area();
      while (tmp_area != NULL)
      {
         tmp_area->save_state();

         tmp_area->reset_list();

         tmp_obj = tmp_area->get_next_obj();
         while (tmp_obj != NULL)
         {
            if (tmp_obj->is_a_mudobject())
          {
               special_holder *tmp_special;

               if (((MudObject *) tmp_obj)->get_contained_by() == 
                                                (MudObject *) the_entity)
             {
                  sysmessage("eep! tried to delete an object with items in it!\n");
                  RAISE(1);
               }
         
               if (the_entity->get_type() == OBJ_TYPE_SPECIAL)
             { 
                  tmp_special = ((MudObject *) tmp_obj)->get_special_list();
                  while (tmp_special != NULL)
                {
                     if (tmp_special->the_special == ((Specials *) the_entity))
                 {
                        sysmessage("eep!  tried to delete a still-used special!\n");
                        RAISE(1);
                 }
                     tmp_special = tmp_special->next_special;
                  }
             }
            }
            tmp_obj = tmp_area->get_next_obj();
         }
         tmp_area->restore_state();
         tmp_area = mudobjects->get_next_area();
      }
      mudobjects->restore_state();

      if (the_entity->is_an_individual())
      {
         Individual *the_ind;

         the_ind = ((Individual *) the_entity);
         tmp_player = mainstruct->get_first_player();
         while (tmp_player != NULL)
         {
            if (tmp_player->get_target() == the_ind)
          {
               sysmessage("eep!  tried to delete a targeted individual!\n");
               RAISE(1);
          }
            tmp_player = tmp_player->get_next_player();
       }
      }
   }

   switch(the_entity->get_type())
   {
      case OBJ_TYPE_LOCATION:
         Location *the_loc;

         the_loc = (Location *) the_entity;
         delete_Location(the_loc);
         break;

      case OBJ_TYPE_ITEM:
         Item *the_item;

         the_item = (Item *) the_entity;
         delete the_item;
         break;

      case OBJ_TYPE_MARKER:
         Marker *the_marker;

         the_marker = (Marker *) the_entity;
         delete_Marker(the_marker);
         break;

      case OBJ_TYPE_DOOR:
         Door *the_door;

         the_door = (Door *) the_entity;
         delete_Door(the_door);
         break;

      case OBJ_TYPE_MOVEABLE:
         Moveable *the_mov;

         the_mov = (Moveable *) the_entity;
         delete_Moveable(the_mov);
         break;

      case OBJ_TYPE_KEY:
         Key *the_key;

         the_key = (Key *) the_entity;
         delete_Key(the_key);
         break;

      case OBJ_TYPE_BOOK:
         Book *the_book;

         the_book = (Book *) the_entity;
         delete_Book(the_book);
         break;

      case OBJ_TYPE_ROPE:
         Rope *the_rope;

         the_rope = (Rope *) the_entity;
         delete_Rope(the_rope);
         break;

      case OBJ_TYPE_MOBILE:
         Mobile *the_mob;

         the_mob = (Mobile *) the_entity;
         delete_Mobile(the_mob);
         break;

      case OBJ_TYPE_MERGER:
         Merger *the_merger;

         the_merger = (Merger *) the_entity;
         delete_Merger(the_merger);
         break;

      case OBJ_TYPE_MONEY:
         Money *the_money;

         the_money = (Money *) the_entity;
         delete_Money(the_money);
         break;

      case OBJ_TYPE_WEAPON:
         Weapon *the_weapon;

         the_weapon = (Weapon *) the_entity;
         delete the_weapon;
         break;

      case OBJ_TYPE_WEARABLE:
         Wearable *the_wearable;

         the_wearable = (Wearable *) the_entity;
         delete the_wearable;
         break;

      case OBJ_TYPE_FOOD:
         Food *the_food;

         the_food = (Food *) the_entity;
         delete the_food;
         break;

      case OBJ_TYPE_SPECIAL:
         Specials *the_special;

         the_special = (Specials *) the_entity;
         delete the_special;
         break;

      case OBJ_TYPE_BOAT:
         Boat *the_boat;

         the_boat = (Boat *) the_entity;
         delete_Boat(the_boat);
         break;

      case OBJ_TYPE_SPELL:
         Spell *the_spell;

         the_spell = (Spell *) the_entity;
         delete the_spell;
         break;

      case OBJ_TYPE_SKILL:
         Skill *the_skill;

         the_skill = (Skill *) the_entity;
         delete_Skill(the_skill);
         break;

      case OBJ_TYPE_RACE:
         Race *the_race;

         the_race = (Race *) the_entity;
         delete the_race;
         break;

      case OBJ_TYPE_INCLINAT:
         Inclination *the_inclination;

         the_inclination = (Inclination *) the_entity;
         delete the_inclination;
         break;

      case OBJ_TYPE_TALENT:
         Talent *the_talent;

         the_talent = (Talent *) the_entity;
         delete the_talent;
         break;

      case OBJ_TYPE_MASK:
         Mask *the_mask;

         the_mask = (Mask *) the_entity;
         delete_Mask(the_mask);
         break;

      case OBJ_TYPE_QUEST:
         Quest *the_quest;

         the_quest = (Quest *) the_entity;
         delete_Quest(the_quest);
         break;

      case OBJ_TYPE_LEVEL:
         Level *the_level;

         the_level = (Level *) the_entity;
         delete the_level;
         break;

      case OBJ_TYPE_VERB:
         Verb *the_verb;

         the_verb = (Verb *) the_entity;
         delete the_verb;
         break;

      case OBJ_TYPE_ACTION:
         Action *the_action;

         the_action = (Action *) the_entity;
         delete the_action;
         break;

      case OBJ_TYPE_CHATLINE:
         ChatLine *the_chatline;

         the_chatline = (ChatLine *) the_entity;
         delete the_chatline;
         break;

      case OBJ_TYPE_BULLETIN:
         Bulletin *the_bull;

         the_bull = (Bulletin *) the_entity;
         delete_Bulletin(the_bull);
         break;

      default:
         break;

   }
   return 1;
}


/***********************************************************************
 ** add_fighter - adds a fighter to the list of individuals fighting
 **
 ** Parameters: - the_ind - the individual who is fighting
 **               strike_now - striking this turn or next, 0 for next
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **          -2 if already in the list
 **
 ***********************************************************************/

int Mud::add_fighter(Individual *the_ind, int strike_now)
{
   fighting_ind *new_fight;
   fighting_ind *tmp_fight;

   if (the_ind == NULL)
      return -1;

   new_fight = new_fighting_ind();
   new_fight->next_fighter = NULL;
   new_fight->the_fighter = the_ind;
   new_fight->turn = strike_now;

   tmp_fight = fight_list;
   if (tmp_fight == NULL)
   {
      fight_list = new_fight;
      return 1;
   }

   if (tmp_fight->the_fighter == the_ind)
   {
      delete_fighting_ind(new_fight);
      return -2;
   }

#ifdef DEBUG_FIGHT
   sysmessage("adding: %s\n", new_fight->the_fighter->get_name());
#endif
   while (tmp_fight->next_fighter != NULL)
   {
      if (tmp_fight->next_fighter->the_fighter == the_ind)
      {
         delete_fighting_ind(new_fight);
#ifdef DEBUG_FIGHT
         RAISE(1);
#endif
         return -2;
      }

      tmp_fight = tmp_fight->next_fighter;
   }

   tmp_fight->next_fighter = new_fight;
   return 1;
}

/***********************************************************************
 ** remove_fighter - removes a fighter from the list of individuals fighting
 **
 ** Parameters: - the_ind - the individual who will be removed
 **
 ** Returns:  Nothing
 **
 ***********************************************************************/

int Mud::remove_fighter(Individual *the_ind)
{
   fighting_ind *tmp_fight;
   fighting_ind *prev_fight;

   if ((the_ind == NULL) || (fight_list == NULL))
      return -1;

   tmp_fight = fight_list;
   prev_fight = NULL;

   while ((tmp_fight != NULL) && (tmp_fight->the_fighter != the_ind))
   {
      prev_fight = tmp_fight;
      tmp_fight = tmp_fight->next_fighter;
   } 
 
   if (tmp_fight == NULL)
      return -1;

   (tmp_fight->the_fighter)->clr_target();

   /* if the node to delete is at the root node */
   if (prev_fight == NULL)
   {
      fight_list = tmp_fight->next_fighter;
   }
   else
   {
      prev_fight->next_fighter = tmp_fight->next_fighter;
   }

   /* if we are deleting the one that cur_fighter points, go to the next one */
   if (tmp_fight == cur_fighter)
   {
      if (prev_fight == NULL)
         cur_fighter = fight_list;
      else
         cur_fighter = prev_fight->next_fighter;
   }

   // If the prev_fight was the one deleted, reset it
   if (tmp_fight == prev_fight)
   {
     prev_fight = fight_list;
     while ((prev_fight != NULL) && (prev_fight->next_fighter != cur_fighter))
       prev_fight = prev_fight->next_fighter;
   }

#ifdef DEBUG_FIGHT
   sysmessage("removing: %s\n", tmp_fight->the_fighter->get_name());
#endif
   delete_fighting_ind(tmp_fight);

   return 1;
}


/***********************************************************************
 ** clear_fighter - clears from the list all fighters who are fighting
 **                 this one individual
 **
 ** Parameters: - the_ind - the individual who will be cleared
 **
 ** Returns:  Nothing
 **
 ***********************************************************************/

int Mud::clear_fighter(Individual *the_ind)
{
   fighting_ind *tmp_fight;
   fighting_ind *prev_fight;
   fighting_ind *del_fight;

   if ((the_ind == NULL) || (fight_list == NULL))
      return -1;

   tmp_fight = fight_list;
   prev_fight = NULL;

   while (tmp_fight != NULL)
   {

      if ((tmp_fight->the_fighter)->get_target() == the_ind)
      {
         (tmp_fight->the_fighter)->clr_target();
         if (mainstruct->get_num_attacking(tmp_fight->the_fighter) == 0)
       {
            del_fight = tmp_fight;
            tmp_fight = tmp_fight->next_fighter;
            (del_fight->the_fighter)->stop_fighting();
         }
         else
       {
            prev_fight = tmp_fight;
            tmp_fight = tmp_fight->next_fighter;
         }
      }
      else
      {
         prev_fight = tmp_fight;
         tmp_fight = tmp_fight->next_fighter;
      }
   } 

   return 1;
}


/***********************************************************************
 ** reset_fight_list - resets the list of fighters
 **
 **
 ***********************************************************************/

void Mud::reset_fight_list(void)
{
   cur_fighter = fight_list;
}


/***********************************************************************
 ** get_next_fighter - returns the next fighter in the list
 **
 **
 ***********************************************************************/

fighting_ind *Mud::get_next_fighter(void)
{
   fighting_ind *ret_fighter;

   ret_fighter = cur_fighter;
   if (cur_fighter != NULL)
      cur_fighter = cur_fighter->next_fighter;

   return ret_fighter;
}


/***********************************************************************
 ** get_num_attacking - gets the number of individuals attacking a
 **                     specified individual
 **
 ** Parameters: - the_ind - the individual who will be checked
 **
 ** Returns:  Nothing
 **
 ***********************************************************************/

int Mud::get_num_attacking(Individual *the_ind)
{
   fighting_ind *tmp_fighter;
   int          count = 0;

   tmp_fighter = fight_list;
   while (tmp_fighter != NULL)
   {
      if ((tmp_fighter->the_fighter)->get_target() == the_ind)
         count++;

      tmp_fighter = tmp_fighter->next_fighter;
   }
   return count;
}


/***********************************************************************
 ** load_game_data - loads the current game data from the data file,
 **                  such as the time of day, default start location, 
 **                  etc
 **
 ** Parameters: - error_log - the error log to write to
 **
 ** Returns:  1 for success
 **          -1 for error
 **          -2 for can't open the file
 **          
 **
 ***********************************************************************/

int Mud::load_game_data(ErrLog *error_log)
{
   FILE         *the_file = NULL;
   token_record *the_token;
   Strings      holder;
   Strings      filename;
 

   filename.sprintf("%s%s%s", the_config.basedir.str_show(), DSEP, GAME_DATA);
   /* if we can't open the date file, return an error */
   if ((the_file = xfopen(filename.str_show(), "r", "gamedata_file")) == NULL)
   {
      return -2;
   }

   /* Set timeofday */
   the_token = get_token(the_file, '\0');     
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for time of day in game data file");

      error_log->log_err(holder.str_show(), "load_game_data");
      return -1;
   }
   set_tod((TimeOfDay) atoi(the_token->the_string));

   /* Set day_of_year */
   the_token = get_token(the_file, '\0');     
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for day of year in game data file");

      error_log->log_err(holder.str_show(), "load_game_data");
      return -1;
   }
   set_doy(atoi(the_token->the_string));
   
   /* Set year_of_age */
   the_token = get_token(the_file, '\0');     
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for year of age in game data file");

      error_log->log_err(holder.str_show(), "load_game_data");
      return -1;
   }
   set_yoa(atoi(the_token->the_string));

   /* Set the default start location */
   the_token = get_token(the_file, '\0');     
   def_start_loc = the_token->the_string;

   xfclose(the_file, "gamedata_file");

   return 1;

}


/***********************************************************************
 ** save_game_data - writes the current game data to the data file
 **
 ** Parameters: - error_log - the error log to write to
 **
 ** Returns:  1 for success
 **          -1 for error
 **          -2 for can't open the file
 **          
 **
 ***********************************************************************/

int Mud::save_game_data(ErrLog *error_log)
{
   FILE    *the_file = NULL;
   Strings  filename;

   /* if we can't open their user file, they carry nothing */
   filename.sprintf("%s%s%s", the_config.basedir.str_show(), DSEP, GAME_DATA);
   if ((the_file = xfopen(filename.str_show(), "w+", "gamedata_file")) == NULL)
   {
      error_log->log_err("Error writing to game data file.", 
                                                    "save_game_data");
      return -2;
   }

   fprintf(the_file, "%d\n", (int) time_of_day);
   fprintf(the_file, "%d\n", day_of_year);
   fprintf(the_file, "%d\n", year_of_age);
   fprintf(the_file, "%s\n", def_start_loc.str_show());
   
   xfclose(the_file, "gamedata_file");
   return 1;
}


/***********************************************************************
 ** get_levels - returns the levels database pointer
 **
 **
 ***********************************************************************/

Level_List *Mud::get_levels(void)
{
   return game_levels;
}


/***********************************************************************
 ** sort_playerlist - sort the player list in order dependant on what
 **                   metric is being used to indicate seniority
 **
 **  Parameters: sort_by - what to sort by
 **                 possible: exp, chain name
 **                 
 ** 
 **
 ***********************************************************************/

int Mud::sort_playerlist(char *sort_by)
{
   Player *tmp_prev = NULL;
   Player *tmp_player;
   Player *cur_prev = NULL;
   Player *cur_player = NULL;
   int    value1 = 0;
   int    high_value = 10000;
   int    needs_sort = 0;
   int    the_type; /* 1 - exp */
  
   if (!STRCASECMP("exp", sort_by))
      the_type = 1;
   else
      the_type = 0;

   /* first scan the first element, see if we don't need a sort */
   tmp_player = player_list;
 
   while (tmp_player != NULL)
   {
      if (tmp_prev == NULL)
      {
         tmp_prev = tmp_player;
         tmp_player = tmp_player->get_next_player();
         continue;
      }

      switch(the_type)
      {
         case 1:
            high_value = tmp_prev->get_exp();
            value1 = tmp_player->get_exp();
            break;
         default:
            sysmessage("not supported yet\n");
            break;      
      }

      if (high_value < value1)
      {
         needs_sort = 1;
         break;
      } 
      tmp_prev = tmp_player;
      tmp_player = tmp_player->get_next_player();
   }

   if (!needs_sort)
      return 0;


   /* first scan the first element, see if we don't need a sort */
   cur_player = player_list;
 
   while (cur_player != NULL)
   {
      
      tmp_player = cur_player;
      tmp_prev = NULL;
      while (tmp_player != NULL)
      {

         switch(the_type)
         {
            case 1:
               value1 = tmp_player->get_exp();
               high_value = cur_player->get_exp();
               break;
            default:
               sysmessage("not supported yet\n");
               break;      
         }

         if (high_value < value1)
         {
            tmp_prev->set_next_player(tmp_player->get_next_player());
            if (cur_prev == NULL)
          {
               player_list = tmp_player;
            }
            else
          {
               cur_prev->set_next_player(tmp_player);
          }
            tmp_player->set_next_player(cur_player);
            cur_player = tmp_player;
            tmp_player = tmp_prev->get_next_player();
         } 
         else
       {
            tmp_prev = tmp_player;
            tmp_player = tmp_player->get_next_player();
         }
      }
      cur_prev = cur_player;
      cur_player = cur_player->get_next_player();
   }
   return 1;

   
}


/***********************************************************************
 ** get_def_start_loc - returns the default start location for players
 **
 **
 ***********************************************************************/

char *Mud::get_def_start_loc(void)
{
   return def_start_loc.str_show();
}

/***********************************************************************
 ** set_def_start_loc - sets the default start location for players
 **
 ** Parameters: new_start - the new start location 
 **
 ***********************************************************************/

void Mud::set_def_start_loc(char *new_start)
{
   def_start_loc = new_start;
}


/***********************************************************************
 ** display_races - displays the races in the game
 **
 ** Parameters: the_player - the player to display the races to
 **
 ** Returns: num displayed for success, -1 for failure
 **
 ***********************************************************************/

int Mud::display_races(Player *the_player)
{
   return mudobjects->display_races(the_player);
}


/***********************************************************************
 ** display_inclination - displays the inclination in the game
 **
 ** Parameters: the_player - the player to display the inclinations to
 **
 ** Returns: num displayed for success, -1 for failure
 **
 ***********************************************************************/

int Mud::display_inclinations(Player *the_player)
{
   return mudobjects->display_inclinations(the_player);
}

/***********************************************************************
 ** display_mud_stats - displays the mud performance stats
 **
 ** Parameters: the_player - the player to display to
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int Mud::display_mud_stats(Player *the_player)
{
   the_player->send_plr("&+YCycle Times&*\n");
   the_player->send_plr("&+B---------------------------&*\n\n");
   the_player->send_plr("&+gMin Time (ms): &+w%ld millisecs&*\n", min_cycle);
   the_player->send_plr("&+gMax Time (ms): &+w%ld millisecs&*\n", max_cycle);
   the_player->send_plr("&+gAvg Time (ms): &+w%ld millisecs&*\n\n", avg_cycle);
   the_player->send_plr("&+gNum Cycles: \t&+c%ld&*\n", num_cycle);
   the_player->send_plr("&+gCycle Interval: &+c%ld millisecs&*\n", ((long)
                                       (1000000 / the_config.pollspersec)));
   the_player->send_plr("&+gCycles Lagged: \t%s%ld&*\n\n", 
                  ((lagged_cycle == 0) ? "&+G" : "&+R"), lagged_cycle); 
   return 1;
}

/***********************************************************************
 ** increment_lagged_cycle - increments the number of times the poll cycle
 **                          has been lagged beyond the set poll interval
 **
 ***********************************************************************/

void Mud::increment_lagged_cycle()
{
   lagged_cycle++;
}


/***********************************************************************
 ** has_bulletin - if the object passed in has a bulletin attached to it,
 **                will pass the pointer to the object back
 **
 ** Parameters: the_obj - the object to check for a bulletin
 **
 ** Returns: pointer to the bulletin if attached, NULL if not
 **
 ***********************************************************************/

Bulletin *Mud::has_bulletin(MudObject *the_obj)
{
   Strings holder;
   Area_Dbase *bull_area;
   Entity *tmp_entity;
   Bulletin *the_bull;

   if (the_obj == NULL)
      return NULL;

   holder.sprintf("%s@%s", the_obj->get_name(), the_obj->get_area());
   if ((bull_area = mudobjects->get_area("bulletins")) == NULL)
   {
      mainstruct->log_error("No bulletin area found on game port.", 
                                              "has_bulletin");
      return NULL;
   }

   bull_area->reset_list();
   tmp_entity = bull_area->get_next_obj();
   while (tmp_entity != NULL)
   {
      if (tmp_entity->get_type() != OBJ_TYPE_BULLETIN)
      {
         holder.sprintf("Object '%s' in bulletin area not a bulletin.",
                                             tmp_entity->get_name());
         mainstruct->log_error(holder.str_show(), 
                                              "has_bulletin");
         return NULL;
      }

      the_bull = (Bulletin *) tmp_entity;
      if (!STRCASECMP(holder.str_show(), the_bull->get_loc_str()))
         return the_bull;
      tmp_entity = bull_area->get_next_obj();
   } 
   return NULL;
}


/***********************************************************************
 ** clear_bulletin_users - removes all players from the bulletin board so
 **                        we can do away with it
 **
 ** Returns: num cleared if successful, -1 if failed
 **
 ***********************************************************************/

int Mud::clear_bulletin_users()
{
   Player      *the_player;
   int         counter = 0;
   Inp_Handler *the_handler;

   the_player = player_list;
   while (the_player != NULL)
   {
      the_handler = the_player->get_input_handler();

      if (the_handler->has_handler(bulletin_command_handler))
      {
         the_player->send_plr("Bulletin area reloading.  "
                              "Must boot you from bulletin board.\n");
         while (the_handler->get_command() != bulletin_command_handler)
       {
            if (the_handler->get_command() == bulletin_get_subject)
          {
               the_handler->remove_pop_function();
               the_handler->set_delete_data();
          }

            the_handler->pop_input_handler();
       }
         the_handler->pop_input_handler();
         counter++;
      }
      the_player = the_player->get_next_player();
   }
   return counter;
}


/***********************************************************************
 ** get_timer - gets a pointer to the game timer
 **
 ** Returns: num cleared if successful, -1 if failed
 **
 ***********************************************************************/

#ifdef WIN32
CGameTimer * Mud::get_timer()
#else
Timing *Mud::get_timer()
#endif
{
   return &the_timer;
}


/***********************************************************************
 ** are_ports_combined - returns TRUE if the game and builder port are the
 **                      same port
 ***********************************************************************/

int Mud::are_ports_combined()
{
   return combined_ports;
}


/***********************************************************************
 ** switch_for_builder - switches a player with the socket and puts a
 **                      builder in their place with the same connection
 **
 ** Parameters: the_player - the player we should be switching
 **
 ***********************************************************************/

int Mud::switch_for_builder(Player *the_player)
{
      Player *tmp_player;
      Connection *tmp_conn;

      // First, remove the player from the player list
      tmp_player = get_first_player();
      if (tmp_player = the_player)
            player_list = player_list->get_next_player();
      else
      {
            while ((tmp_player->get_next_player() != NULL) && 
                     (tmp_player->get_next_player() != the_player))
            {
                  tmp_player = tmp_player->get_next_player();
            }
            if (tmp_player->get_next_player() != NULL)
                  tmp_player = tmp_player->get_next_player()->get_next_player();
      }

      // Now yank out his connection
      tmp_conn = the_player->get_connection();
      the_player->set_connection(NULL);
      add_builder(tmp_conn);
      return 1;
}


/***********************************************************************
 ** start_convert - a win32 port function for initiating the code that
 **                 will ask the user if they wish to convert this
 **
 ** Parameters: filename - the name of the file to convert
 **
 ***********************************************************************/


int Mud::start_convert(char *filename)
{
#ifdef WIN32
      CAskConvert dlg;
      CConverter the_converter;

      main_dlg->KillTimer(TIMER_STARTUP);
      dlg.m_filename = filename;
      if ((the_config.conf_flags->get_flag(CF_NOPROMPTCONV)) || (dlg.DoModal() == IDOK))
      {
            the_converter.m_file_from = filename;
            the_converter.m_file_to = filename;
            the_converter.m_file_type = "AIME Version 0.52-0.58";
            the_converter.convert_indicated();
      }
      else
      {
            AfxMessageBox("Mud cannot load.  Either move the file with the wrong version or run "
                              "convert on it to start the mud.");
            main_dlg->initiate_halt();
            return 0;
      }
#else
      sysmessage(_("Error: Win32 code run in non-Win32 mode!\n"));
      raise(11);
#endif
      return 1;
}


/***********************************************************************
 ** unlock_bootstrap - unlocks bootstrap so it will run, used in windows
 **                        threads
 ***********************************************************************/

void Mud::unlock_bootstrap()
{
      boot_locked = 0;
}


/***********************************************************************
 ** get_boot_status - gets where the bootstrap process has proceeded to
 ***********************************************************************/

int Mud::get_boot_status()
{
      return status;
}


/***********************************************************************
 ** set_boot_status - sets where the bootstrap process has proceeded to
 ***********************************************************************/

void Mud::set_boot_status(int new_val)
{
      status = new_val;
}

#endif

Generated by  Doxygen 1.6.0   Back to index