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

mobile.cpp

/**********************************************************************
 ** Mobile class: A mobile is a game character that can usually move around
 **               and interact with the players in various ways, like talking
 **               and fighting
 **
 **
 ** Last reviewed:  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 MOBILE_C
#define MOBILE_C

#include "config.h"
#include "sysdep.h"
#include "strings.h"
#include "mudtypes.h"
#include "mobile.h"
#include "utils.h"
#include "objtype.h"
#include "global.h"
#include "lexer.h"
#include "indflags.h"
#include "newfuncts.h"
#include "locflags.h"


/***********************************************************************
 ** Mobile (constructor) - creates the mobile
 **
 ** Parameters: the_name - the name of the mobile
 **             the_area - the area the mobile belongs to
 **
 ** Returns: Nothing
 **
 ***********************************************************************/

Mobile::Mobile(char *the_name, char *the_area)
{
   /* this should be the only place that this is set */
   obj_type = OBJ_TYPE_MOBILE;
   
   if (the_name != NULL)
      set_name(the_name);
   
   if (the_area != NULL)
      set_area(the_area);

   tell_list = NULL;
   the_shop = NULL;

   speed = the_config.default_speed;
   aggression = rot_timer = 0;
}

/***********************************************************************
 ** ~Mobile (destructor) - destroys it
 **
 ** Parameters: None
 **
 ** Returns: Nothing
 **
 ***********************************************************************/

Mobile::~Mobile()
{
   Com_List *tmp_list;
 
   while (tell_list != NULL)
   {
      tmp_list = tell_list;
      tell_list = tell_list->next_com;
      delete_Com_List(tmp_list);
   }
 
   delete_Shop(the_shop);
}


bool Mobile::can_see_ind(Individual *the_ind)
{
    int the_num;

    if (the_ind->is_visible())
        return true;

    if (the_ind->is_vis_incog() 
    && (the_ind->get_loc())->find_contained(get_name(), &the_num))
        return true;

    return false;
}


/***********************************************************************
 ** write_object - writes the mobile to a specified file in specified
 **                file format
 **
 ** Parameters: the_file - the file to write to
 **             build_format - use builder format or not. 0 for not
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/
   
void Mobile::write_object(FILE *the_file, int build_format)
{
   Com_List *tmp_list;
   Flags *tmp_indflag;

   fprintf(the_file, "\nmob %s\n", get_name());
   if (build_format)
      fprintf(the_file, "%d\n", is_modified());

   write_mudobject_attrib(the_file);

   fprintf(the_file, "^%s^\n", get_brief());
   fprintf(the_file, "^%s^\n", (get_subarea() == NULL) ? "" : get_subarea());
   fprintf(the_file, "%s\n", (get_start_wield(Left) == NULL) ? 
                                        "none" : get_start_wield(Left));
   fprintf(the_file, "%s\n", (get_start_wield(Right) == NULL) ? 
                                        "none" : get_start_wield(Right));
   fprintf(the_file, "^%s^\n", (get_start_wear() == NULL) ? 
                                                     "" : get_start_wear());
   fprintf(the_file, "^%s^\n", (get_bare_weapon() == NULL) ? 
                                                     "" : get_bare_weapon());
   fprintf(the_file, "%d\n", get_strength());
   fprintf(the_file, "%d\n", get_dexterity());
   fprintf(the_file, "%d\n", get_constitution());
   fprintf(the_file, "%d\n", get_intel());
   fprintf(the_file, "%d\n", get_wisdom());
   fprintf(the_file, "%d\n", get_charisma());

   tmp_indflag = get_indflags();
   tmp_indflag->write_flag(the_file);

   fprintf(the_file, "%d\n", get_sex());
   fprintf(the_file, "%d\n", get_vislvl());

   fprintf(the_file, "%d\n", get_speed());
   fprintf(the_file, "%d\n", get_aggression());

   /******** Stuff added for version 0.59.2 *******/
   fprintf(the_file, "%d\n", get_wimpy());
   fprintf(the_file, "%d\n", get_max_magic());
   fprintf(the_file, "%d\n", get_max_endurance());
   write_ranks(the_file);

   tmp_list = tell_list;
   while (tmp_list != NULL)
   {
      fprintf(the_file, "+\n^%s^\n^%s^\n", tmp_list->the_keywords.str_show(), 
                                           tmp_list->the_reply.str_show());
      tmp_list = tmp_list->next_com;
   }
   fprintf(the_file, "#\n\n");

   write_shop(the_file);
}

/***********************************************************************
 ** describe - describes the mobile to a builder
 **
 ** Parameters: the_builder - the person to send all the data to
 **
 ***********************************************************************/

void Mobile::describe(Builder *the_builder)
{
   int counter = 0;
   Com_List *tmp_list;

   the_builder->send_bldr("\n&+G      Mobile: &+M%s&*\n", get_name());
   the_builder->send_bldr("&+G       Title: &+w%s&*\n", get_title());
   the_builder->send_bldr("&+G    Altnames: &+g%s&*\n", get_altname());
   the_builder->send_bldr("&+G      Clones: &+g%s&*\n", get_clones());
   the_builder->send_bldr("&+G    Specials: &+g%s&*\n", get_special_str());
   the_builder->send_bldr("&+G    Subareas: &+g%s&*\n", get_subarea());
   the_builder->send_bldr("&+G  BareWeapon: &+w%s&*\n", get_bare_weapon());
   the_builder->send_bldr("&+G    StartLoc: &+M%s&*\n", get_location());
   the_builder->send_bldr("&+G Wield(Left): &+M%s&*\n", get_start_wield(Left));
   the_builder->send_bldr("&+GWield(Right): &+M%s&*\n", get_start_wield(Right));
   the_builder->send_bldr("&+G        Wear: &+M%s&*\n", get_start_wear());
   the_builder->send_bldr("&+G       Speed: &+w%d&*\n", get_speed());
   the_builder->send_bldr("&+G         Sex: &+w%s&*\n", get_sex_str());
   the_builder->send_bldr("&+G  Aggression: &+w%d&*\n", get_aggression());
   the_builder->send_bldr("&+G    Strength: &+w%d&*\n", get_strength());
   the_builder->send_bldr("&+G   Dexterity: &+w%d&*\n", get_dexterity());
   the_builder->send_bldr("&+GConstitution: &+w%d&*\n", get_constitution());
   the_builder->send_bldr("&+G       Intel: &+w%d&*\n", get_intel());
   the_builder->send_bldr("&+G      Wisdom: &+w%d&*\n", get_wisdom());
   the_builder->send_bldr("&+G    Charisma: &+w%d&*\n", get_charisma());
   the_builder->send_bldr("&+G       Wimpy: &+w%d&*\n", get_wimpy());
   the_builder->send_bldr("&+G    MaxMagic: &+w%d&*\n", get_max_magic());
   the_builder->send_bldr("&+G    MaxEndur: &+w%d&*\n", get_max_endurance());
   the_builder->send_bldr("&+GBrief:&*\n%s\n", get_brief());
   the_builder->send_bldr("&+GDesc:&*\n%s\n", get_desc());

   the_builder->send_bldr("\n");

   if (get_shop() != NULL)
      the_builder->send_bldr("&+G\nShop assigned with name&+W: &+w%s\n\n", the_shop->get_name());

   if (get_ranks() != NULL)
     the_builder->send_bldr("&+GThis mobile has proficiencies assigned to it.&*\n");

   tmp_list = tell_list;
   
   while (tmp_list != NULL)
   {
      counter++;
      the_builder->send_bldr("&+GTell Reply [&+B%d&+G]:\n", counter);
      the_builder->send_bldr("   &+GKeywords: &+g%s\n", tmp_list->the_keywords.str_show());
      the_builder->send_bldr("   &+GReply: \n\t&+w%s&*\n", tmp_list->the_reply.str_show());
      tmp_list = tmp_list->next_com;
   }
}


/***********************************************************************
 ** describe - describes the mobile to a player
 **
 ** Parameters: the_player - the person to send all the data to
 **
 ***********************************************************************/

void Mobile::describe(Player *the_player)
{
   int counter = 0;
   Com_List *tmp_list;
   MudObject *tmp_container;
   Strings   container_name;

   the_player->send_plr("\n&+G      Mobile: &+M%s&*\n", get_name());
   the_player->send_plr("&+G       Title: &+w%s&*\n", get_title());
   the_player->send_plr("&+G    Keywords: &+w%s&*\n", get_keywords());
   the_player->send_plr("&+G    Altnames: &+g%s&*\n", get_altname());
   the_player->send_plr("&+G      Clones: &+g%s&*\n", get_clones());
   the_player->send_plr("&+G    Specials: &+g%s&*\n", get_special_str());
   the_player->send_plr("&+G    StartLoc: &+M%s&*\n", get_location());

   tmp_container = get_contained_by();
   if (tmp_container == NULL)
      container_name = "nowhere";
   else
      container_name.sprintf("%s@%s", tmp_container->get_name(), tmp_container->get_area());

   the_player->send_plr("&+G  CurrentLoc: &+M%s&*\n", container_name.str_show());
   the_player->send_plr("&+G    Subareas: &+g%s&*\n", get_subarea());
   the_player->send_plr("&+G  BareWeapon: &+w%s&*\n", get_bare_weapon());
   the_player->send_plr("&+G Wield(Left): &+M%s&*\n", get_start_wield(Left));
   the_player->send_plr("&+GWield(Right): &+M%s&*\n", get_start_wield(Right));
   the_player->send_plr("&+G        Wear: &+M%s&*\n", get_start_wear());
   the_player->send_plr("&+G       Speed: &+w%d&*\n", get_speed());
   the_player->send_plr("&+G         Sex: &+w%s&*\n", get_sex_str());
   the_player->send_plr("&+G  Aggression: &+w%d&*\n", get_aggression());
   the_player->send_plr("&+G    Strength: &+w%d&*\n", get_strength());
   the_player->send_plr("&+GConstitution: &+w%d&*\n", get_constitution());
   the_player->send_plr("&+G   Dexterity: &+w%d&*\n", get_dexterity());
   the_player->send_plr("&+G      Health: &+w%d\\&+W%d&*\n", get_health(), get_maxhealth());
   the_player->send_plr("&+G       Intel: &+w%d&*\n", get_intel());
   the_player->send_plr("&+G      Wisdom: &+w%d&*\n", get_wisdom());
   the_player->send_plr("&+G    Charisma: &+w%d&*\n", get_charisma());
   the_player->send_plr("&+G       Wimpy: &+w%d&*\n", get_wimpy());
   the_player->send_plr("&+G    MaxMagic: &+w%d&*\n", get_max_magic());
   the_player->send_plr("&+G    MaxEndur: &+w%d&*\n", get_max_endurance());
   the_player->send_plr("&+Y        Size: &+W%d&*\n", get_mem_size());
   the_player->send_plr("&+GBrief:&*\n%s\n", get_brief());
   the_player->send_plr("&+GDesc:&*\n%s\n", get_desc());

   list_specials(the_player);
   the_player->send_plr("\n");

   if (get_shop() != NULL)
      the_player->send_plr("&+G\nShop assigned with name&+W: &+w%s\n\n", the_shop->get_name());

   if (get_ranks() != NULL)
     the_player->send_plr("&+GThis mobile has proficiencies assigned to it.&*\n");

   tmp_list = tell_list;
   while (tmp_list != NULL)
   {
      counter++;
      the_player->send_plr("&+GTell Reply [&+B%d&+G]:\n", counter);
      the_player->send_plr("   &+GKeywords: &+g%s\n", tmp_list->the_keywords.str_show());
      the_player->send_plr("   &+GReply: \n\t&+w%s&*\n", tmp_list->the_reply.str_show());
      tmp_list = tmp_list->next_com;
   }
}


/***********************************************************************
 ** set_attrib - sets a specified attribute to a specified value
 **
 ** Parameters: the_builder - the builder who is changing this attribute
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/
   
int Mobile::set_attrib(Builder *the_builder, Parse *the_parsed){

   if (the_parsed->get_target1() == NULL)
   {   the_builder->
           send_bldr("You can set the following attributes on a mobile.\n"
       "   title, altnames, desc, location, indflags, clones, brief, sex,\n"
       "   subareas, wear, speed, aggression, strength, dexterity,\n "
       "   constitution, reply, currency, itemname, wielded, specials, \n"
       "   intel, wisdom, charisma, wimpy, maxmagic, maxendur, value, \n"
       "   numberof, type, profname, rank and probability");
       return -1;
   }

   if (!STRNCASECMP(the_parsed->get_target1(), "title", strlen(the_parsed->get_target1())))
   {
      return set_attrib_title(the_parsed, the_builder);
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "altnames",
                               strlen(the_parsed->get_target1())))
   {
      return set_attrib_altnames(the_parsed, the_builder);
   }

   if (!STRNCASECMP(the_parsed->get_target1(), "desc", 
                               strlen(the_parsed->get_target1())))
   {
      return set_attrib_desc(the_builder);
   }

   if (!STRNCASECMP(the_parsed->get_target1(), "location", 
                               strlen(the_parsed->get_target1())))
   {
      return set_attrib_loc(the_parsed, the_builder);
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "specials", 
                               strlen(the_parsed->get_target1())))
   {
      return set_attrib_special(the_parsed, the_builder);
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "bareweapon",
                               strlen(the_parsed->get_target1())))
   {
      if (the_parsed->get_speech() == NULL)
      {
         the_builder->
                 send_bldr("You need to specify a BareWeapon to set to.\n");
         return -1;
      }
      set_bare_weapon(the_parsed->get_speech());
      the_builder->send_bldr("BareHands on %s set to: %s\n", get_name(), 
                                                        get_bare_weapon());
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "indflags", 
                               strlen(the_parsed->get_target1())))
   {
      Flags *tmp_indflags;
      int flagnum;
      Strings holder;

      tmp_indflags = get_indflags();
      
      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("Set which individuals flag?\n");
         return -1;
      }
      holder.assign_word(the_parsed->get_speech(), 1);
     
      if ((flagnum = 
          tmp_indflags->get_by_name(holder.str_show(), indflagnames)) == -1)
      {
         the_builder->send_bldr("That is not an individual flag.\n");
         return -1;
      }

      holder.assign_word(the_parsed->get_speech(), 2);
      if (holder.str_show() == NULL)
      {
         the_builder->send_bldr("Set that flag to what?\n"
                                "Valid choices are: On or Off\n");
         return -1;
      }

      if (holder.str_n_cmp("On", holder.str_len()))
         tmp_indflags->set_flag(flagnum);
      else if (holder.str_n_cmp("Off", holder.str_len()))
         tmp_indflags->clr_flag(flagnum);
      else
      {
         the_builder->send_bldr("That is not a valid setting.\n"
                                "Valid choices are: On or Off\n");
         return -1;
      }
      the_builder->send_bldr("Flag &+M%s&* has been set to: %s\n",
             indflagnames[flagnum], (tmp_indflags->get_flag(flagnum)) ? 
                       "&+GOn&*" : "&+ROff&*");
      return 1;
 
   }

   if (!STRNCASECMP(the_parsed->get_target1(), "clones",
                               strlen(the_parsed->get_target1())))
   {
      return set_attrib_clones(the_parsed, the_builder);
   }
   
   if (!STRNCASECMP(the_parsed->get_target1(), "brief", 
                               strlen(the_parsed->get_target1())))
   {
      if (the_builder->get_long_input(&brief) < 0)
      {
         the_builder->send_bldr("Error reading in input, failed!\n");
         return -1;
      }
      return 1;
   }

   if (!STRNCASECMP(the_parsed->get_target1(), "subareas",
                               strlen(the_parsed->get_target1())))
   {
      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify a subarea to set to.\n");
         return -1;
      }
      set_subarea(the_parsed->get_speech());
      the_builder->send_bldr("Subareas on %s set to: %s\n", get_name(), 
                                                        get_subarea());
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "wear",
                               strlen(the_parsed->get_target1())))
   {
      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify objects to wear.\n");
         return -1;
      }
      set_start_wear(the_parsed->get_speech());
      the_builder->send_bldr("Wear on %s set to: %s\n", get_name(), 
                                                        get_start_wear());
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "speed",
                               strlen(the_parsed->get_target1())))
   {
      int the_speed;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify a number for speed.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->
              send_bldr("You need to specify speed as a number (0-100).\n");
         return -1;
      }

      the_speed = atoi(the_parsed->get_speech());
      if ((the_speed < 0) || (the_speed > 100))
      {
         the_builder->send_bldr("Speed must be between 0 and 100.\n");
         return -1;
      }      

      set_speed(the_speed);
      the_builder->send_bldr("Speed set to %d on mobile object %s.\n",
                                 get_speed(), get_name());
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "intel",
                               strlen(the_parsed->get_target1())))
   {
      int the_intel;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify a number for intel.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->
              send_bldr("You need to specify intel as a number (0-100).\n");
         return -1;
      }

      the_intel = atoi(the_parsed->get_speech());
      if ((the_intel < 0) || (the_intel > 100))
      {
         the_builder->send_bldr("Intel must be between 0 and 100.\n");
         return -1;
      }      

      set_intel(the_intel);
      the_builder->send_bldr("Intel set to %d on mobile object %s.\n",
                                 get_intel(), get_name());
      return 1;
   }

   if (!STRNCASECMP(the_parsed->get_target1(), "wisdom",
                               strlen(the_parsed->get_target1())))
   {
      int the_wisdom;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify a number for wisdom.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->
              send_bldr("You need to specify wisdom as a number (0-100).\n");
         return -1;
      }

      the_wisdom = atoi(the_parsed->get_speech());
      if ((the_wisdom < 0) || (the_wisdom > 100))
      {
         the_builder->send_bldr("Wisdom must be between 0 and 100.\n");
         return -1;
      }      

      set_wisdom(the_wisdom);
      the_builder->send_bldr("Wisdom set to %d on mobile object %s.\n",
                                 get_wisdom(), get_name());
      return 1;
   }

   if (!STRNCASECMP(the_parsed->get_target1(), "charisma",
                               strlen(the_parsed->get_target1())))
   {
      int the_charisma;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify a number for charisma.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->
              send_bldr("You need to specify charisma as a number (0-100).\n");
         return -1;
      }

      the_charisma = atoi(the_parsed->get_speech());
      if ((the_charisma < 0) || (the_charisma > 100))
      {
         the_builder->send_bldr("Charisma must be between 0 and 100.\n");
         return -1;
      }      

      set_charisma(the_charisma);
      the_builder->send_bldr("Charisma set to %d on mobile object %s.\n",
                                 get_charisma(), get_name());
      return 1;
   }

   if (!STRNCASECMP(the_parsed->get_target1(), "aggression",
                               strlen(the_parsed->get_target1())))
   {
      int the_aggression;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify a number for "
                                "aggression.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->
           send_bldr("You need to specify aggression as a number (0-100).\n");
         return -1;
      }

      the_aggression = atoi(the_parsed->get_speech());
      if ((the_aggression < 0) || (the_aggression > 100))
      {
         the_builder->send_bldr("Aggression must be between 0 and 100.\n");
         return -1;
      }      

      set_aggression(the_aggression);
      the_builder->send_bldr("Aggression set to %d on mobile object %s.\n",
                                 get_aggression(), get_name());
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "strength", strlen(the_parsed->get_target1())))
   {
      int the_strength;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify a number for strength.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->send_bldr("You need to specify strength as a number.\n");
         return -1;
      }

      the_strength = atoi(the_parsed->get_speech());
      if ((the_strength < 1) || (the_strength > 100))
      {
         the_builder->send_bldr("Strength must be between 1 and 100.\n");
         return -1;
      }      

      set_strength(the_strength);
      the_builder->send_bldr("Strength set to %d on mobile object %s.\n",get_strength(), get_name());
      return 1;
   }
    if (!STRNCASECMP(the_parsed->get_target1(), "sex", strlen(the_parsed->get_target1())))
    {
        if (the_parsed->get_speech() == NULL)
        {
            the_builder->send_bldr("You need to specify a sex to set to.\n");
            return -1;
        }
        if (!STRNCASECMP(the_parsed->get_speech(), "male", strlen(the_parsed->get_speech()))) {
            the_builder->send_bldr("Sex changed from %s to male.\n", get_sex_str());
            set_sex(SEX_MALE);
        }
        else if (!STRNCASECMP(the_parsed->get_speech(), "female", strlen(the_parsed->get_speech()))) {
            the_builder->send_bldr("Sex changed from %s to female.\n", get_sex_str());
            set_sex(SEX_FEMALE);
        }
        else if (!STRNCASECMP(the_parsed->get_speech(), "neuter", strlen(the_parsed->get_speech()))) {
            the_builder->send_bldr("Sex changed from %s to neuter.\n", get_sex_str());
            set_sex(SEX_NEUTER);
        }
        else {
            the_builder->send_bldr("Valid sexes are male, female, and neuter.\n");
            return -1;
        }

        return 1;
    }
   if (!STRNCASECMP(the_parsed->get_target1(), "dexterity",
                               strlen(the_parsed->get_target1())))
   {
      int the_dex;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->
          send_bldr("You need to specify a number for dexterity.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->
           send_bldr("You need to specify dexterity as a number (1-100).\n");
         return -1;
      }

      the_dex = atoi(the_parsed->get_speech());
      if ((the_dex < 1) || (the_dex > 100))
      {
         the_builder->send_bldr("Dexterity must be between 1 and 100.\n");
         return -1;
      }      

      set_dexterity(the_dex);
      the_builder->send_bldr("Dexterity set to %d on mobile object %s.\n",
                                 get_dexterity(), get_name());
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "constitution",
                               strlen(the_parsed->get_target1())))
   {
      int the_cons;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->
             send_bldr("You need to specify a number for Constitution.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->
              send_bldr("You need to specify Constitution as a number.\n");
         return -1;
      }

      the_cons = atoi(the_parsed->get_speech());
      if (the_cons < 1)
      {
         the_builder->send_bldr("Constitution must be greater than 0.\n");
         return -1;
      }      

      set_constitution(the_cons);
      the_builder->send_bldr("Constitution set to %d on mobile object %s.\n",
                                 get_constitution(), get_name());
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "wimpy",
                               strlen(the_parsed->get_target1())))
   {
      int the_wimpy;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify a number for wimpy.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->
              send_bldr("You need to specify wimpy as a number ( >= 0 ).\n");
         return -1;
      }

      the_wimpy = atoi(the_parsed->get_speech());
      if (the_wimpy < 0)
      {
         the_builder->send_bldr("Wimpy must be greater than or equal to 0.\n");
         return -1;
      }      

      set_wimpy(the_wimpy);
      the_builder->send_bldr("Wimpy set to %d on mobile object %s.\n",
                                            get_wimpy(), get_name());
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "maxmagic",
                               strlen(the_parsed->get_target1())))
   {
      int max_magic;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify a number for MaxMagic.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->
              send_bldr("You need to specify MaxMagic as a number ( >= 0 ).\n");
         return -1;
      }

      max_magic = atoi(the_parsed->get_speech());
      if (max_magic < 0)
      {
         the_builder->send_bldr("MaxMagic must be greater than or equal to 0.\n");
         return -1;
      }      

      set_max_magic(max_magic);
      the_builder->send_bldr("MaxMagic set to %d on mobile object %s.\n",
                                            get_max_magic(), get_name());
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "maxendur",
                               strlen(the_parsed->get_target1())))
   {
      int max_endur;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("You need to specify a number for MaxEndur.\n");
         return -1;
      }
 
      if (!isdigit(*(the_parsed->get_speech()))) 
      {
         the_builder->
              send_bldr("You need to specify MaxEndur as a number ( >= 0 ).\n");
         return -1;
      }

      max_endur = atoi(the_parsed->get_speech());
      if (max_endur < 0)
      {
         the_builder->send_bldr("MaxEndur must be greater than or equal to 0.\n");
         return -1;
      }      

      set_max_endurance(max_endur);
      the_builder->send_bldr("MaxEndur set to %d on mobile object %s.\n",
                                            get_max_endurance(), get_name());
      return 1;
   }


   if (!STRNCASECMP(the_parsed->get_target1(), "reply",
                    strlen(the_parsed->get_target1())))
   {  Strings   tmp_str;
      Strings   tmp_word;
      int       replynr;
      Com_List  *tmp_list;
      int       counter = 1;

      tmp_str = the_parsed->get_speech();

      tmp_word.assign_word(tmp_str.str_show(),1);

      if (tmp_word.str_show() == NULL)
      {
         the_builder->send_bldr("Usage: set reply <nr>\n");
         return -1;
      }

      if (isdigit(*(tmp_word.str_show())))
      {  
         replynr = atoi(tmp_word.str_show());
      }
      else
      {  the_builder->send_bldr("Usage: set reply <nr>\n");
         return -1;
      }

      tmp_list = tell_list;

      while (tmp_list != NULL)
      {
         if (counter == replynr)
            break;
         tmp_list = tmp_list->next_com;
         counter++;
      }
      if ((counter != replynr) || (tmp_list == NULL))
      {
         the_builder->send_bldr("That tell reply doesn't exist.\n");
         return -1;
      }
      
      if (the_builder->get_long_input(&(tmp_list->the_reply), 1) < 0)
      {
         the_builder->send_bldr("Error reading in input, failed!\n");
         return -1;
      }
     
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "profname",
                    strlen(the_parsed->get_target1())))
   {  Strings   tmp_str;
      Strings   tmp_word;
      Strings   new_name;
      int       profnr;
      rank_list *tmp_list;
      int       counter = 1;

      tmp_str = the_parsed->get_speech();

      tmp_word.assign_word(tmp_str.str_show(), 1);
      new_name.assign_word(tmp_str.str_show(), 2);

      if ((tmp_word.str_show() == NULL) || (new_name.str_show() == NULL))
      {
         the_builder->send_bldr("Usage: set profname <nr> <name>\n");
         return -1;
      }

      if (isdigit(*(tmp_word.str_show())))
      {  
         profnr = atoi(tmp_word.str_show());
      }
      else
      {  the_builder->send_bldr("Usage: set profname <nr> <name>\n");
         return -1;
      }

      tmp_list = get_ranks();

      while (tmp_list != NULL)
      {
         if (counter == profnr)
            break;
         tmp_list = tmp_list->next_rank;
         counter++;
      }
      if ((counter != profnr) || (tmp_list == NULL))
      {
         the_builder->send_bldr("That proficiency doesn't exist.\n");
         return -1;
      }
      
      tmp_list->rank_name = new_name.str_show();

      the_builder->send_bldr("Proficiency %d profname set to: %s\n", 
                        profnr,  tmp_list->rank_name.str_show());
     
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "rank",
                    strlen(the_parsed->get_target1())))
   {  Strings   tmp_str;
      Strings   tmp_word;
      Strings   new_rank;
      int       profnr;
      int       ranknum;
      rank_list *tmp_list;
      int       counter = 1;

      tmp_str = the_parsed->get_speech();

      tmp_word.assign_word(tmp_str.str_show(), 1);
      new_rank.assign_word(tmp_str.str_show(), 2);

      if ((tmp_word.str_show() == NULL) || (new_rank.str_show() == NULL))
      {
         the_builder->send_bldr("Usage: set rank <nr> <ranknr>\n");
         return -1;
      }

      if (isdigit(*(tmp_word.str_show())))
      {  
         profnr = atoi(tmp_word.str_show());
      }
      else
      {  the_builder->send_bldr("Usage: set rank <nr> <ranknr>\n");
         return -1;
      }

      if (isdigit(*(new_rank.str_show())))
      {  
         ranknum = atoi(new_rank.str_show());
      }
      else
      {  the_builder->send_bldr("Usage: set rank <nr> <ranknr>\n");
         return -1;
      }

      tmp_list = get_ranks();

      while (tmp_list != NULL)
      {
         if (counter == profnr)
            break;
         tmp_list = tmp_list->next_rank;
         counter++;
      }
      if ((counter != profnr) || (tmp_list == NULL))
      {
         the_builder->send_bldr("That proficiency doesn't exist.\n");
         return -1;
      }
      
      if (ranknum < 0)
      {
      the_builder->send_bldr("Rank must be greater than 0.\n");
      return -1;
      }
      
      tmp_list->the_rank = ranknum;
      the_builder->send_bldr("Proficiency %d rank set to: %d\n", 
                        profnr,  tmp_list->the_rank);
     
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "probability",
                    strlen(the_parsed->get_target1())))
   {  Strings   tmp_str;
      Strings   tmp_word;
      Strings   new_prob;
      int       probnr;
      int       probnum;
      rank_list *tmp_list;
      int       counter = 1;

      tmp_str = the_parsed->get_speech();

      tmp_word.assign_word(tmp_str.str_show(), 1);
      new_prob.assign_word(tmp_str.str_show(), 2);

      if ((tmp_word.str_show() == NULL) || (new_prob.str_show() == NULL))
      {
         the_builder->send_bldr("Usage: set probability <nr> <probability>\n");
         return -1;
      }

      if (isdigit(*(tmp_word.str_show())))
      {  
         probnr = atoi(tmp_word.str_show());
      }
      else
      {  the_builder->send_bldr("Usage: set probability <nr> <probability>\n");
         return -1;
      }

      if (isdigit(*(new_prob.str_show())))
      {  
         probnum = atoi(new_prob.str_show());
      }
      else
      {  the_builder->send_bldr("Usage: set probability <nr> <probability>\n");
         return -1;
      }

      tmp_list = get_ranks();

      while (tmp_list != NULL)
      {
         if (counter == probnr)
            break;
         tmp_list = tmp_list->next_rank;
         counter++;
      }
      if ((counter != probnr) || (tmp_list == NULL))
      {
         the_builder->send_bldr("That proficiency doesn't exist.\n");
         return -1;
      }
      
      if ((probnum < 0) || (probnum > 100))
      {
      the_builder->send_bldr("Probability must be between 0 and 100.\n");
      return -1;
      }
      
      tmp_list->the_exp_prob = probnum;
      the_builder->send_bldr("Proficiency %d probability set to: %d\n", 
                        probnr,  tmp_list->the_exp_prob);
     
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "currency",
                               strlen(the_parsed->get_target1())))
   {
      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("usage: set currency <objectname>\n");
         return -1;
      }

      the_shop->set_currency(the_parsed->get_speech());
      the_builder->send_bldr("Shop currency on %s set to: %s\n", get_name(), 
                                                the_shop->get_currency());
      set_modified(1);
      return 1;      
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "itemname",
                               strlen(the_parsed->get_target1())))
   {
      Strings    alias;
      Strings    objname;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("usage: set itemname <alias> <objectname>\n");
         return -1;
      }

      alias.assign_word(the_parsed->get_speech(), 1);
      if (alias.str_show() == NULL)
      {
         the_builder->send_bldr("usage: set itemname <alias> <objectname>\n");
         return -1;
      }
      
      objname.assign_word(the_parsed->get_speech(), 2);
      if (objname.str_show() == NULL)
      {
         the_builder->send_bldr("usage: set itemname <alias> <objectname>\n");
         return -1;
      }

      if (the_shop->set_itemname(alias.str_show(), objname.str_show()) == -2)
      {
         the_builder->send_bldr("That alias does not exist.\n");
         return -1;
      }

      the_builder->send_bldr("Shop itemname on %s alias %s set to: %s\n", 
                        get_name(),  alias.str_show(),  objname.str_show());
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "itemdesc",
                               strlen(the_parsed->get_target1())))
   {
      Strings    alias;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("usage: set itemdesc <alias>\n");
         return -1;
      }

      alias.assign_word(the_parsed->get_speech(), 1);
      if (alias.str_show() == NULL)
      {
         the_builder->send_bldr("usage: set itemdesc <alias>\n");
         return -1;
      }
      
      if (the_shop->bldr_set_desc(alias.str_show(), the_builder) == -2)
      {
         the_builder->send_bldr("That alias does not exist.\n");
         return -1;
      }

      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "wielded",
                               strlen(the_parsed->get_target1())))
   {
      Strings    hand;
      Strings    objname;
      char *the_hands;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->
              send_bldr("usage: set wield <left|right|both> <objectname>\n");
         return -1;
      }

      hand.assign_word(the_parsed->get_speech(), 1);
      if (hand.str_show() == NULL)
      {
         the_builder->
             send_bldr("usage: set wield <left|right|both> <objectname>\n");
         return -1;
      }
      
      objname.assign_word(the_parsed->get_speech(), 2);
      if (objname.str_show() == NULL)
      {
         the_builder->
             send_bldr("usage: set wield <left|right|both> <objectname>\n");
         return -1;
      }

      if (hand.str_n_cmp("left", hand.str_len()))
      {
         set_start_wield(objname.str_show(), Left);
         the_hands = "left hand";
      }
      else if (hand.str_n_cmp("right", hand.str_len()))
      {
         set_start_wield(objname.str_show(), Right);
         the_hands = "right hand";
      }
      else if (hand.str_n_cmp("both", hand.str_len()))
      {
         set_start_wield(objname.str_show(), Both);
         the_hands = "both hands";
      }
      else
      {
         the_builder->send_bldr("Valid hands are: Left, Right, or Both.\n");
         return -1;
      }

      the_builder->send_bldr("Start Wield on %s %s set to: %s\n", 
                        get_name(),  the_hands,  objname.str_show());
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "value",
                               strlen(the_parsed->get_target1())))
   {
      Strings    alias;
      Strings    the_value;
      int        value;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("usage: set value <alias> <number>\n");
         return -1;
      }

      alias.assign_word(the_parsed->get_speech(), 1);
      if (alias.str_show() == NULL)
      {
         the_builder->send_bldr("usage: set value <alias> <number>\n");
         return -1;
      }
      
      the_value.assign_word(the_parsed->get_speech(), 2);
      if (the_value.str_show() == NULL)
      {
         the_builder->send_bldr("usage: set value <alias> <number>\n");
         return -1;
      }

      if (!isdigit(*(the_value.str_show()))) 
      {
         the_builder->send_bldr("You need to specify value as a number.\n");
         return -1;
      }

      value = atoi(the_value.str_show());

      if (the_shop->set_value(alias.str_show(), value) <= -2)
      {
         the_builder->send_bldr("That alias does not exist.\n");
         return -1;
      }

      the_builder->send_bldr("Shop value on %s alias %s set to: %d\n", 
                        get_name(),  alias.str_show(),  value);
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "numberof",
                               strlen(the_parsed->get_target1())))
   {
      Strings    alias;
      Strings    the_value;
      int        numberof;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("usage: set numberof <alias> <number>\n");
         return -1;
      }

      alias.assign_word(the_parsed->get_speech(), 1);
      if (alias.str_show() == NULL)
      {
         the_builder->send_bldr("usage: set numberof <alias> <number>\n");
         return -1;
      }
      
      the_value.assign_word(the_parsed->get_speech(), 2);
      if (the_value.str_show() == NULL)
      {
         the_builder->send_bldr("usage: set numberof <alias> <number>\n");
         return -1;
      }

      if (!isdigit(*(the_value.str_show()))) 
      {
         the_builder->send_bldr("You need to specify numberof as a number.\n");
         return -1;
      }

      numberof = atoi(the_value.str_show());

      if (numberof < 0)
      {
         the_builder->send_bldr("NumberOf can't be a negative number.\n");
         return -1;
      }

      if (numberof > 9999)
      {
         the_builder->send_bldr("Max number is 9999 (indicates unlimited).\n");
         return -1;
      }

      if (the_shop->set_num_of(alias.str_show(), numberof) <= -2)
      {
         the_builder->send_bldr("That alias does not exist.\n");
         return -1;
      }

      the_builder->send_bldr("Shop NumberOf on %s alias %s set to: %d\n", 
                        get_name(),  alias.str_show(),  numberof);
      set_modified(1);
      return 1;
   }
   if (!STRNCASECMP(the_parsed->get_target1(), "type",
                               strlen(the_parsed->get_target1())))
   {
      Strings       alias;
      Strings       name_type;
      exchange_type tmp_type;

      if (the_parsed->get_speech() == NULL)
      {
         the_builder->send_bldr("usage: set type <alias> <buy|sell|dual>\n");
         return -1;
      }

      alias.assign_word(the_parsed->get_speech(), 1);
      if (alias.str_show() == NULL)
      {
         the_builder->send_bldr("usage: set type <alias> <buy|sell|dual>\n");
         return -1;
      }
      
      name_type.assign_word(the_parsed->get_speech(), 2);
      if (name_type.str_show() == NULL)
      {
         the_builder->send_bldr("usage: set type <alias> <buy|sell|dual>\n");
         return -1;
      }

      if (!STRCASECMP(name_type.str_show(), "buy"))
      {
         tmp_type = Buy;
      }
      else if (!STRCASECMP(name_type.str_show(), "sell"))
      {
         tmp_type = Sell;
      }
      else if (!STRCASECMP(name_type.str_show(), "dual"))
      {
         tmp_type = Dual;
      }
      else
      {
         the_builder->send_bldr("That is not a valid type.\n"
                                "Valid types are: Buy, Sell, and Dual\n");
         return -1;
      }

      if (the_shop->set_type(alias.str_show(), tmp_type) == -2)
      {
         the_builder->send_bldr("That alias does not exist.\n");
         return -1;
      }

      the_builder->send_bldr("Shop type on %s alias %s set to: %s\n", 
                        get_name(),  alias.str_show(), name_type.str_show());
      set_modified(1);
      return 1;
   }

   the_builder->send_bldr("The attribute '%s' is not a mobile attribute.\n",
                                           the_parsed->get_target1());
   return -1;
}


/***********************************************************************
 ** set_brief - sets the brief for the mobile
 **
 ** Parameters: the_brief - the string to set the brief to
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/
   
int Mobile::set_brief(char *the_brief)
{
   if (the_brief == NULL)
      return -1;

   brief = the_brief;
   return 1;
}


/***********************************************************************
 ** get_brief - gets the brief for the mobile
 **
 ** Parameters: Nothing
 **
 ** Returns:  pointer to the brief string
 **
 ***********************************************************************/
   
char *Mobile::get_brief(void)
{
   return brief.str_show();
}


/***********************************************************************
 ** set_speed - sets the speed for the mobile
 **
 ** Parameters: the_speed - the speed to set the brief to
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/
   
int Mobile::set_speed(int the_speed)
{
   if ((the_speed > 100) || (the_speed < 0))
      return -1;

   speed = the_speed;
   return 1;
}


/***********************************************************************
 ** get_speed - gets the speed for the mobile
 **
 ** Parameters: Nothing
 **
 ** Returns:  the speed integer value
 **
 ***********************************************************************/
   
int Mobile::get_speed(void)
{
   return speed;
}


/***********************************************************************
 ** set_rot_timer - sets the time left before the corpse rots away
 **
 ** Parameters: the_speed - the speed to set the brief to
 **
 **
 ***********************************************************************/
   
void Mobile::set_rot_timer(int new_time)
{
   rot_timer = new_time;
}


/***********************************************************************
 ** get_rot_timer - gets the time left before the corpse rots away
 **
 ** Parameters: Nothing
 **
 ** Returns:  the time
 **
 ***********************************************************************/
   
int Mobile::get_rot_timer(void)
{
   return rot_timer;
}


/***********************************************************************
 ** set_aggression - sets the aggression for the mobile
 **
 ** Parameters: the_value - the speed to set the brief to
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/
   
int Mobile::set_aggression(int the_value)
{
   if ((the_value > 100) || (the_value < 0))
      return -1;

   aggression = the_value;
   return 1;
}


/***********************************************************************
 ** get_aggression - gets the aggression for the mobile
 **
 ** Parameters: Nothing
 **
 ** Returns:  the aggression integer value
 **
 ***********************************************************************/
   
int Mobile::get_aggression(void)
{
   return aggression;
}


/***********************************************************************
 ** set_subarea - sets the subarea this mobile is allowed in
 **
 ** Parameters: the_subarea - the subarea to set this to
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/
   
int Mobile::set_subarea(char *the_subarea)
{
   if (the_subarea == NULL)
      return -1;

   subareas = the_subarea;
   return 1;
}


/***********************************************************************
 ** get_subarea - gets the subarea for the mobile
 **
 ** Parameters: Nothing
 **
 ** Returns:  a pointer to the subarea string
 **
 ***********************************************************************/
   
char *Mobile::get_subarea(void)
{
   return subareas.str_show();
}


/***********************************************************************
 ** check_mobile - checks the mobile for events, such as moving, talking,
 **                or specials events
 **
 ** Parameters: Nothing
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/
   
int Mobile::check_mobile(void)
{
   int rand_num = 0;
   Location *new_loc = NULL;
   int      results;
   Strings  exit;
   Strings  holder;
   char     *dir_str[10] = {"North", "South", "East", "West", "Up", "Down", 
                     "Northeast", "Northwest", "Southeast", "Southwest"};

   /* if the location on this mobile is non-existant, ignore it */
   if (get_loc() == NULL)
   {
#if 0

      if (get_location() != NULL)
      {
         holder.sprintf("Mobile '%s@%s' cur_loc set to NULL but location "
              "string set to '%s'", get_name(), get_area(), get_location());
         mainstruct->log_error(holder.str_show(), "check_mobile");
      }
#endif
      return -1;
   }
   if (the_shop != NULL)
      the_shop->update_requests(get_loc());

   /* if the mobile is a corpse, then it does nothing as corpses don't
      usually do much */
   if (indflags->get_flag(INDFLAG_CORPSE))   
      return 0;

   /* we check to see if the mobile will move on this turn */
   if ((speed > 0) && 
       (!(get_indflags())->get_flag(INDFLAG_FIGHTING)))    
                  /* if it is set to 0, dont waste cpu time on this */
   {
      /* generate a random number and see if it is less than our speed */
      rand_num=1+(int) (100.0*rand()/(RAND_MAX+1.0));
      if (rand_num < speed)
      {
         rand_num=1+(int) (10.0*rand()/(RAND_MAX+1.0));
         new_loc = (get_loc())->get_exit(rand_num, 
                                      (get_loc())->get_area(), &results);

         if (new_loc != NULL)
         {
            Strings mob_name;
            Flags   *tmp_locflags;

            exit = dir_str[rand_num];  

            tmp_locflags = new_loc->get_locflags();

            /* if it is a nomobile room, don't let them in */
            if (tmp_locflags->get_flag(LOCFLAG_NOMOBILES))
               return -1;

            /* if the room is watery and they are not a water creature,
               don't let them in */
            if (tmp_locflags->get_flag(LOCFLAG_AQUATIC))
               return -1;

            /* if they have an allowed subarea set, don't allow them in any
               rooms that aren't marked with that subarea */
            if (subareas.str_show() != NULL)
            {
               if (!subareas.find_in_str(new_loc->get_location()))
               {
                  return -1;
               }
            }

            mob_name = get_title();
            mob_name.upper(0);
            /* say that they are leaving the room */
            holder.sprintf("%s goes %s.\n", mob_name.str_show(), 
                                                         exit.str_show());

            (get_loc())->send_location(holder.str_show(), NULL);

            /* tell the target room that we have arrived */
            holder.sprintf("%s enters the room.\n", mob_name.str_show());
            new_loc->send_location(holder.str_show(), NULL);

            if (set_location(new_loc) == -1)
            {
               mainstruct->log_error("Could not set mobile location!", 
                                                               "check_mobile");
            }
         }
      }

   }

   /* see if they attack anyone this turn */
   check_aggression(NULL);

   /* see if they pick up anything this turn */
   check_get();

   return 1;

}


/***********************************************************************
 ** add_comlist - adds a comlist structure to the tell list
 **
 ** Parameters: new_com - the comlist structure to add
 **
 ** Returns:  depth it is down the list for success, -1 for failure
 **
 ***********************************************************************/
   
int Mobile::add_comlist(Com_List *new_com)
{
   Com_List *tmp_list;
   int      depth = 2;

   if (new_com == NULL)
      return -1;

   if (tell_list == NULL)
   {
      tell_list = new_com;
      return 1;
   }

   tmp_list = tell_list;

   while (tmp_list->next_com != NULL)
   {
      tmp_list = tmp_list->next_com;
      depth++;
   }

   tmp_list->next_com = new_com;
   return depth;
}


/***********************************************************************
 ** del_comlist - deletess a comlist structure from the tell list
 **
 ** Parameters: new_com - the comlist structure to add
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/
   
int Mobile::del_comlist(int the_num)
{
   int count = 1;
   Com_List *tmp_list;
   Com_List *prev_list = NULL;

   if ((the_num <= 0) || (tell_list == NULL))
      return -1;

   tmp_list = tell_list;

   while (count != the_num)
   {
      if (tmp_list == NULL)
         return -1;
      prev_list = tmp_list;
      tmp_list = tmp_list->next_com;
      count++;
   }

   if (tmp_list == NULL)
      return -1;

   if (prev_list == NULL)
      tell_list = tmp_list->next_com;
   else
      prev_list->next_com = tmp_list->next_com;
   delete_Com_List(tmp_list);
   return 1;
}


/***********************************************************************
 ** rename_comlist - renames the keywords on a comlist item to something else
 **
 ** Parameters: the_num - the comlist number to set
 **             new_keywords - the new keywords to set it to
 **
 ** Returns:  1 for success, -1 for failure
 **
 ***********************************************************************/

int Mobile::rename_comlist(int the_num, char *new_keywords)
{
   int count = 1;
   Com_List *tmp_list;

   if ((the_num <= 0) || (tell_list == NULL) || (new_keywords == NULL))
      return -1;

   tmp_list = tell_list;

   while (count != the_num)
   {
      if (tmp_list == NULL)
         return -1;
      tmp_list = tmp_list->next_com;
      count++;
   }

   if (tmp_list == NULL)
      return -1;

   tmp_list->the_keywords = new_keywords;
   return 1;
}



/***********************************************************************
 ** find_reply - finds the proper reply if one exists based on the keywords
 **
 ** Parameters: the_keyword - the keyword to look for
 **
 ** Returns:  pointer to the string if one found
 **           null if failed
 **
 ***********************************************************************/
   
char *Mobile::find_reply(char *the_keyword)
{
   Com_List *tmp_list;

   tmp_list = tell_list;
   while (tmp_list != NULL)
   {
      if (tmp_list->the_keywords.find_in_str(the_keyword))
         return tmp_list->the_reply.str_show();

      tmp_list = tmp_list->next_com;
   }
   return NULL;
}


/***********************************************************************
 ** set_title - sets the title of the mobile
 **
 ** Parameters: the_title - the title string to set it to
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int Mobile::set_title(char *the_title)
{
   if (the_title == NULL)
      return -1;

   title = the_title;
   title.upper(0);
   if (title.str_len() > MAXTITLELEN)
      title.truncate(MAXTITLELEN);

   assign_keywords(title.str_show());

   return 1;
}


/***********************************************************************
 ** copy_object - copies the mobile to another object of different name
 **
 ** Parameters: copy_obj - copy attributes from this object
 **
 ** Returns:  1 if succeeded 
 **           0 if failed
 **
 ***********************************************************************/
int Mobile::copy_object(Entity *copy_obj)
{
   Mobile *copy_from;

   if (copy_obj->get_type() != OBJ_TYPE_MOBILE)
      return 0;

   copy_from = (Mobile *) copy_obj;

   /******* set the mudobject attributes *****/
   copy_mudobject_attrib((MudObject *) copy_from); 

   /******* set the individual attributes *****/
   copy_individual_attrib((Individual *) copy_from);

   /******* set the mobile attributes *****/
   set_brief(copy_from->get_brief());
   set_speed(copy_from->get_speed());
   set_subarea(copy_from->get_subarea());
   set_start_wear(copy_from->get_start_wear());
   set_start_wield(copy_from->get_start_wield(Left), Left);
   set_start_wield(copy_from->get_start_wield(Right), Right);
   set_aggression(copy_from->get_aggression());
   set_bare_weapon(copy_from->get_bare_weapon());

   tell_list = copy_from->copy_com_list();

   return 1;
}

/***********************************************************************
 ** copy_com_list - copies the com list and passes it out
 **
 ** Parameters: None
 **
 ** Returns:  pointer to the list if successful
 **           NULL if failed
 **
 ***********************************************************************/
Com_List *Mobile::copy_com_list()
{
   Com_List *new_list = NULL;
   Com_List *new_com;
   Com_List *next_com;
   Com_List *last_added = NULL;

   next_com = tell_list;
   while (next_com != NULL)
   {
      new_com = new_Com_List();
      new_com->next_com = NULL;
      new_com->the_keywords = next_com->the_keywords.str_show();
      new_com->the_reply = next_com->the_reply.str_show();

      if (last_added == NULL)
      {
         new_list = new_com;
         last_added = new_com;
      }
      else
      {
         last_added->next_com = new_com;
         last_added = new_com;
      }

      next_com = next_com->next_com;
   }
   return new_list;
}


/***********************************************************************
 ** operator = - copies an object to this object
 **
 ** Parameters: None
 **
 ** Returns: a pointer to this object copied to
 **
 ***********************************************************************/

Mobile *Mobile::operator = (Mobile *copy_from)
{
   if (!STRCASECMP(copy_from->get_name(), get_name()))
      return NULL;

   copy_object(copy_from);
   return this;
}


/***********************************************************************
 ** get_shop - returns the shop object for this mobile
 **
 **
 ***********************************************************************/

Shop *Mobile::get_shop()
{
   return the_shop;
}


/***********************************************************************
 ** read_shop - reads in the shop object for this mobile
 **
 ** Parameters: read_file - the file we are reading this from
 **             error_log - the error log to write to
 **
 **
 ***********************************************************************/

int Mobile::read_shop(FILE *read_file, ErrLog *error_log, int for_build_port)
{
   token_record *the_token;
   Shop         *new_shop;
   Strings      holder;
   char         *temp_desc;
   
   new_shop = new_Shop();

   /* read in the shop title */
   the_token = get_token(read_file, '^');
   new_shop->set_name(the_token->the_string);

   /* read in the type of currency this shop will use */
   the_token = get_token(read_file, '\0');
   new_shop->set_currency(the_token->the_string);

   the_token = get_token(read_file, '\0');
   while (the_token->token_type == T_PLUS)
   {
      Strings itemname;
      Strings alias;
      int     value, tmp_type, number_of;

      /* first we get the object name */
      the_token = get_token(read_file,'\0');
      itemname = the_token->the_string;

      /* next we get the alias name */
      the_token = get_token(read_file, '\0');
      alias = the_token->the_string;

      /* Read in the value */
      the_token = get_token(read_file, '\0');
     
      if (the_token->token_type != T_NUMERICAL)
      {
         holder.sprintf("Invalid format for shop item value in mudobject %s@%s",
                                               get_name(), get_area());
         error_log->log_err(holder.str_show(), "read_shop");
         return -1;
      }
      value = (atoi(the_token->the_string));

      /* Read in the type */
      the_token = get_token(read_file, '\0');
     
      if (the_token->token_type != T_NUMERICAL)
      {
         holder.sprintf("Invalid format for shop item type in mudobject %s@%s",
                                                      get_name(), get_area());
         error_log->log_err(holder.str_show(), "read_shop");
         return -1;
      }
      tmp_type = (atoi(the_token->the_string));

      /* Read in the number of */
      the_token = get_token(read_file, '\0');
     
      if (the_token->token_type != T_NUMERICAL)
      {
         holder.sprintf(
           "Invalid format for shop item NumberOf in mudobject %s@%s",
                                                 get_name(), get_area());
         error_log->log_err(holder.str_show(), "read_shop");
         return -1;
      }
      number_of = (atoi(the_token->the_string));

      /* read in the item description */
      temp_desc = read_desc_type(read_file, error_log, (MudObject *) this);
      if (temp_desc == NULL)
         return -1;

      holder = temp_desc;

      delete temp_desc;
      holder.remove_newline();
      if (!for_build_port)
         holder.swap_chars('\n', ' ');

      new_shop->add_shop_item(itemname.str_show(), alias.str_show(), value);
      new_shop->set_desc(alias.str_show(), holder.str_show());
      new_shop->set_type(alias.str_show(), (exchange_type) tmp_type);
      new_shop->set_num_of(alias.str_show(), number_of);

      the_token = get_token(read_file, '\0');
   }

   if (the_token->token_type != T_POUND)
   {
      holder.sprintf("Invalid format in shop for mudobject %s@%s", get_name(),
                                                                   get_area());
      error_log->log_err(holder.str_show(), "read_shop");
      return -1;
   }
   the_shop = new_shop;
   return 1;
}


/***********************************************************************
 ** write_shop - writes the shop for this mobile to a specified file
 **
 ** Parameters: the_file - the file to write to
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/
   
int Mobile::write_shop(FILE *the_file)
{
   if (the_shop != NULL)
      the_shop->write_shop(the_file);

   fprintf(the_file, "#\n");
   return 1;
}


/***********************************************************************
 ** set_shop - sets the shop pointer to specified shop object
 **
 ** Parameters: new_shop - the shop we are setting to
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/
   
int Mobile::set_shop(Shop *new_shop)
{
   if (new_shop == NULL)
      return -1;

   the_shop = new_shop;
   return 1;
}


/***********************************************************************
 ** delete_shop - as its name says, deletes the shop object
 **
 ** Parameters: Nothing
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/
int Mobile::delete_shop(void)
{
   if (the_shop == NULL)
      return -1;

   delete_Shop(the_shop);
   the_shop = NULL;
   return 1;
}


/***********************************************************************
 ** set_start_wield - sets the name of the object that this mobile will
 **                   start the game wielding
 **
 ** Parameters: the_item - the itemname we are to set this to
 **             the_hand - the hand that should wield this item
 **
 ** Returns:  1 if successful
 **          -1 if failed
 **
 ***********************************************************************/

int Mobile::set_start_wield(char *the_item, playerhand the_hand)
{
   if (the_item == NULL)
      return -1;

   if ((the_hand == Right) || (the_hand == Both))
   {
      if (!STRCASECMP(the_item, "none"))
         wield_right.truncate(0);
      else
         wield_right = the_item;
   } 
   if ((the_hand == Left) || (the_hand == Both))
   {
      if (!STRCASECMP(the_item, "none"))
         wield_left.truncate(0);
      else
         wield_left = the_item;
   } 
   return 1;
}


/***********************************************************************
 ** get_start_wield - gets the objectname for a particular hand that a
 **                   mobile starts off wielding
 **
 ** Parameters: the_hand - the hand that should wield this item
 **
 ** Returns:  a pointer to the object name string
 **
 ***********************************************************************/

char *Mobile::get_start_wield(playerhand the_hand)
{
   if ((the_hand == Both) || (the_hand == Left))
      return wield_left.str_show();
   else
      return wield_right.str_show();
}


/***********************************************************************
 ** set_start_wear - sets the string for the objects the mobile starts wearing
 **
 ** Parameters: the_items - the string of items we are setting it to
 **
 ** Returns:  Nothing
 **
 ***********************************************************************/

void Mobile::set_start_wear(char *the_items)
{
   worn = the_items;
}


/***********************************************************************
 ** get_start_wear - gets the string for the objects the mobile starts wearing
 **
 ** Parameters: Nothing
 **
 ** Returns:  a pointer to the object name string
 **
 ***********************************************************************/

char *Mobile::get_start_wear()
{
   return worn.str_show();
}


/***********************************************************************
 ** read_mobile_attrib - reads in mobile attributes from the file
 **
 ** Parameters: read_file - the file to read in from
 **             areaname - the area that we are reading
 **             error_log - the error log to write any errors to
 **
 ** Returns:  1 for successful read
 **          -1 for errors in the read
 **
 ***********************************************************************/

int Mobile::read_mobile_attrib(FILE *read_file, ErrLog *error_log, int for_build_port)
{
   token_record *the_token;
   Strings      holder;
   char         *temp_desc;


   temp_desc = read_desc_type(read_file, error_log, (MudObject *) this);
   if (temp_desc == NULL)
      return -1;
   set_brief(temp_desc);

   delete temp_desc;


   /* set the subareas */
   the_token = get_token(read_file,'\0');
   if (the_token->token_type != T_CARROT)
   {
       holder.sprintf("Invalid format in mudobject %s", get_name());
       error_log->log_err(holder.str_show(), "read_mobile_attrib");
       return -1;
   } 
   the_token = get_token(read_file, '^');
   set_subarea(the_token->the_string);

   /* get the start wield left */
   the_token = get_token(read_file, '\0');
   set_start_wield(the_token->the_string, Left);

   /* get the start wield right */
   the_token = get_token(read_file, '\0');
   set_start_wield(the_token->the_string, Right);

   /* get the next item, it should be a '^', if not, raise error */
   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_CARROT)
   {
      holder.sprintf("Invalid format in mudobject %s", get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   /* get the start wear objects */
   the_token = get_token(read_file, '^');
   set_start_wear(the_token->the_string);

   /* get the next item, it should be a '^', if not, raise error */
   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_CARROT)
   {
      holder.sprintf("Invalid format in mudobject %s", get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   /* get the BareWeapon of this mobile */
   the_token = get_token(read_file, '^');
   set_bare_weapon(the_token->the_string);   

   /* Set strength */
   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for attribute strength in mudobject %s", 
                                                                get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_strength(atoi(the_token->the_string));

   /* Set dexterity */
   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.sprintf("Invalid format for attribute dexterity in mudobject %s", get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_dexterity(atoi(the_token->the_string));

   /* Set health */
   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
        sprintf("Invalid format for attribute constitution in mudobject %s", 
                                                               get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_constitution(atoi(the_token->the_string));
   set_health(get_maxhealth());

   /* Set intel */
   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for attribute intel in mudobject %s", 
                                                               get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_intel(atoi(the_token->the_string));

   /* Set wisdom */
   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for attribute wisdom in mudobject %s", 
                                                               get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_wisdom(atoi(the_token->the_string));

   /* Set charisma */
   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for attribute charisma in mudobject %s", 
                                                               get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_charisma(atoi(the_token->the_string));

   /* read in the individual flags */
   if (indflags->read_flags(read_file, error_log) <= 0)
   {
      holder.sprintf("Error reading indflags for mobile '%s@%s'", get_name(),
                                                                 get_area()); 
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }   
   indflags->clr_frozen(indflagfrozen);
   indflags->set_flag(INDFLAG_ATTACKPLAYER);

   // Set sex
   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_NUMERICAL)
   {
       holder.sprintf("Invalid format for attribute sex in mudobject %s", get_name());
       error_log->log_err(holder.str_show(), "read_mobile_attrib");
       return -1;
   }
   set_sex(atoi(the_token->the_string));

   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_NUMERICAL)
   {
       holder.sprintf("Invalid format for attribute vislvl in mudobject %s", get_name());
       error_log->log_err(holder.str_show(), "read_mobile_attrib");
       return -1;
   }
   set_vislvl(atoi(the_token->the_string));

   /* Set speed */
   the_token = get_token(read_file, '\0');
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.sprintf("Invalid format for attribute speed in mudobject %s", 
                                                                get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_speed(atoi(the_token->the_string));

   /* Set aggression */
   the_token = get_token(read_file, '\0');
     
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for attribute aggression in mudobject %s", 
                                                                get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_aggression(atoi(the_token->the_string));

   /* Set wimpy */
   the_token = get_token(read_file, '\0');
     
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for attribute wimpy in mudobject %s", 
                                                                get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_wimpy(atoi(the_token->the_string));

   /* Set max_magic */
   the_token = get_token(read_file, '\0');
     
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for attribute max_magic in mudobject %s", 
                                                                get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_max_magic(atoi(the_token->the_string));

   /* Set max_endurance */
   the_token = get_token(read_file, '\0');
     
   if (the_token->token_type != T_NUMERICAL)
   {
      holder.
         sprintf("Invalid format for attribute max_endurance in mudobject %s", 
                                                                get_name());
      error_log->log_err(holder.str_show(), "read_mobile_attrib");
      return -1;
   }
   set_max_endurance(atoi(the_token->the_string));

   // Read all ranks of abilities or combat skills
   if (read_ranks(read_file) < 0)
     return -1;

   /* get the talk structs */
   the_token = get_token(read_file,'\0');
   while (the_token->token_type != T_POUND)
   {
      Com_List *new_com;

      if (the_token->token_type != T_PLUS)
      {
         holder.sprintf("Invalid format in mudobject %s", get_name());
         error_log->log_err(holder.str_show(), "read_mobile_attrib");
         return -1;
      }

      new_com = new_Com_List();
      new_com->next_com = NULL;

      /* first we get the tell keylist */
      the_token = get_token(read_file,'\0');
      if (the_token->token_type != T_CARROT)
      {
         holder.sprintf("Invalid format in mudobject %s", get_name());
         error_log->log_err(holder.str_show(), "read_mobile");
         delete_Com_List(new_com);
         return -1;
      }

      the_token = get_token(read_file, '^');
      new_com->the_keywords.str_copy(the_token->the_string);
      

      temp_desc = read_desc_type(read_file, error_log, (MudObject *) this);
      if (temp_desc == NULL)
         return -1;
      new_com->the_reply.str_copy(temp_desc);
      new_com->the_reply.remove_newline();
      if (!for_build_port)
         new_com->the_reply.swap_chars('\n', ' ');
      delete temp_desc;

      /* now add the new_com struct */
      add_comlist(new_com);
      the_token = get_token(read_file,'\0');
   }


   /* get the shop structs */
   the_token = get_token(read_file,'\0');
   if (the_token->token_type != T_POUND)
   {
      if (the_token->token_type != T_CARROT)
      {
         holder.sprintf("Invalid format in mudobject %s", get_name());
         error_log->log_err(holder.str_show(), "read_mobile_attrib");
         return -1;
      }

      if (read_shop(read_file, error_log, for_build_port) <= 0)
      {
         return -1;
      }
   }
   return 1;
}


/***********************************************************************
 ** start_wield - starts a mobile out wielding indicated weapons
 **
 ** Parameters: 
 **
 ** Returns:  1 for successful
 **          -1 for errors
 **
 ***********************************************************************/

int Mobile::start_wield(Object_List *obj_dbase, ErrLog *error_log)
{
   playerhand the_hand = Left;
   MudObject  *wield_obj;
   Inventory  *the_inv;
   Strings    holder;
   MudObject  *new_obj;
   int        i;

   the_inv = get_inventory();
   for (i=0; i<2; i++)
   {
      if (get_start_wield(the_hand) != NULL)
      { 
         if ((wield_obj = obj_dbase->get_mudobject(get_area(), 
                                     get_start_wield(the_hand))) == NULL)
       {
            holder.sprintf("Wield object %s does not exist in mobile %s@%s.\n",
                          get_start_wield(the_hand), get_name(), get_area());
            error_log->log_err(holder.str_show(), "start_wield");
         }
         else
       {
            if (!wield_obj->is_a_moveable())
          {
               holder.sprintf(
                       "Wield object %s@%s in mobile %s@%s must be moveable.\n",
                        wield_obj->get_name(), wield_obj->get_area(), 
                                         get_name(), get_area());
               error_log->log_err(holder.str_show(), "start_wield");
            }
            if (the_inv->find_by_objname(wield_obj->get_name(), 
                                         wield_obj->get_area()) == NULL)
          {
               new_obj = obj_dbase->clone_object(wield_obj);
               add_contained(new_obj);
               wield_obj = new_obj;
            }
            wield_moveable((Moveable *) wield_obj);
         }
      }
      the_hand = Right;
   }
   return 1;
}

/***********************************************************************
 ** start_wear - starts a mobile out wearing indicated weapons
 **
 ** Parameters: 
 **
 ** Returns:  1 for successful
 **          -1 for errors
 **
 ***********************************************************************/

int Mobile::start_wear(Object_List *obj_dbase, ErrLog *error_log)
{
   Inventory  *the_inv;
   Strings    holder;
   MudObject  *new_obj;
   MudObject  *wear_obj;
   int        i;

   /* wear objects that need to be worn */
   i=1;
   the_inv = get_inventory();
   while (holder.assign_word(get_start_wear(), i) > 0)
   {
      if ((wear_obj = obj_dbase->get_mudobject(get_area(), 
                                               holder.str_show())) == NULL)
      {
         holder.sprintf("Wear object %s does not exist in mobile %s@%s.\n",
                           holder.str_show(), get_name(), get_area());
         error_log->log_err(holder.str_show(), "start_wear");
      }
      else
      {
         if (!wear_obj->is_a_moveable())
       {
            holder.sprintf("Wear object %s@%s in mobile %s@%s must "
              "be moveable.\n", wear_obj->get_name(), wear_obj->get_area(), 
                                                   get_name(), get_area());
            error_log->log_err(holder.str_show(), "start_wear");
         }
         else if (wear_obj->get_type() != OBJ_TYPE_WEARABLE)
       {
            holder.sprintf("Wear object %s@%s in mobile %s@%s must "
              "be wearable.\n", wear_obj->get_name(), wear_obj->get_area(), 
                                                   get_name(), get_area());
            error_log->log_err(holder.str_show(), "start_wear");
       }
         else
       {
            if (the_inv->find_by_objname(wear_obj->get_name(), 
                                          wear_obj->get_area()) == NULL)
          {
               new_obj = obj_dbase->clone_object(wear_obj);
               add_contained(new_obj);
               wear_obj = new_obj;
            }
            wear_item((Wearable *) wear_obj);
         }
      }
    
      i++;
   }
   return 1;
}


/***********************************************************************
 ** check_aggression - checks to see if this mobile attacks anyone
 **
 ** Parameters: the_ind - the individual we might attack, if we just want
 **                       to attack someone in the room, set this NULL
 **
 ** Returns:  1 for attack
 **           0 for nobody attacked
 **          -1 for errors
 **
 ***********************************************************************/

int Mobile::check_aggression(Individual *the_ind)
{
   Individual *attack_them;
   MudObject  *tmp_obj;
   Inventory  *in_room;
   Strings    holder;
   MudObject  *attack_obj = NULL;
   Flags      *tmp_indflags;

   if (get_aggression() == 0)
      return 0;

   tmp_indflags = get_indflags();
   if (tmp_indflags->get_flag(INDFLAG_FIGHTING))
      return 0;

   // If they are dead, no attack, that would be silly
   if ((tmp_indflags->get_flag(INDFLAG_CORPSE)) ||
       (tmp_indflags->get_flag(INDFLAG_GHOST)))
     return 0;

   if (((get_loc())->get_locflags())->get_flag(LOCFLAG_PEACEFUL))
   {
      return 0;
   }

   /* if we will not attack this time */
   if (((int) (100.0*(rand()/(RAND_MAX+1.0)))) >= get_aggression())
      return 0;

   in_room = (get_loc())->get_inventory();
   in_room->reset_current();
   tmp_obj = in_room->get_first();

   attack_them = the_ind;

   if (attack_them == NULL)
   {
      while (tmp_obj != NULL)
      {
         if ((tmp_obj != (MudObject *) this) &&
             (((tmp_obj->get_type() == OBJ_TYPE_MOBILE) &&
               (!tmp_indflags->get_flag(INDFLAG_ATTACKPLAYER))) ||
              (tmp_obj->get_type() == OBJ_TYPE_PLAYER)))
       {
            attack_obj = tmp_obj;
            break;
         }
         tmp_obj = in_room->get_next();
      }
      if (attack_obj == NULL)
         return 0;

      attack_them = (Individual *) attack_obj;
   }

   if (check_specials("on_attack", this, attack_them, NULL, 
                                                  this, NULL) == 3)
      return 0;

   holder.sprintf("%s lunging at %s with a snarl!\n", 
                            get_title(), attack_them->get_title());
   if (attack_them->get_type() == OBJ_TYPE_PLAYER)
   {
      ((Player *) attack_them)->send_plr("%s lunges at you with a snarl!\n",
                                                              get_title());
      (attack_them->get_loc())->
                     send_location(holder.str_show(), (Player *) attack_them);
   }
   else
   {
      (attack_them->get_loc())->send_location(holder.str_show(), NULL);
   }

   if (request_fight(attack_them) < 0)
   {
      printf("fight refused!\n");
      return 1;
   }
   start_fight(attack_them);

   return 1;
}


/***********************************************************************
 ** check_get - checks to see if the mobile picks up anything this turn
 **
 ** Returns:  1 for picked up
 **           0 for nothing done
 **          -1 for errors
 **
 ***********************************************************************/

int Mobile::check_get()
{
   Flags      *tmp_indflags;
   Inventory  *in_room;
   MudObject  *tmp_obj;

   tmp_indflags = get_indflags();
   if (!tmp_indflags->get_flag(INDFLAG_GETSTUFF))
      return 0;

   /* 10 percent chance we pick something up */
   if (((int) (100*(rand()/(RAND_MAX+1.0)))) >= 10)
      return 0;

   in_room = (get_loc())->get_inventory();
   in_room->reset_current();
   tmp_obj = in_room->get_first();

   while (tmp_obj != NULL)
   {
      if (tmp_obj->is_a_moveable())
      {
         game_get_obj(tmp_obj, get_loc(), 1, 0);
         return 1;
      }
      
      tmp_obj = in_room->get_next();
   }

   return 0;
}


/***********************************************************************
 ** rot_corpse - rot the corpse based on environmental conditions
 **
 ** Parameters: Nothing
 **
 ** Returns:  the rot timer count left
 **
 ***********************************************************************/
   
int Mobile::rot_corpse(void)
{
   int      increment;
   Strings  holder;
   int      display_message = 1;
   Location *the_loc;

   /* this will do for now, we can factor in environment later */
   rot_timer--;

   increment = (int) (((float) rot_timer / (float) the_config.secs_to_rot) * 100.0);

   if (increment == 80)
   {
      holder.sprintf("The corpse of %s starts to smell badly.\n", get_title());
   }
   else if (increment == 60)
   {
      holder.sprintf("Maggots chew hungrily on the remains of %s.\n", get_title());
   }
   else if (increment == 40)
   {
      holder.sprintf("All flesh has been eaten off the corpse.\n");
   }
   else if (increment == 20)
   {
      holder.sprintf("The corpse is crumbling away.\n");
   }
   else
      display_message = 0;

   if (display_message)
   {
      the_loc = get_loc();
      the_loc->send_location(holder.str_show(), NULL);
   }

   return rot_timer;
}

/***********************************************************************
 ** reset_individual: resets the individual's variables to default
 **
 ** Parameters: the_str - the string to load with the decaying string
 **
 ** Returns: -1 for failure, 1 for success
 **
 ***********************************************************************/

int Mobile::load_decay_str(Strings *the_str)
{
   int increment;

   if (the_str == NULL)
      return -1;

   increment = (int) (((float) rot_timer / (float) the_config.secs_to_rot) * 100.0);

   if (increment > 90)
   {
      the_str->sprintf("The corpse, still in fairly good shape, appears to be "
                       "the corpse\nof %s.", get_title());
   }
   else if (increment > 80)
   {
      the_str->sprintf("The corpse of %s is starting to bloat.", get_title());      
   }
   else if (increment > 70)
   {
      the_str->sprintf("The severely bloated corpse of %s is starting to smell.", 
                                                                    get_title());  
   }
   else if (increment > 60)
   {
      the_str->sprintf("Maggots crawl through the decaying remains of %s.", 
                                                                   get_title());
   }
   else if (increment > 50)
   {
      the_str->sprintf(
       "Badly decayed and horribly reaking, it is tough to tell this was once %s.", 
                                                                     get_title()); 
   }
   else if (increment > 40)
   {
      the_str->sprintf("Bones protrude from what flesh remains of this poor soul.");      
   }
   else if (increment > 30)
   {
      the_str->sprintf(
         "Flecks of dried flesh are attached sporradicly on bones of this old skeleton.");      
   }
   else if (increment > 20)
   {
      the_str->sprintf("A dried skeleton is all that remains of this body.\n");     
   }
   else if (increment > 10)
   {
      the_str->sprintf(
         "Dried and crumbling bones remain a marker of what once was a body."); 
   }
   else if (increment > 10)
   {
      the_str->sprintf(
         "A pile of bones mark the final resting place of one adventurer.");      
   }
   else if (increment > 0)
   {
      the_str->sprintf("Half-crumbled bones rest where once a body lied.");      
   }



   return 1;   
}

/***********************************************************************
 ** get_mem_size - gets how much memory this special is taking up
 **
 ** Returns: mem size in bytes
 **
 ***********************************************************************/

int Mobile::get_mem_size()
{
   int size = 0;

   size = sizeof(this);
   size += get_mem_size_dynamic();
   return size;
}

/***********************************************************************
 ** send_plr - as this is not a player, does nothing if called
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int Mobile::send_plr(char *new_str, ...)
{
  return 1;
}

/***********************************************************************
 ** get_mem_size_dynamic - gets how much memory is taken up by pointers
 **                        pointing to other objects, not including the
 **                        sizeof(this)
 **
 ** Returns: mem size in bytes
 **
 ***********************************************************************/

int Mobile::get_mem_size_dynamic()
{
   int  size = 0;
   Com_List *tmp_com;

   tmp_com = tell_list;
   while (tmp_com != NULL)
   {
      size += tmp_com->the_keywords.get_mem_size_dynamic();
      size += tmp_com->the_reply.get_mem_size_dynamic();
      size += sizeof(*tmp_com);
      tmp_com = tmp_com->next_com;
   }

   size += brief.get_mem_size_dynamic();
   size += subareas.get_mem_size_dynamic();
   size += wield_left.get_mem_size_dynamic();
   size += wield_right.get_mem_size_dynamic();
   size += worn.get_mem_size_dynamic();

   if (the_shop != NULL)
      size += the_shop->get_mem_size();
   
   size += get_mem_size_ind();
   size += get_mem_size_mudobj();
   size += get_mem_size_entity();

   return size;
}


/***********************************************************************
 ** attack - attacks another individual by choosing an attack (spell, skill,
 **          or swinging the weapon) and using it
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int Mobile::attack(Individual *target)
{
  rank_list *tmp_rank;
  int       rand_num;
  Ability   *the_ability;

  if ((get_target() == NULL) || (get_target()->get_loc() != get_loc()))
  {
    stop_fighting();
    return 0;
  }

  // First, lets check their spells and skills to see if its a castin time!
  tmp_rank = get_ranks();
  while (tmp_rank != NULL)
  {
    if ((tmp_rank->the_type == OBJ_TYPE_SPELL) || 
      (tmp_rank->the_type == OBJ_TYPE_SKILL))
    {
      // If random chance happens to specify using this ability
      rand_num = (int) (100.0*(rand()/(RAND_MAX+1.0)));
      if (rand_num < tmp_rank->the_exp_prob)
      {

      // If this ability doesn't seem to exist, go onto the next one
      if ((the_ability = 
           mainstruct->get_ability(tmp_rank->rank_name.str_show())) == NULL)
      { 
        tmp_rank = tmp_rank->next_rank;
        continue;
      }

      // If they don't have enough juice to use this, go onto the next one
      if (((the_ability->get_type() == OBJ_TYPE_SPELL) && 
           (the_ability->get_drain() > get_magic())) || 
          ((the_ability->get_type() == OBJ_TYPE_SKILL) && 
           (the_ability->get_drain() > get_endurance())))
      {
        tmp_rank = tmp_rank->next_rank;
        continue;
      }

        return the_ability->use_ability(this, target, NULL);
      }
    }
    tmp_rank = tmp_rank->next_rank;
  }

  return use_weapon(target);
}


/***********************************************************************
 ** coord_ranks - coordinates the ranks in a mobile, setting the types
 **               if it can figure it out
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int Mobile::coord_ranks(Object_List *the_dbase)
{
  rank_list *tmp_rank;
  Ability *the_ability;

  tmp_rank = get_ranks();
  while (tmp_rank != NULL)
  {
    if ((the_ability = 
       the_dbase->get_ability_obj(tmp_rank->rank_name.str_show())) != NULL)
    {
      tmp_rank->the_type = the_ability->get_type();
    }
    else
      tmp_rank->the_type = OBJ_TYPE_WEAPON;

    tmp_rank = tmp_rank->next_rank;
  }
  return 1;
}


#endif


Generated by  Doxygen 1.6.0   Back to index