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

object_list.cpp

/**********************************************************************
 ** Object_List class: Functions to control the mudobject database. This
 **                    is the main database for all objects in the mud
 **
 ** Reviewed last: version 0.14
 **
 ** Copyright (C) 2000 George Noel (Slate)
 **
 **   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 OBJECT_LIST_C
#define OBJECT_LIST_C

#include <signal.h>
#ifdef WIN32
#include "../win32/stdafx.h"
#endif
#include "config.h"
#include "sysdep.h"
#include "strings.h"
#include "lexer.h"
#include "mudtypes.h"
#include "mudobject.h"
#include "location.h"
#include "btree.h"
#include "area_dbase.h"
#include "logs.h"
#include "errlog.h"
#include "object_list.h"
#include "mudobject.h"
#include "individual.h"
#include "location.h"
#include "verb.h"
#include "verb_list.h"
#ifdef WIN32
#include "../win32/winport.h"
#else
#include "port.h"
#endif
#include "mud.h"
#include "global.h"
#include "objtype.h"
#include "marker.h"
#include "door.h"
#include "moveable.h"
#include "key.h"
#include "book.h"
#include "mobile.h"
#include "merger.h"
#include "money.h"
#include "weapon.h"
#include "wearable.h"
#include "utils.h"
#include "food.h"
#include "indflags.h"
#include "specials.h"
#include "ability.h"
#include "quest.h"
#include "race.h"
#include "inclination.h"
#include "talent.h"
#include "mask.h"
#include "newfuncts.h"
#include "memchk.h"
#include "dirread.h"

/***********************************************************************
 ** Object_List (constructor) - Creates the object list database, loading
 **                             all area files into the database
 **
 ** Parameters: error_log - the error log to report errors to
 **             quiet_mode - displays output or not
 **
 ** Returns: Nothing
 **
 ***********************************************************************/

Object_List::Object_List(ErrLog *error_log, bool quiet_mode)
{
   int          stringlen;
   Strings      dirname;          
   Strings      holder;
   Strings      full_areaname;
   char         areaname[129]; /* name of the area we're loading */  
   char         *charptr;        /* used to move along string */
   char         *prevptr = NULL; /* used to move along string */
   FILE         *areafile = NULL;       /* the area file we are reading */
   int          results;
   DirRead      *dirptr = NULL;
   Area_Dbase   *temp_area;


   the_dbase.set_del_data();

   loaded = max_lookup = avg_lookup = num_lookups = 0;
   min_lookup = 10000;
   
   if (add_hardcoded(error_log) < 0)
   {
      error_log->log_err("Error loading hardcoded locations.\n", 
                                                       "Object_List");
      return;
   }
   
   dirname.sprintf("%s%s%s%s", the_config.basedir.str_show(), DSEP, AREADIR, DSEP);
   dirptr = new DirRead(dirname.str_show());
   if (!dirptr->is_valid())
   {
      error_log->log_err("Error reading areas directory\n", "Object_List");
      return;
   }

   while ((charptr = dirptr->get_next(".area")) != NULL)
   {
      /* format the string to a correct filename */
      strncpy(areaname, charptr, 128); 
      prevptr = NULL;
      charptr = &areaname[0];
      while ((*charptr) && ((*charptr != '\n') && (*charptr != '\0')))
      {
         charptr++;
      }
      if (*charptr)
         *charptr = '\0';

      full_areaname.sprintf("%s%s%s%s%s", the_config.basedir.str_show(), DSEP, 
                      AREADIR, DSEP, areaname);
      /* open the area file for reading */
      if ((areafile = xfopen(full_areaname.str_show(), "r", "load_area_file")) == NULL)
      {
         holder.sprintf("Error - could not open area %s file.\n", areaname);
         error_log->log_err(holder.str_show(), "Object_List");
      }

      /* we are done with the area filename, so just get the area name */
      charptr = &areaname[0];
      while ((*charptr) && (*charptr != '.'))
      {
         if (*charptr == *DSEP)
            prevptr = charptr;
         charptr++;
      }
      if (prevptr == NULL)
       prevptr = &areaname[0];
      else
         prevptr++;
      *charptr = '\0';
      stringlen = strlen(prevptr);
      strncpy(areaname, prevptr, stringlen);      
      areaname[stringlen] = '\0';


      /* if we successfully opened the file, add the area to the arealist */
      if (areafile != NULL)
      {  
         temp_area = new Area_Dbase(areaname);

         if (!quiet_mode)
             {
            sysmessage("\t\tLoading: %s        %s", areaname, NEWLINE);
            fflush(stdout);
             }
         if ((results = temp_area->load_area(areafile, error_log, 0, 0)) >= 0)
            add_area(temp_area, error_log);
         else if (results == -2)
             {
            status.sprintf("%s%s%s%s%s.area", the_config.basedir.str_show(), 
                     DSEP, AREADIR, DSEP, areaname);
                  delete temp_area;
                  return;
             }          
           else
            delete temp_area;
      }
   }
   if (dirptr != NULL)
     delete dirptr;
  
   if (the_config.conf_flags->get_flag(CF_USEQUESTS))
   {
      if (load_quests(error_log) == -2)
        {
           status.sprintf("%s%s%s%squests.dat", the_config.basedir.str_show(), DSEP, DATA_DIR, DSEP);
           return; 
        }
   }

   if (load_abilities(error_log) == -2)
   {
      status.sprintf("%s%s%s%sabilities.dat", the_config.basedir.str_show(), DSEP, DATA_DIR, DSEP);
        return; 
   }

   if (load_races(error_log) == -2)
   {
      status.sprintf("%s%s%s%sraces.dat", the_config.basedir.str_show(), DSEP, DATA_DIR, DSEP);
        return; 
   }

   if (load_inclinations(error_log) == -2)
   {
      status.sprintf("%s%s%s%sinclinations.dat", the_config.basedir.str_show(), DSEP, DATA_DIR, DSEP);
        return; 
   }

   if (load_talents(error_log) == -2)
   {
      status.sprintf("%s%s%s%stalents.dat", the_config.basedir.str_show(), DSEP, DATA_DIR, DSEP);
        return; 
   }

   if (load_bulletins(error_log) == -2)
   {
      status.sprintf("%s%s%s%sbulletins.dat", the_config.basedir.str_show(), 
                 DSEP, DATA_DIR, DSEP);
      printf("loading bulletins failed.\n");
      return; 
   }

   if (load_masks(error_log) == -2)
   {
      status.sprintf("%s%s%s%smasks.dat", the_config.basedir.str_show(), DSEP, DATA_DIR, DSEP);
        return; 
   }

   coordinate(error_log);
   loaded = 1;
}


/***********************************************************************
 ** Object_List (constructor) - Overloaded, not used
 **
 ** Parameters: None
 **
 ** Returns: Nothing
 **
 ***********************************************************************/

Object_List::Object_List()
{
}


/***********************************************************************
 ** ~Object_List (destructor) - Will soon deallocate all data
 **
 ** Parameters: None
 **
 ** Returns: Nothing
 **
 ***********************************************************************/

Object_List::~Object_List()
{
   /* we need to check to see if anyone is in the bulletin board and
      if so, pop their input handlers to take them out of it */
   mainstruct->clear_bulletin_users();
   empty_objects();
}






/***********************************************************************
 ** get_mudobject - returns a pointer to a mudobject
 **
 ** Parameters: the_area - the area string of where to get it from
 **             the_name - the name of the actual object
 **
 ** Returns: a pointer to the object
 **
 ***********************************************************************/

MudObject *Object_List::get_mudobject(char *the_area, char *the_name)
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */
   Strings    holder; 
   Entity     *results;
   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


   if ((the_name == NULL) || (the_area == NULL))
      return NULL;

   holder = the_name;
   if (holder.num_char('@') > 0)
   {
      the_area = holder.str_show();
      while (*the_area != '@')
         the_area++;
      *the_area = '\0';
      the_area++;
   }

   area_holder = the_dbase.find(the_area);

   if (area_holder == NULL)
      return NULL;
  
   results = area_holder->get_areaobject(holder.str_show());


#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_start, 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


   if (loaded)
   {
      num_lookups++;
      if (timespan > max_lookup)
         max_lookup = timespan;

      if (timespan < min_lookup)
         min_lookup = timespan;

      avg_lookup = ((avg_lookup*(num_lookups-1)) + timespan) / num_lookups;
   }

   if ((results == NULL) || (!results->is_a_mudobject()))
   {
      return NULL;
   }

   return (MudObject *) results;
}


/***********************************************************************
 ** get_special_obj - returns a pointer to a special if found
 **
 ** Parameters: the_area - the area string of where to get it from
 **             the_name - the name of the actual object
 **
 ** Returns: a pointer to the object
 **
 ***********************************************************************/

Specials *Object_List::get_special_obj(char *the_area, char *the_name)
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */
   Strings    holder; 
   Entity     *results;
   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


   if ((the_name == NULL) || (the_area == NULL))
      return NULL;

   holder = the_name;
   if (holder.num_char('@') > 0)
   {
      the_area = holder.str_show();
      while (*the_area != '@')
         the_area++;
      *the_area = '\0';
      the_area++;
   }

   area_holder = the_dbase.find(the_area);
  
   if (area_holder == NULL)
   {
      return NULL;
   }

   if ((results = area_holder->get_areaobject(holder.str_show())) == NULL)
      return NULL;


#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_start, 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


   if (loaded)
   {
      num_lookups++;
      if (timespan > max_lookup)
         max_lookup = timespan;

      if (timespan < min_lookup)
         min_lookup = timespan;

      avg_lookup = ((avg_lookup*(num_lookups-1)) + timespan) / num_lookups;
   }

   if (results->get_type() != OBJ_TYPE_SPECIAL)
      return NULL;

   return (Specials *) results;
}


/***********************************************************************
 ** get_ability_obj - returns a pointer to an ability if found
 **
 ** Parameters: the_area - the area string of where to get it from
 **             the_name - the name of the actual object
 **
 ** Returns: a pointer to the object
 **
 ***********************************************************************/

Ability *Object_List::get_ability_obj(char *the_name)
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */
   Entity     *results;
   long       timespan;


#if defined( AIME_WIN32 )
   FILETIME time_start, time_end;

   GetSystemTimeAsFileTime( &time_start );

#else
   struct timeval time_start, time_end;

   gettimeofday(&time_start, NULL);
#endif


   if (the_name == NULL)
      return NULL;

   area_holder = the_dbase.find("abilities");
  
   if (area_holder == NULL)
   {
      mainstruct->log_error("Abilities area should exist but doesnt.", 
                                            "get_ability_obj");
      return NULL;
   }

   if ((results = area_holder->get_areaobject(the_name)) == NULL)
      return NULL;


#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
   gettimeofday(&time_start, 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


   if (loaded)
   {
      num_lookups++;
      if (timespan > max_lookup)
         max_lookup = timespan;

      if (timespan < min_lookup)
         min_lookup = timespan;

      avg_lookup = ((avg_lookup*(num_lookups-1)) + timespan) / num_lookups;
   }

   if (!results->is_an_ability())
      return NULL;

   return (Ability *) results;
}


/***********************************************************************
 ** delete_obj - deletes the mudobject
 **
 ** Parameters: the_obj - the object getting deleted
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int Object_List::delete_obj(MudObject *the_obj)
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */

   if (the_obj == NULL)
      return -1;

   area_holder = the_dbase.find(the_obj->get_area());
  
   if (area_holder == NULL)
   {
      return -1;
   }

   return area_holder->delete_areaobject(the_obj->get_name());
}


/***********************************************************************
 ** remove_obj - removes the mudobject, but does not delete it
 **
 ** Parameters: the_obj - the object getting removed
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int Object_List::remove_obj(MudObject *the_obj)
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */

   if (the_obj == NULL)
      return -1;

   area_holder = the_dbase.find(the_obj->get_area());
  
   if (area_holder == NULL)
   {
      return -1;
   }

   return area_holder->remove_areaobject(the_obj);
}


/***********************************************************************
 ** add_area - adds an area to the mud database
 **
 ** Parameters: area_name - the name of the area to add
 **             error_log - the log to report errors to
 **
 ** Returns:  1 for success
 **          -1 for failure
 **
 ***********************************************************************/

int Object_List::add_area(Area_Dbase *temp_area, ErrLog *error_log)
{
   Strings holder;
    
   if (temp_area == NULL)
      return -1;

   if (the_dbase.add(temp_area->get_areaname(), temp_area) <= 0)
   {
      holder.sprintf("Error creating area '%s' in database\n", 
                                                  temp_area->get_areaname());
      error_log->log_err(holder.str_show(), "add_area");
      return -1;
   }
   return 1;
}

/***********************************************************************
 ** add_mudobject - adds a mudobject to the database
 **
 ** Parameters: the_area - the name of the area to add it to
 **             the_object - the object to be added
 **
 ** Returns:  1 for success
 **          -1 for failure
 **
 ***********************************************************************/

int Object_List::add_mudobject(char *the_area, MudObject *the_object)
{
   Area_Dbase *area_holder;

   area_holder = the_dbase.find(the_area);
   if (area_holder == NULL)
   {
      return -1;
   }

   return area_holder->add_areaobject(the_object);
}


/***********************************************************************
 ** is_location - is this mudobject a location?
 **
 ** Parameters: the_object - the mudobject to check
 **
 ** Returns:  pointer to the location if it is a location
 **           NULL if it is not a location
 **
 ***********************************************************************/

Location *Object_List::is_location(MudObject *the_object)
{
   Location *temp_loc;

   /* if they have sent us an empty mudobject */
   if (the_object == NULL)
      return NULL;

   /* if this is not a location object, we won't convert it */
   if (the_object->get_type() != OBJ_TYPE_LOCATION)
      return NULL;

   /* convert it over */
   temp_loc = (Location *) the_object;

   return temp_loc;
}

/***********************************************************************
 ** coordinate - takes the list of objects and checks for invalid exit
 **              links and also adds objects to other object's
 **              inventories.
 **
 ** Parameters: error_log - the error log to report errors to
 **
 ** Returns: Nothing
 **
 ***********************************************************************/

int Object_List::coordinate(ErrLog *error_log)
{
   Area_Dbase *cur_area = NULL;  /* holds a temp area for checking */
   Strings   holder;

   the_dbase.reset_current();
   cur_area = the_dbase.get_next();
   while (cur_area != NULL)
   {
      cur_area->coord_area1(error_log, this);
      cur_area = the_dbase.get_next();
   }

   the_dbase.reset_current();
   cur_area = the_dbase.get_next();
   while (cur_area != NULL)
   {
      cur_area->coord_area2(error_log, this);
      cur_area = the_dbase.get_next();
   }
      
   return 1;
}


/***********************************************************************
 ** add_hardcoded - adds hardcoded rooms, or rooms that we can fall back
 **                 on that have to be there to prevent crashes, like a
 **                 player being assigned to a room that disappears at
 **                 reload
 **
 ** Parameters: ErrLog - the error log to send errors to
 **
 ** Returns:  1 for success
 **          -1 for failed
 **
 ***********************************************************************/

int Object_List::add_hardcoded(ErrLog *error_log)
{
   Location  *void_loc;
   Area_Dbase *tmp_area;
   Mobile    *ghost_mob;

   tmp_area = new Area_Dbase(the_config.hardcoded_areaname.str_show());
   add_area(tmp_area, error_log);

   void_loc = new_Location(the_config.backup_locname.str_show(), 
                                      the_config.hardcoded_areaname.str_show());
   void_loc->set_title(the_config.backup_loctitle.str_show());
   void_loc->set_desc(0, the_config.backup_locdesc.str_show());
   void_loc->set_desc(1, the_config.backup_locdesc.str_show());
   void_loc->set_desc(2, the_config.backup_locdesc.str_show());

   if (add_mudobject(the_config.hardcoded_areaname.str_show(), 
                                                      (MudObject *) void_loc) < 1)
   {
      raise(11);   
   }
  
   void_loc = new_Location(the_config.entry_locname.str_show(), 
                                   the_config.hardcoded_areaname.str_show());
   void_loc->set_title(the_config.entry_loctitle.str_show());
   void_loc->set_desc(0, the_config.entry_locdesc.str_show());

   if (add_mudobject(the_config.hardcoded_areaname.str_show(), 
                                                   (MudObject *) void_loc) < 1)
   {
      raise(11);   
   }

   /* create the ghost mobile so we can clone it later on */
   ghost_mob = new_Mobile(the_config.ghost_name.str_show(), 
                          the_config.hardcoded_areaname.str_show());
   ghost_mob->set_title(the_config.ghost_title.str_show());
   ghost_mob->set_brief(the_config.ghost_brief.str_show());
   ghost_mob->set_desc(the_config.ghost_desc.str_show());
   ghost_mob->set_altname(the_config.ghost_altnames.str_show());
   ghost_mob->set_loc_str("none");
   (ghost_mob->get_indflags())->set_flag(INDFLAG_GHOST);

   add_mudobject(the_config.hardcoded_areaname.str_show(), ghost_mob);

   return 1;
}


/***********************************************************************
 ** reset_list - resets the dbase object list to the beginning
 **
 ** Parameters: None
 **
 ** Returns:  1 if success
 **
 ***********************************************************************/

void Object_List::reset_list()
{
   the_dbase.reset_current();
}
   

/***********************************************************************
 ** get_next_area - gets the next area in the database
 **
 ** Parameters: None
 **
 ** Returns:  a pointer to the object if a success
 **           NULL if at the end of the list
 **
 ***********************************************************************/

Area_Dbase *Object_List::get_next_area()
{
   return the_dbase.get_next();
}


/***********************************************************************
 ** clone_object - creates a copy of the object, giving it a slightly
 **                different name. Loads the object into the database
 **                into the hardcoded cloned zone and returns a pointer 
 **                to that object
 **
 ** Parameters: orig-obj - the original object we are cloning
 **
 ** Returns: a pointer to the new cloned object
 **
 ***********************************************************************/

MudObject *Object_List::clone_object(MudObject *orig_obj)
{
   MudObject *new_object = NULL;
   Strings   new_name;
   MudObject *parent_obj = NULL;

   if (orig_obj->get_parent() != NULL)
   {
      if ((parent_obj = get_mudobject(orig_obj->get_area(), 
                                        orig_obj->get_parent())) == NULL)
      {
         return NULL;
      }
   }
   else
      parent_obj = orig_obj;

   while (new_object == NULL)
   {
      new_name.sprintf("%s%ld", parent_obj->get_name(), 
                                          parent_obj->get_next_cloned());

      new_object = (MudObject *)orig_obj->copy_obj(new_name.str_show());
      new_object->set_area(orig_obj->get_area());
      
      if (new_object->is_merger())
      {
         if (((Merger *) new_object)->get_number_of() <= 0)
            ((Merger *) new_object)->set_number_of(1);
      }
      
      parent_obj->increment_cloned();
      if (add_mudobject(new_object->get_area(), new_object) <= 0)
      {
         if (new_object != NULL)
            mainstruct->delete_entity(new_object);

         new_object = NULL;
      }
   }
   new_object->set_parent(parent_obj->get_name());

   return new_object;
}


/***********************************************************************
 ** display_data - displays object database statistics
 **                
 **
 ** Parameters: the_player - who we send the messages to
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int Object_List::display_data(Player *the_player)
{
   int num_obj = 0;
   int num_areas = 0;
   Area_Dbase *tmp_area;

   the_dbase.reset_current();
   tmp_area = the_dbase.get_next();
   while (tmp_area != NULL)
   {
      num_areas++;
      num_obj += tmp_area->get_num_obj_loaded();
      tmp_area = the_dbase.get_next();
   }
   the_player->send_plr("\n&+GObject Database Statistics&*\n");
   the_player->send_plr("&+B-----------------------------&*\n\n");
   the_player->send_plr("Number of areas loaded: \t&+W%ld&*\n\n", num_areas);
   the_player->send_plr("Number of objects loaded: \t%ld\n\n", num_obj);
   the_player->send_plr("&+gMax Lookup Time (microseconds)&+b: &+W%ld&*\n", 
                                                                max_lookup);
   the_player->send_plr("&+gAvg Lookup Time (microseconds)&+b: &+W%ld&*\n", 
                                                                avg_lookup);
   the_player->send_plr("&+gMin Lookup Time (microseconds)&+b: &+W%ld&*\n\n",
                                                                min_lookup);
   return 1;
}


/***********************************************************************
 ** display_list_data - displays a list of areas and the data associated
 **                     with them
 **                
 **
 ** Parameters: the_player - who we send the messages to
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int Object_List::display_list_data(Player *the_player)
{
   Area_Dbase *tmp_area;
   int        count = 0;

   the_player->send_plr("\n&+GGame area listing&*\n\n");
   the_player->send_plr(
   "&+W                Num     Num    Secs Since    Reload    Memory&*\n"
   "&+WName           MudObj  Clones  Last Reload  Interval    Used&*\n");
   the_player->send_plr("&+B----------------------------------------"
                        "---------------------------&*\n");
  
   the_dbase.reset_current();
   tmp_area = the_dbase.get_next();
   while (tmp_area != NULL)
   {
      tmp_area->display_brief_data(the_player);
      count++;
      tmp_area = the_dbase.get_next();
   }
   
   the_player->send_plr("&+B----------------------------------------"
                        "---------------------------&*\n");
   the_player->send_plr("&+GNumber of areas: &+W%d&*\n\n", count);
   return 1;
}


void Object_List::save_state(void)
{
   the_dbase.push_current();
}

void Object_List::restore_state(void)
{
   the_dbase.pop_current();
}


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

int Object_List::load_abilities(ErrLog *error_log) 
{
   FILE *abilities_file = NULL;
   Strings filename;
   Area_Dbase *tmp_area;
   int results;

   filename.sprintf("%s/%s/abilities.dat", the_config.basedir.str_show(),
                                                                    DATA_DIR);
   if ((abilities_file = xfopen(filename.str_show(), "r", 
                                                 "ability_file")) == NULL)
   {
      error_log->log_err("Error, could not open abilities file!", 
                                                     "load_abilities");
      return -1;
   }

   /* if we successfully opened the file, add the area to the arealist */
   if (abilities_file != NULL)
   {  
      tmp_area = new Area_Dbase("abilities");

      if ((results = tmp_area->load_area(abilities_file, error_log, 0, 0)) >= 0)
         add_area(tmp_area, error_log);
      else if (results == -2)
        {
           delete tmp_area;
             return -2;
        }
        else
         delete tmp_area;
   }
   return 1;
}

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

int Object_List::load_races(ErrLog *error_log) 
{
   FILE *races_file = NULL;
   Strings filename;
   Area_Dbase *tmp_area;
   int        results;

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

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

      if ((races_file = xfopen(filename.str_show(), "w",
                                           "races_create")) == NULL)
      {
         printf("Fatal Error, could not create quests file!\n");
         exit(0);
      }

      fprintf(races_file, "^%s^\n^^\n^^\n\n", FULLVERSION);
      xfclose(races_file, "races_create");

      if ((races_file = xfopen(filename.str_show(), "r", 
                                            "race_file")) == NULL)
      {
         error_log->log_err("Error, could not open races file!", 
                                            "load_races");
         return -1;
      }
   }

   /* if we successfully opened the file, add the area to the arealist */
   if (races_file != NULL)
   {  
      tmp_area = new Area_Dbase("races");

      if ((results = tmp_area->load_area(races_file, error_log, 0, 0)) >= 0)
         add_area(tmp_area, error_log);
      else if (results == -2)
        {
           delete tmp_area;
             return -2;
        }
      else
         delete tmp_area;
   }

   return 1;
}


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

int Object_List::load_inclinations(ErrLog *error_log) 
{
   FILE *inclinations_file = NULL;
   Strings filename;
   Area_Dbase *tmp_area;
   int        results;

   filename.sprintf("%s/%s/inclinations.dat", the_config.basedir.str_show(), 
                                                                    DATA_DIR);
   if ((inclinations_file = xfopen(filename.str_show(), "r", 
                                                  "inclinations_file")) == NULL)
   {
#ifndef WIN32
      char       user_input[11];

      printf("The Inclination data file is missing.  "
             "Would you like to create it? (y/n) ");
      fflush(stdout);

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

      if ((inclinations_file = xfopen(filename.str_show(), "w",
                                           "inclinations_create")) == NULL)
      {
         printf("Fatal Error, could not create inclinations file!\n");
         exit(0);
      }

      fprintf(inclinations_file, "^%s^\n^^\n^^\n\n", FULLVERSION);
      xfclose(inclinations_file, "inclinations_create");

      if ((inclinations_file = xfopen(filename.str_show(), "r", 
                                            "inclination_file")) == NULL)
      {
         error_log->log_err("Error, could not open inclinations file!", 
                                            "load_inclinations");
         return -1;
      }
   }

   /* if we successfully opened the file, add the area to the arealist */
   if (inclinations_file != NULL)
   {  
      tmp_area = new Area_Dbase("inclinations");

      if ((results = tmp_area->load_area(inclinations_file, error_log, 0, 0)) >= 0)
         add_area(tmp_area, error_log);
      else if (results == -2)
        {
           delete tmp_area;
             return -2;
        }
      else
         delete tmp_area;
   }

   return 1;
}


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

int Object_List::load_talents(ErrLog *error_log) 
{
   FILE *talents_file = NULL;
   Strings filename;
   Area_Dbase *tmp_area;
   int        results;

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

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

      if ((talents_file = xfopen(filename.str_show(), "w",
                                           "talents_create")) == NULL)
      {
         printf("Fatal Error, could not create quests file!\n");
         exit(0);
      }

      fprintf(talents_file, "^%s^\n^^\n^^\n\n", FULLVERSION);
      xfclose(talents_file, "talents_create");

      if ((talents_file = xfopen(filename.str_show(), "r", 
                                            "talent_file")) == NULL)
      {
         error_log->log_err("Error, could not open talents file!", 
                                            "load_talents");
         return -1;
      }
   }

   /* if we successfully opened the file, add the area to the arealist */
   if (talents_file != NULL)
   {  
      tmp_area = new Area_Dbase("talents");

      if ((results = tmp_area->load_area(talents_file, error_log, 0, 0)) >= 0)
         add_area(tmp_area, error_log);
      else if (results == -2)
        {
           delete tmp_area;
             return -2;
        }
      else
         delete tmp_area;
   }

   return 1;
}


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

int Object_List::load_masks(ErrLog *error_log) 
{
   FILE *masks_file = NULL;
   Strings filename;
   Area_Dbase *tmp_area;
   int        results;

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

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

      if ((masks_file = xfopen(filename.str_show(), "w",
                                           "masks_create")) == NULL)
      {
         printf("Fatal Error, could not create quests file!\n");
         exit(0);
      }

      fprintf(masks_file, "^%s^\n^^\n^^\n\n", FULLVERSION);
      xfclose(masks_file, "masks_create");

      if ((masks_file = xfopen(filename.str_show(), "r", 
                                            "mask_file")) == NULL)
      {
         error_log->log_err("Error, could not open masks file!", 
                                            "load_masks");
         return -1;
      }
   }

   /* if we successfully opened the file, add the area to the arealist */
   if (masks_file != NULL)
   {  
      tmp_area = new Area_Dbase("masks");

      if ((results = tmp_area->load_area(masks_file, error_log, 0, 0)) >= 0)
         add_area(tmp_area, error_log);
      else if (results == -2)
        {
           delete tmp_area;
             return -2;
        }
      else
         delete tmp_area;
   }

   return 1;
}


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

int Object_List::load_bulletins(ErrLog *error_log) 
{
   FILE *bull_file = NULL;
   Strings filename;
   Strings dirname;
   Area_Dbase *tmp_area;
   int        results;
   DirRead *dirptr = NULL;

   filename.sprintf("%s/%slist", the_config.basedir.str_show(), BULLETINDIR);


   dirname.sprintf("%s%s%s", the_config.basedir.str_show(), 
               DSEP, BULLETINDIR);

   dirptr = new DirRead(dirname.str_show());
   if (!dirptr->is_valid())
   {
      error_log->log_err("Error, could not get bulletin directory!", 
                                                     "load_bulletin");
      return -1;
   }

   /* if we successfully opened the file, add the area to the arealist */
   tmp_area = new Area_Dbase("bulletins");

   if ((results = tmp_area->load_area(dirptr, "btn", error_log, 0, 0)) >= 0)
   {
      add_area(tmp_area, error_log);
   }
   else if (results == -2)
   {
     delete dirptr;
     delete tmp_area;
       return -2;
   }
   else
   {
     delete tmp_area;
   }
   delete dirptr;

   return 1;
}


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

int Object_List::load_quests(ErrLog *error_log) 
{
   FILE *quests_file = NULL;
   Strings filename;
   Area_Dbase *tmp_area;
   int        results;

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

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

      if ((quests_file = xfopen(filename.str_show(), "w",
                                           "quests_create")) == NULL)
      {
         printf("Fatal Error, could not create quests file!\n");
         exit(0);
      }

      fprintf(quests_file, "^%s^\n^^\n^^\n\n", FULLVERSION);
      xfclose(quests_file, "quests_create");

      if ((quests_file = xfopen(filename.str_show(), "r", 
                                            "quest_file")) == NULL)
      {
         error_log->log_err("Error, could not open quests file!", 
                                            "load_quests");
         return -1;
      }
   }

   /* if we successfully opened the file, add the area to the arealist */
   if (quests_file != NULL)
   {  
      tmp_area = new Area_Dbase("quests");

      if ((results = tmp_area->load_area(quests_file, error_log, 0, 0)) >= 0)
         add_area(tmp_area, error_log);
      else if (results == -2)
        {
           delete tmp_area;
             return -2;
        }
      else
         delete tmp_area;
   }

   return 1;
}


/***********************************************************************
 ** list_quests - lists the quests available to the players
 **
 ** Parameters: - the_player - the player to list to
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/

int Object_List::list_quests(Player *the_player) 
{
   Area_Dbase *quest_dbase;
   Entity     *tmp_entity;
   Quest      *fir_quest;
   Quest      *sec_quest;
   Strings    whitespace1;
   Strings    whitespace2;
   Strings    holder;

   quest_dbase = the_dbase.find("quests");
  
   if (quest_dbase == NULL)
   {
      return -1;
   }

   the_player->send_plr(
     "                        &+CQuest Information&*\n\n"
     "  &+Y Name             Req  Pts     Name             Req  Pts&*\n"
     "&+B____________________________________________________________&*\n");
 
   quest_dbase->reset_list();
   tmp_entity = quest_dbase->get_next_obj();

   while (tmp_entity != NULL)
   {
      if (tmp_entity->get_type() != OBJ_TYPE_QUEST)
         return -1;
      fir_quest = (Quest *) tmp_entity;

      tmp_entity = quest_dbase->get_next_obj();
      if (tmp_entity != NULL)
      {
         if (tmp_entity->get_type() != OBJ_TYPE_QUEST)
            return -1;
         sec_quest = (Quest *) tmp_entity;
      }
      else
         sec_quest = NULL;


      whitespace1 = "                ";
      whitespace1.truncate(16 - strlen(fir_quest->get_name()));

      whitespace2 = "                ";
      if (sec_quest != NULL)
      {
         whitespace2.truncate(16 - strlen(sec_quest->get_name()));
         the_player->send_plr(
         "&+B| &+W%s%s &+B| &+Y%s &+B|  &+W%d  &+B|"
              "| &+W%s%s &+B| &+Y%s &+B|  &+W%d  &+B|&*\n", 
           fir_quest->get_name(), whitespace1.str_show(), 
           fir_quest->get_required() ? "*" : " ", fir_quest->get_qpoints(),   
           sec_quest->get_name(), whitespace2.str_show(), 
           sec_quest->get_required() ? "*" : " ", sec_quest->get_qpoints());
      }
      else
      {
         the_player->send_plr(
         "&+B| &+W%s%s &+B| &+Y%s &+B|  &+W%d  &+B|"
              "| &+W%s &+B| &+Y  &+B|     |&*\n", 
           fir_quest->get_name(), whitespace1.str_show(), 
           fir_quest->get_required() ? "*" : " ", fir_quest->get_qpoints(), 
           whitespace2.str_show());
      }
      tmp_entity = quest_dbase->get_next_obj();
   }

   the_player->send_plr(
     "&+B------------------------------------------------------------&*\n");
   return 1;

}


/***********************************************************************
 ** get_quest_obj - returns a pointer to an quest if found
 **
 ** Parameters: the_area - the area string of where to get it from
 **             the_name - the name of the actual object
 **
 ** Returns: a pointer to the object
 **
 ***********************************************************************/

Quest *Object_List::get_quest_obj(char *the_name)
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */
   Entity     *results;
   long       timespan;


#if defined( AIME_WIN32 )
   FILETIME time_start, time_end;

   GetSystemTimeAsFileTime( &time_start );

#else
   struct timeval time_start, time_end;

   gettimeofday(&time_start, NULL);
#endif

   
   if (the_name == NULL)
      return NULL;

   area_holder = the_dbase.find("quests");
  
   if (area_holder == NULL)
   {
      mainstruct->log_error("Quests area should exist but doesnt.", 
                                            "get_quest_obj");
      return NULL;
   }

   if ((results = area_holder->get_areaobject(the_name)) == NULL)
      return NULL;


#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
        gettimeofday(&time_start, 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


   if (loaded)
   {
      num_lookups++;
      if (timespan > max_lookup)
         max_lookup = timespan;

      if (timespan < min_lookup)
         min_lookup = timespan;

      avg_lookup = ((avg_lookup*(num_lookups-1)) + timespan) / num_lookups;
   }

   if (results->get_type() != OBJ_TYPE_QUEST)
      return NULL;

   return (Quest *) results;
}



/***********************************************************************
 ** get_race_obj - returns a pointer to an race if found
 **
 ** Parameters: the_area - the area string of where to get it from
 **             the_name - the name of the actual object
 **
 ** Returns: a pointer to the object
 **
 ***********************************************************************/

Race *Object_List::get_race_obj(char *the_name)
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */
   Entity     *results;
   long       timespan;


#if defined( AIME_WIN32 )
   FILETIME time_start, time_end;

   GetSystemTimeAsFileTime( &time_start );

#else
   struct timeval time_start, time_end;

   gettimeofday(&time_start, NULL);
#endif


   if (the_name == NULL)
      return NULL;

   area_holder = the_dbase.find("races");
  
   if (area_holder == NULL)
   {
      mainstruct->log_error("Races area should exist but doesnt.", 
                                            "get_race_obj");
      return NULL;
   }

   if ((results = area_holder->get_areaobject(the_name)) == NULL)
      return NULL;

   
#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
        gettimeofday(&time_start, 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


   if (loaded)
   {
      num_lookups++;
      if (timespan > max_lookup)
         max_lookup = timespan;

      if (timespan < min_lookup)
         min_lookup = timespan;

      avg_lookup = ((avg_lookup*(num_lookups-1)) + timespan) / num_lookups;
   }

   if (results->get_type() != OBJ_TYPE_RACE)
      return NULL;

   return (Race *) results;
}


/***********************************************************************
 ** get_inclination_obj - returns a pointer to an inclinatino if found
 **
 ** Parameters: the_area - the area string of where to get it from
 **             the_name - the name of the actual object
 **
 ** Returns: a pointer to the object
 **
 ***********************************************************************/

Inclination *Object_List::get_inclination_obj(char *the_name)
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */
   Entity     *results;
   long       timespan;


#if defined( AIME_WIN32 )
   FILETIME time_start, time_end;

   GetSystemTimeAsFileTime( &time_start );

#else
   struct timeval time_start, time_end;

   gettimeofday(&time_start, NULL);
#endif


   if (the_name == NULL)
      return NULL;

   area_holder = the_dbase.find("inclinations");
  
   if (area_holder == NULL)
   {
      mainstruct->log_error("Inclinations area should exist but doesnt.", 
                                            "get_inclination_obj");
      return NULL;
   }

   if ((results = area_holder->get_areaobject(the_name)) == NULL)
      return NULL;


#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
        gettimeofday(&time_start, 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


   if (loaded)
   {
      num_lookups++;
      if (timespan > max_lookup)
         max_lookup = timespan;

      if (timespan < min_lookup)
         min_lookup = timespan;

      avg_lookup = ((avg_lookup*(num_lookups-1)) + timespan) / num_lookups;
   }

   if (results->get_type() != OBJ_TYPE_INCLINAT)
      return NULL;

   return (Inclination *) results;
}


/***********************************************************************
 ** get_talent_obj - returns a pointer to an talent if found
 **
 ** Parameters: the_area - the area string of where to get it from
 **             the_name - the name of the actual object
 **
 ** Returns: a pointer to the object
 **
 ***********************************************************************/

Talent *Object_List::get_talent_obj(char *the_name)
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */
   Entity     *results;
   long       timespan;


#if defined( AIME_WIN32 )
   FILETIME time_start, time_end;

   GetSystemTimeAsFileTime( &time_start );

#else
   struct timeval time_start, time_end;

   gettimeofday(&time_start, NULL);
#endif


   if (the_name == NULL)
      return NULL;

   area_holder = the_dbase.find("talents");
  
   if (area_holder == NULL)
   {
      mainstruct->log_error("Talents area should exist but doesnt.", 
                                            "get_talent_obj");
      return NULL;
   }

   if ((results = area_holder->get_areaobject(the_name)) == NULL)
      return NULL;


#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
        gettimeofday(&time_start, 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


   if (loaded)
   {
      num_lookups++;
      if (timespan > max_lookup)
         max_lookup = timespan;

      if (timespan < min_lookup)
         min_lookup = timespan;

      avg_lookup = ((avg_lookup*(num_lookups-1)) + timespan) / num_lookups;
   }

   if (results->get_type() != OBJ_TYPE_TALENT)
      return NULL;

   return (Talent *) results;
}


/***********************************************************************
 ** get_mask_obj - returns a pointer to a mask if found
 **
 ** Parameters: the_name - the name of the actual object
 **
 ** Returns: a pointer to the object
 **
 ***********************************************************************/

Mask *Object_List::get_mask_obj(char *the_name)
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */
   Entity     *results;
   long       timespan;


#if defined( AIME_WIN32 )
   FILETIME time_start, time_end;

   GetSystemTimeAsFileTime( &time_start );

#else
   struct timeval time_start, time_end;

   gettimeofday(&time_start, NULL);
#endif


   if (the_name == NULL)
      return NULL;

   area_holder = the_dbase.find("masks");
  
   if (area_holder == NULL)
   {
      mainstruct->log_error("Masks area should exist but doesnt.", 
                                            "get_mask_obj");
      return NULL;
   }

   if ((results = area_holder->get_areaobject(the_name)) == NULL)
      return NULL;


#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
        gettimeofday(&time_start, 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


   if (loaded)
   {
      num_lookups++;
      if (timespan > max_lookup)
         max_lookup = timespan;

      if (timespan < min_lookup)
         min_lookup = timespan;

      avg_lookup = ((avg_lookup*(num_lookups-1)) + timespan) / num_lookups;
   }

   if (results->get_type() != OBJ_TYPE_MASK)
      return NULL;

   return (Mask *) results;
}


/***********************************************************************
 ** extend_reset - extends the time till reset if applicable
 **
 ** Parameters: - the_ind - the individual who is in the area to extend
 **               new_val - the num of seconds to extend it
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/

int Object_List::extend_reset(Individual *the_ind, int new_val) 
{
   Area_Dbase *area_holder;  /* points to the area database we retrieve */
   Location   *ind_loc;
   Strings    holder;
   long       ttr;           // time to reset

   if ((the_ind == NULL) || (new_val<=0))
      return -1;

   ind_loc = the_ind->get_loc();

   area_holder = the_dbase.find(ind_loc->get_area());
  
   if (area_holder == NULL)
   {
      holder.sprintf("Could not get area of individual '%s'", 
                                                     the_ind->get_name());
      mainstruct->log_error(holder.str_show(), "extend_reset");
      return -1;
   }
   
   ttr = area_holder->get_time_till_reset();
   if (ttr == 0)
      return 0;

   if (ttr < new_val)
   {
      area_holder->set_time_till_reset(new_val);
   }
   return 1;
}


/***********************************************************************
 ** get_area - gets the area specified
 **
 ** Parameters: - the_name - the name of the area to get
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/

Area_Dbase *Object_List::get_area(char *the_name) 
{
   return the_dbase.find(the_name);
}


/***********************************************************************
 ** 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 Object_List::display_races(Player *the_player)
{
   Area_Dbase *race_area;
   Entity     *tmp_obj;
   Race       *tmp_race;
   Strings    race_name;
   char       tmp_line[20];
   Strings    holder;
   int        num_in_line = 0;
   int        count = 0;

   if ((race_area = get_area("races")) == NULL)
   {
      mainstruct->log_error("Area 'races' should exist but does not.", 
                                                     "display_races");
      the_player->send_plr("Error, could not read races.\n");
      return -1;
   }

   race_area->reset_list();

   the_player->send_plr("\n\n&+WAvailable Races:&*\n");
   the_player->send_plr("&+B-----------------------------------&*\n");
   while ((tmp_obj = race_area->get_next_obj()) != NULL)
   {
      if (tmp_obj->get_type() != OBJ_TYPE_RACE)
      {
         holder.sprintf("Object '%s' found in races area not a race.", 
                                          tmp_obj->get_name());
         mainstruct->log_error(holder.str_show(), "display_races");
         return -1;
      }
      tmp_race = (Race *) tmp_obj;
      race_name = tmp_race->get_name();
      if (race_name.str_len() > 15)
         race_name.truncate(15);
      race_name.upper(0);
      sprintf(tmp_line, "%-15s", race_name.str_show());
      holder.str_cat(tmp_line);
      num_in_line++;
      if (num_in_line == 3)
      {
         the_player->send_plr("&+g%s&*\n", holder.str_show());
         holder.truncate(0);
         num_in_line = 0;
      }
      count++;
   }
   if (num_in_line > 0)
   {
      the_player->send_plr("&+g%s&*\n", holder.str_show()); 
   }
   the_player->send_plr("\n");
   the_player->send_plr("Type '? <race>' to see a description of the race.\n\n");

   return count;
}


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

int Object_List::display_inclinations(Player *the_player)
{
   Area_Dbase  *inclination_area;
   Entity      *tmp_obj;
   Inclination *tmp_inclination;
   Strings     inclination_name;
   char        tmp_line[20];
   Strings     holder;
   int         num_in_line = 0;
   int         count = 0;
   int         show_all = 0;
   Race        *plr_race;
   Strings     incl_list;

   if ((inclination_area = get_area("inclinations")) == NULL)
   {
      mainstruct->log_error("Area 'inclinations' should exist but does not.", 
                                                     "display_inclinations");
      the_player->send_plr("Error, could not read inclinations.\n");
      return -1;
   }

   inclination_area->reset_list();

   the_player->send_plr("\n\n&+WAvailable Inclinations:&*\n");
   the_player->send_plr("&+B-----------------------------------&*\n");

   if ((plr_race = mainstruct->get_race(the_player->get_race())) == NULL)
   {
     holder.sprintf("Could not get player race '%s'", the_player->get_race());
     mainstruct->log_error(holder.str_show(), "display_inclinations");
     return -1;
   }

   incl_list = plr_race->get_allow_incl();
   if (!STRCASECMP(incl_list.str_show(), "all"))
     show_all = 1;
     
   while ((tmp_obj = inclination_area->get_next_obj()) != NULL)
   {
      if (tmp_obj->get_type() != OBJ_TYPE_INCLINAT)
      {
         holder.sprintf(
              "Object '%s' found in inclinations area not a inclination.", 
                                          tmp_obj->get_name());
         mainstruct->log_error(holder.str_show(), "display_inclinations");
         return -1;
      }
      tmp_inclination = (Inclination *) tmp_obj;

      if (show_all || (incl_list.find_in_str(tmp_inclination->get_name())))
      {
      inclination_name = tmp_inclination->get_name();
      if (inclination_name.str_len() > 15)
        inclination_name.truncate(15);
      inclination_name.upper(0);
      sprintf(tmp_line, "%-15s", inclination_name.str_show());
      holder.str_cat(tmp_line);
      num_in_line++;
      if (num_in_line == 3)
      {
        the_player->send_plr("&+g%s&*\n", holder.str_show());
        holder.truncate(0);
        num_in_line = 0;
      }
      count++;
      }
   }
   if (num_in_line > 0)
   {
      the_player->send_plr("&+g%s&*\n", holder.str_show()); 
   }
   the_player->send_plr("\n");
   the_player->send_plr(
       "Type '? <inclination>' to see a description of the inclination.\n");

   return count;
}



/***********************************************************************
 ** reload_races - reloads the races into memory
 **
 ** Parameters: None
 **
 ** Returns: 1, -1 for failure
 **
 ***********************************************************************/

int Object_List::reload_races(void)
{
   the_dbase.del("races");
   return load_races(mainstruct->get_log());
}

/***********************************************************************
 ** reload_inclinations - reloads the inclinations into memory
 **
 ** Parameters: None
 **
 ** Returns: 1, -1 for failure
 **
 ***********************************************************************/

int Object_List::reload_inclinations(void)
{
   the_dbase.del("inclinations");
   return load_inclinations(mainstruct->get_log());
}

/***********************************************************************
 ** reload_talents - reloads the talents into memory
 **
 ** Parameters: None
 **
 ** Returns: 1, -1 for failure
 **
 ***********************************************************************/

int Object_List::reload_talents(void)
{
   the_dbase.del("talents");
   return load_talents(mainstruct->get_log());
}


/***********************************************************************
 ** reload_abilities - reloads the abilities into memory
 **
 ** Parameters: None
 **
 ** Returns: 1, -1 for failure
 **
 ***********************************************************************/

int Object_List::reload_abilities(void)
{
   the_dbase.del("abilities");
   return load_abilities(mainstruct->get_log());
}

/***********************************************************************
 ** reload_bulletins - reloads the bulletins into memory
 **
 ** Parameters: None
 **
 ** Returns: 1, -1 for failure
 **
 ***********************************************************************/

int Object_List::reload_bulletins(void)
{
   the_dbase.del("bulletins");
   return load_bulletins(mainstruct->get_log());
}

/***********************************************************************
 ** reload_masks - reloads the masks into memory
 **
 ** Parameters: None
 **
 ** Returns: 1, -1 for failure
 **
 ***********************************************************************/

int Object_List::reload_masks(void)
{
   the_dbase.del("masks");
   return load_masks(mainstruct->get_log());
}

/***********************************************************************
 ** has_inclinations - indicates whether any inclinations exist to assign
 **
 ** Parameters: None
 **
 ** Returns: 1 for has them, 0 for not, -1 for failed
 **
 ***********************************************************************/

int Object_List::has_inclinations(void)
{
   Area_Dbase *tmp_area;

   if ((tmp_area = the_dbase.find("inclinations")) == NULL)
      return -1;

   tmp_area->reset_list();
   if (tmp_area->get_next_obj() == NULL)
      return 0;
   return 1;
}

/***********************************************************************
 ** has_talents - indicates whether any talents exist to assign
 **
 ** Parameters: None
 **
 ** Returns: 1 for has them, 0 for not, -1 for failed
 **
 ***********************************************************************/

int Object_List::has_talents(void)
{
   Area_Dbase *tmp_area;

   if ((tmp_area = the_dbase.find("talents")) == NULL)
      return -1;

   tmp_area->reset_list();
   if (tmp_area->get_next_obj() == NULL)
      return 0;
   return 1;
}

/***********************************************************************
 ** player_to_mobile - creates a mobile by the same name as the player
 **                    and copies all attributes of the player to the mobile
 **
 ** Parameters: the_player - the player to make a mobile clone of
 **
 ** Returns: pointer to the new mobile object, NULL for failure
 **
 ***********************************************************************/

Mobile *Object_List::player_to_mobile(Player *the_player)
{
   int        counter = 0;
   Mobile     *new_mob = NULL;
   Entity     *the_search;
   Strings    new_name;
   Strings    holder;
   Area_Dbase *tmp_area;

   if (the_player == NULL)
      return NULL;

   /* get the hardcoded area */
   if ((tmp_area = get_area(the_config.hardcoded_areaname.str_show())) == NULL)
   {
      holder.sprintf("Error, could not find hardcoded area %s", 
                      the_config.hardcoded_areaname.str_show());
      mainstruct->log_error(holder.str_show(), "player_to_mobile");
      return NULL;
   }

   /* first find an available object name */
   new_name.sprintf("%s%d", the_player->get_name(), counter);
   the_search = tmp_area->get_areaobject(new_name.str_show());
   while (the_search != NULL)
   {
      counter++;
      new_name.sprintf("%s%d", the_player->get_name(), counter);
      the_search = tmp_area->get_areaobject(new_name.str_show());
   }

   /* now we create the object */
   new_mob = new_Mobile(new_name.str_show(), 
                        the_config.hardcoded_areaname.str_show());

   /******* set the mudobject attributes *****/
   new_mob->copy_mudobject_attrib((MudObject *) the_player); 

   /******* set the individual attributes *****/
   new_mob->copy_individual_attrib((Individual *) the_player);

   /******* set the mobile attributes *****/
   new_mob->set_brief("A corpse");

   tmp_area->add_areaobject(new_mob);
   return new_mob;
}


/***********************************************************************
 ** get_status - gets the status of the load and if there were any failures
 **              due to version incompatabilities
 **
 ** Returns: NULL if no problems, pointer to the areaname if there were
 **
 ***********************************************************************/

char * Object_List::get_status()
{
      return status.str_show();
}


/***********************************************************************
 ** empty_objects - clears all objects of their inventory that are being
 **                 deleted and removes them from their location
 ***********************************************************************/

int Object_List::empty_objects()
{
      Area_Dbase *tmp_area;

      the_dbase.reset_current();
      tmp_area = the_dbase.get_next();
      while (tmp_area != NULL)
      {
            tmp_area->empty_objects();
            tmp_area = the_dbase.get_next();
      }
      return 1;
}



#endif


Generated by  Doxygen 1.6.0   Back to index