wileymud-1.187b/
wileymud-1.187b/attic/
wileymud-1.187b/attic/bin/
wileymud-1.187b/attic/lib/
wileymud-1.187b/attic/lib/adm/
wileymud-1.187b/attic/lib/man/
wileymud-1.187b/attic/lib/new-wld/
wileymud-1.187b/attic/lib/new-wld/default/
wileymud-1.187b/attic/lib/old/
wileymud-1.187b/attic/lib/wld/
wileymud-1.187b/attic/public_html/
wileymud-1.187b/attic/public_html/gfx/
wileymud-1.187b/attic/src/bin/
wileymud-1.187b/attic/src/etc/
wileymud-1.187b/attic/src/libauth-4.0-p5/
wileymud-1.187b/attic/src/sedna/
wileymud-1.187b/backups/
wileymud-1.187b/bin/
wileymud-1.187b/docs/
wileymud-1.187b/etc/
wileymud-1.187b/lib/
wileymud-1.187b/lib/adm/
wileymud-1.187b/lib/boards/
wileymud-1.187b/lib/log/
wileymud-1.187b/lib/man/
wileymud-1.187b/lib/ply/
wileymud-1.187b/lib/ply/a/
wileymud-1.187b/lib/ply/b/
wileymud-1.187b/lib/ply/c/
wileymud-1.187b/lib/ply/d/
wileymud-1.187b/lib/ply/g/
wileymud-1.187b/lib/ply/k/
wileymud-1.187b/lib/ply/m/
wileymud-1.187b/lib/ply/s/
wileymud-1.187b/lib/ply/t/
wileymud-1.187b/public_html/gfx/
wileymud-1.187b/src/bin/
wileymud-1.187b/src/convert/attic/
wileymud-1.187b/src/convert/obj/
wileymud-1.187b/src/convert/perl/
wileymud-1.187b/src/convert/perl/MudConvert/
wileymud-1.187b/src/convert/perl/MudConvert/DUMP/
wileymud-1.187b/src/convert/perl/MudConvert/Report/
wileymud-1.187b/src/convert/perl/MudConvert/WileyMUD/
wileymud-1.187b/src/convert/perl/output/
wileymud-1.187b/src/convert/perl/output/DUMP/
wileymud-1.187b/src/convert/perl/output/Report/
wileymud-1.187b/src/convert/perl/output/WileyMUD/
wileymud-1.187b/src/etc/
wileymud-1.187b/src/etc/init.d/
wileymud-1.187b/src/etc/rc.d/
wileymud-1.187b/src/etc/rc.d/init.d/
wileymud-1.187b/src/lib/
wileymud-1.187b/src/lib/adm/
wileymud-1.187b/src/lib/boards/
wileymud-1.187b/src/lib/log/
wileymud-1.187b/src/lib/man/
wileymud-1.187b/src/lib/ply/
wileymud-1.187b/src/lib/ply/a/
wileymud-1.187b/src/lib/ply/b/
wileymud-1.187b/src/lib/ply/c/
wileymud-1.187b/src/lib/ply/d/
wileymud-1.187b/src/lib/ply/e/
wileymud-1.187b/src/lib/ply/f/
wileymud-1.187b/src/lib/ply/g/
wileymud-1.187b/src/lib/ply/h/
wileymud-1.187b/src/lib/ply/i/
wileymud-1.187b/src/lib/ply/j/
wileymud-1.187b/src/lib/ply/k/
wileymud-1.187b/src/lib/ply/l/
wileymud-1.187b/src/lib/ply/m/
wileymud-1.187b/src/lib/ply/n/
wileymud-1.187b/src/lib/ply/o/
wileymud-1.187b/src/lib/ply/p/
wileymud-1.187b/src/lib/ply/q/
wileymud-1.187b/src/lib/ply/r/
wileymud-1.187b/src/lib/ply/s/
wileymud-1.187b/src/lib/ply/t/
wileymud-1.187b/src/lib/ply/u/
wileymud-1.187b/src/lib/ply/v/
wileymud-1.187b/src/lib/ply/w/
wileymud-1.187b/src/lib/ply/x/
wileymud-1.187b/src/lib/ply/y/
wileymud-1.187b/src/lib/ply/z/
wileymud-1.187b/src/obj/
wileymud-1.187b/src/utils/
wileymud-1.187b/src/utils/mobmaker/
#ifndef cmob_cpp 
#define cmob_cpp 

#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <strings.h>
#include <unistd.h>
#include <ctype.h>
#include "cmob.h"

extern FILE *file_mob_in;
extern FILE *file_mob_out;

#define NUMFLAGS 23 
#define MAX_STR_LENGTH 1500
#define MAX_SKILLS 10

// SECTION 1: FLAGS
char *races[] = 
	{
	"HALFBREED",
	"HUMAN",
	"ELVEN",
	"DWARF",
	"HALFLING",
	"GNOME",
	"REPTILE",
	"SPECIAL",
	"LYCANTHROPE",
	"DRAGON",
	"UNDEAD",
	"ORC",
	"INSECT",
	"ARACHNID",
	"DINOSAUR",
	"FISH",
	"BIRD",
	"GIANT",
	"PREDATOR",
	"PARASITE",
	"SLIME",
	"DEMON",
	"SNAKE",
	"HERBIV",
	"TREE",
	"VEGGIE",
	"ELEMENT",
	"PLANAR",
	"DEVIL",
	"GHOST",
	"GOBLIN",
	"TROLL",
	"VEGMAN",
	"MFLAYER",
	"PRIMATE",
	"ANIMAL",
	"FAERY",
	"PLANT",
	"\0"
	};

char *sexes[] = 
	{
	"NEUTRAL",
	"MALE",
	"FEMALE",
	"NEUTRAL",
	"MALE",
	"FEMALE",
	"\0"
	};

int cmob_flags_initialized = 0;

struct 
{
  char *flag;
  long bit;
  int FA;  // flags affected (0 = act_flags, 1 = affection_flags)
} flags_translation[NUMFLAGS];

struct 
{
  char *flag;
  long bit;
  int FA;  // flags affected (0 = act_flags, 1 = affection_flags)
} classes[6];

struct
{
  char *flag;
  long bit;
} imm_types[7];

struct
{
  char *flag;
  long bit;
} positions[4];

void initialize_cmob_flags_translation(void)
{
  if(cmob_flags_initialized == 1) return;  // already done
  cmob_flags_initialized = 1;
  register int i = 0;

  // act_flags
  flags_translation[i].flag = strdup("SPECIALPROC");
  flags_translation[i].bit = 1;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("SENTINEL");
  flags_translation[i].bit = 2;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("SCAVENGER");
  flags_translation[i].bit = 4;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("NICE_THIEF");
  flags_translation[i].bit = 16;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("AGGRESSIVE");
  flags_translation[i].bit = 32;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("STAY_ZONE");
  flags_translation[i].bit = 64;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("WIMPY");
  flags_translation[i].bit = 128;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("HATED");
  flags_translation[i].bit = 256;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("IMMORTAL");
  flags_translation[i].bit = 2048;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("USES_ITEMS");
  flags_translation[i].bit = 131072;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("FIGHTER");
  flags_translation[i].bit = 262144;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("FOOD_PROVIDER");
  flags_translation[i].bit = 524288;
  flags_translation[i].FA = 0;
  flags_translation[++i].flag = strdup("MOUNTABLE");
  flags_translation[i].bit = 2097152;
  flags_translation[i].FA = 0;

 // affection flags: 

  flags_translation[++i].flag = strdup("INVISIBLE");
  flags_translation[i].bit = 2;
  flags_translation[i].FA = 1;
  flags_translation[++i].flag = strdup("DETECT_I");
  flags_translation[i].bit = 8;
  flags_translation[i].FA = 1;
  flags_translation[++i].flag = strdup("SENSE_LIFE");
  flags_translation[i].bit = 32;
  flags_translation[i].FA = 1;
  flags_translation[++i].flag = strdup("SANCTUARY");
  flags_translation[i].bit = 128;
  flags_translation[i].FA = 1;
  flags_translation[++i].flag = strdup("FLYING");
  flags_translation[i].bit = 2048;
  flags_translation[i].FA = 1;
  flags_translation[++i].flag = strdup("INFRAVISION");
  flags_translation[i].bit = 32768;
  flags_translation[i].FA = 1;
  flags_translation[++i].flag = strdup("GILLS");
  flags_translation[i].bit = 65536;
  flags_translation[i].FA = 1;
  flags_translation[++i].flag = strdup("SNEAK");
  flags_translation[i].bit = 524288;
  flags_translation[i].FA = 1;
  flags_translation[++i].flag = strdup("HIDE");
  flags_translation[i].bit = 1048576;
  flags_translation[i].FA = 1;
  flags_translation[++i].flag = strdup("CHARM");
  flags_translation[i].bit = 4194304;
  flags_translation[i].FA = 1;

  // Immunities:
  i = 0;
  imm_types[i].flag = strdup("FIRE");
  imm_types[i].bit = 1;
  imm_types[++i].flag = strdup("COLD");
  imm_types[i].bit = 2;
  imm_types[++i].flag = strdup("ELEC");
  imm_types[i].bit = 4;
  imm_types[++i].flag = strdup("ENERGY");
  imm_types[i].bit = 8;
  imm_types[++i].flag = strdup("BLUNT");
  imm_types[i].bit = 16;
  imm_types[++i].flag = strdup("PIERCE");
  imm_types[i].bit = 32;
  imm_types[++i].flag = strdup("SLASH");
  imm_types[i].bit = 64;

  // positions
  i = 0;
  positions[i].flag = strdup("SLEEPING");
  positions[i].bit = 4;
  positions[++i].flag = strdup("RESTING");
  positions[i].bit = 5;
  positions[++i].flag = strdup("SITTING");
  positions[i].bit = 6;
  positions[++i].flag = strdup("STANDING");
  positions[i].bit = 8;


  i = 0;
	classes[i].flag = strdup("MAGE");
	classes[i].bit = 1;
	classes[++i].flag = strdup("CLERIC");
	classes[i].bit = 2;
	classes[++i].flag = strdup("WARRIOR");
	classes[i].bit = 4;
	classes[++i].flag = strdup("THIEF");
	classes[i].bit = 8;
	classes[++i].flag = strdup("RANGER");
	classes[i].bit = 16;
	classes[++i].flag = strdup("DRUID");
	classes[i].bit = 32;
}

// Section 2: Constructors

cmob::cmob()
{
  if(!cmob_flags_initialized) initialize_cmob_flags_translation();
  virtual_number = 0;
  name_list = NULL;
  short_description = long_description = description = 
    localsound = distantsound = NULL;
  act_flags = affection_flags = alignment = 0;
  race = sex = 1;
	Class = 4;
  weight = 250;	 
  height = 198;
  gold.num = gold.side = gold.bonus = 0;
  XP.num = XP.side = XP.bonus = 1;
  level = 1;
  HP.num = HP.side = HP.bonus = 1; 
  AC = 6;
  thaco = 10;
  attacks_per_round = 1;
  damage.num = damage.side = damage.bonus = 3; 
  type = 1;
  immunities = resistance = susceptibility = 0;
  str.num = dex.num = con.num = intel.num = wis.num = 3;
  str.side = dex.side = con.side = intel.side = wis.side = 6;
  str.bonus = dex.bonus = con.bonus = intel.bonus = wis.bonus = 0;
  stradd.num = stradd.side = stradd.bonus = 0;

  sav1 = sav2 = sav3 = sav4 = sav5 = 10;
  def_position = position = 8;
  sound = 0;
  localsound = distantsound = NULL;
}
 
cmob::cmob(const char *input_file_name)
{
  cmob();
  file_mob_in = fopen(input_file_name, "r");
  if(!file_mob_in)
  { cerr << "Fatal Error opening file: " << input_file_name << endl;
    exit(-14);
  }
}

cmob::~cmob(void)
{
  // Well, lots of things may or may not have been allocated, so lets
  // free stuff up.
  if(name_list)
    free(name_list);
  if(short_description)
  	free(short_description);
  if(long_description)
	free(long_description);
  if(localsound)
	free(localsound);
  if(distantsound)
	free(distantsound);
}
  
// Section 3: Integer Variables:

long cmob::get_skill_count(void)
{  return skill_count; }

void cmob::set_number(long num)
{  if(num > -1) virtual_number = num; }
long cmob::get_number(void)
{  return virtual_number; }

void cmob::set_sav1(long n)
{  sav1 = n; }
long cmob::get_sav1(void)
{ return sav1; }

void cmob::set_sav2(long n)
{  sav2 = n; }
long cmob::get_sav2(void)
{  return sav2; }

void cmob::set_sav3(long n)
{  sav3 = n; }
long cmob::get_sav3(void)
{  return sav3; }

void cmob::set_sav4(long n)
{  sav4 = n; }
long cmob::get_sav4(void)
{  return sav4; }

void cmob::set_sav5(long n)
{  sav5 = n; }
long cmob::get_sav5(void)
{  return sav5; }

void cmob::set_alignment(long n)
{ if(n>=-1000 && n<=1000) alignment = n; }
long cmob::get_alignment(void)
{ return alignment; }

void cmob::set_height(long n)
{ if(n>0) height = n; }
long cmob::get_height(void)
{ return height; }

void cmob::set_weight(long n)
{ if(n>0) weight = n; }
long cmob::get_weight(void)
{ return weight; }

void cmob::set_level(long n)
{ if(n>0) level = n; }
long cmob::get_level(void)
{ return level; }

void cmob::set_AC(long n)
{ AC = n; }
long cmob::get_AC(void)
{ return AC; }

void cmob::set_thaco(long n)
{ thaco = n; }
long cmob::get_thaco(void)
{ return thaco; }

void cmob::set_attacks_per_round(long n)
{ if(n>0) attacks_per_round = n; }
long cmob::get_attacks_per_round(void)
{ return attacks_per_round; }

// section 4: dice variables

void copydice(dice& a, dice b)
{  a.num = b.num;  a.side = b.side;  a.bonus = b.bonus; }

void cmob::set_gold(dice d)
{  copydice(gold, d); }
dice *cmob::get_gold(void)
{  return &gold;  }

void cmob::set_XP(dice d)
{  copydice(XP, d); }
dice *cmob::get_XP(void)
{  return &XP;  }

void cmob::set_HP(dice d)
{  copydice(HP, d); }
dice *cmob::get_HP(void)
{  return &HP;  }

void cmob::set_damage(dice d)
{  copydice(damage, d);  }
dice *cmob::get_damage(void)
{  return &damage;  }

void cmob::set_str(dice d)
{  copydice(str, d); }
dice *cmob::get_str(void)
{  return &str; }

void cmob::set_stradd(dice d)
{  copydice(stradd, d); }
dice *cmob::get_stradd(void)
{  return &stradd; }

void cmob::set_dex(dice d)
{  copydice(dex, d);  }
dice *cmob::get_dex(void)
{  return &dex; }

void cmob::set_con(dice d)
{  copydice(con, d); }
dice *cmob::get_con(void)
{  return &con; }

void cmob::set_intel(dice d)
{  copydice(intel, d); }
dice *cmob::get_intel(void)
{  return &intel; }

void cmob::set_wis(dice d)
{  copydice(wis, d); }
dice *cmob::get_wis(void)
{  return &wis; }


// Section 5: File Access
char *cmob::fread_string(void)
{
  char buf[MAX_STR_LENGTH], tmp[MAX_STR_LENGTH];
  char *ack;
  char *rslt;
  register char *point;
  int flag;

  for(register int i = 0; i < MAX_STR_LENGTH; i++)
  {  buf[i] = 0; tmp[i] = 0; }

  do {
    if(!fgets(tmp, MAX_STR_LENGTH, file_mob_in))
    {  cerr << "File read error.\n" << "String so far:\n" << buf; 
       exit(-1);
    }
    ack = tmp;
    if(strlen(ack) + strlen(buf) + 1 > MAX_STR_LENGTH)
    {  ack[MAX_STR_LENGTH - strlen(buf) - 2] = '\0';
       cerr << "String too long in mob #" << virtual_number << endl;
    }
    strcat(buf, ack);

    for(point = buf+strlen(buf)-2; point >= buf && 
				((*point == ' ') || (*point == '\n') || (*point == '\r')
				 || (*point == '\0'));
		point--);
    if(flag=(*point == '~'))
      if(*(buf+strlen(buf)-3) == '\n')
      {
        *(buf+strlen(buf)-2) = '\0';
        *(buf+strlen(buf)-1) = '\0';
      } else 
        *(buf+strlen(buf)-2) = '\0';
    else {
      *(buf+strlen(buf)+1) = '\0';
      *(buf+strlen(buf)) = '\0';
    }
  } while(!flag);
  // do the allocate boogie:
  if(strlen(buf) > 0)
  {
    return strdup(buf);
  }
  return 0;
}


int cmob::load(void)
{
  if(!file_mob_in)
    { cerr << "ERROR!  Attempt to load from unopened file!\n";
      exit(-1);
    }
  
  int i;
  long tmp, tmp2, tmp3, tmp4, tmp5, tmp6;
  char buf[100];
  char letter;

  cmob();

  // Line One:
  fscanf(file_mob_in, "#%i", &i);
  virtual_number = i;
  fscanf(file_mob_in, "\n");
  
  // Line Two:
  name_list = fread_string();
  short_description = fread_string();
  long_description = fread_string();
  description = fread_string();

  // Numeric Data:
  attacks_per_round = 0;
  fscanf(file_mob_in, "%d ", &tmp);
  act_flags = tmp;

  fscanf(file_mob_in, " %d ", &tmp);
  affection_flags = tmp;

  fscanf(file_mob_in, " %d ", &tmp);
  alignment = tmp;

  Class = 1;

  fscanf(file_mob_in, " %c ", &letter);

  switch(letter) {
    case 'W':
    case 'M':
    case 'S':
    {
      if((letter == 'W') || (letter == 'M'))
      {
        fscanf(file_mob_in, " %D ", &tmp);
        attacks_per_round = tmp;
      }
      fscanf(file_mob_in, "\n");
   
      // The new easy monsters:
      str.num = intel.num = wis.num = dex.num = con.num = 14;
      str.side = intel.side = wis.side = dex.side = con.side = 1;
      str.bonus = intel.bonus = wis.bonus = dex.bonus = con.bonus = 0;

      fscanf(file_mob_in, " %D ", &tmp);
      level = tmp;
 
      fscanf(file_mob_in, " %D ", &tmp);
      thaco = tmp;

      fscanf(file_mob_in, " %D ", &tmp);
      AC = tmp;
 
      fscanf(file_mob_in, " %Dd%D+%D ", &tmp, &tmp2, &tmp3);
      HP.num = tmp;  HP.side = tmp2;  HP.bonus = tmp3;

      fscanf(file_mob_in, " %Dd%D+%D ", &tmp, &tmp2, &tmp3);
      damage.num = tmp;  damage.side = tmp2;  damage.bonus = tmp3;

      fscanf(file_mob_in, " %D ", &tmp);
      if (tmp == -1)
      {
	fscanf(file_mob_in, " %D ", &tmp);
      	gold.num = tmp;
        gold.side = 1;
        gold.bonus = 0;
      	fscanf(file_mob_in, " %D ", &tmp);
	XP.num = tmp;
     	XP.side = 1;
	XP.bonus = 0;
 	fscanf(file_mob_in, " %D \n", &tmp);
	race = tmp;
      } else {
	gold.num = tmp;
        gold.side = 1;
        gold.bonus = 1;
	fscanf(file_mob_in, " %D \n", &tmp);
	XP.num = tmp;
	XP.side = 1;
	XP.bonus = 0;
      }

      fscanf(file_mob_in, " %D ", &tmp);
      position = tmp;
      fscanf(file_mob_in, " %D ", &tmp); // this would be def_position
      def_position = tmp;

      fscanf(file_mob_in, " %D ", &tmp); 
      if(tmp<3)
      {
	sex = tmp;
	immunities = resistance = susceptibility = 0;
      } else if(tmp<6) {
	sex = tmp-3;
	fscanf(file_mob_in, " %D ", &tmp);
	immunities = tmp;
	fscanf(file_mob_in, " %D ", &tmp);
	resistance = tmp;
	fscanf(file_mob_in, " %D ", &tmp);
	susceptibility = tmp;
      } else {
	sex = immunities = resistance = susceptibility = 0;
      }
      fscanf(file_mob_in, "\n");

      height = 198;
      weight = 250;

      // read in the sound string:
      if(letter == 'W')
      {
	localsound = fread_string();
	distantsound = fread_string();
      } else {
	localsound = distantsound = 0;
      }
    } break;

    case 'D':
      cerr << "No Support for type D Mobile in number " << virtual_number
	   << endl;
      exit(-2);
      break;

    case 'C': {
      register int x;
      int lvl;
      
      fscanf(file_mob_in, " %d %d %d %d %d", &tmp, &tmp2, &tmp3, &tmp4
					   , &tmp5);
      race = tmp;
      Class = tmp2;
      sex = tmp3;
      height = tmp4;
      weight = tmp5;
  
      fscanf(file_mob_in, " %dd%d+%d ",&tmp, &tmp2, &tmp3);
      gold.num = tmp; gold.side = tmp2; gold.bonus = tmp3;
      fscanf(file_mob_in, "\n");
      fscanf(file_mob_in, " %dd%d+%d ", &tmp,&tmp2,&tmp3);
      XP.num = tmp; XP.side = tmp2; XP.bonus = tmp3;

      fscanf(file_mob_in, " %d ", &tmp);
      level = tmp;
      
      fscanf(file_mob_in, " %dd%d+%d ", &tmp,&tmp2,&tmp3);
      HP.num = tmp;  HP.side = tmp2;  HP.bonus = tmp3;

      fscanf(file_mob_in, " %d %d %d \n", &tmp,&tmp2,&tmp3);
      AC = tmp;
      thaco = tmp2;
      attacks_per_round = tmp3 < 0 ? 1 : tmp3;

      for(x = 0; x < attacks_per_round; x++)
      {
	fscanf(file_mob_in, " %dd%d+%d %d \n",&tmp,&tmp2,&tmp3,&tmp4);
	damage.num = tmp; damage.side = tmp2; damage.bonus = tmp3;
	type = 1;
      }
     
      fscanf(file_mob_in, " %d %d %d \n",&tmp,&tmp2,&tmp3);
      immunities = tmp;
      resistance = tmp2;
      susceptibility = tmp3;

      fscanf(file_mob_in, " %dd%d+%d ",&tmp,&tmp2,&tmp3);
      str.num = tmp; str.side = tmp2; str.bonus = tmp3;
      fscanf(file_mob_in, " %dd%d+%d ",&tmp,&tmp2,&tmp3);
      stradd.num = tmp; stradd.side = tmp2; stradd.bonus = tmp3;
      fscanf(file_mob_in, " %dd%d+%d ",&tmp,&tmp2,&tmp3);
      dex.num = tmp; dex.side = tmp2; dex.bonus = tmp3;
      fscanf(file_mob_in, " %dd%d+%d ",&tmp,&tmp2,&tmp3);
      con.num = tmp; con.side = tmp2; con.bonus = tmp3;
      fscanf(file_mob_in, " %dd%d+%d ",&tmp,&tmp2,&tmp3);
      intel.num = tmp; intel.side = tmp2; intel.bonus = tmp3;
      fscanf(file_mob_in, " %dd%d+%d ",&tmp,&tmp2,&tmp3);
      wis.num = tmp; wis.side = tmp2; wis.bonus = tmp3;

      fscanf(file_mob_in, "\n");
     
      fscanf(file_mob_in, " %d %d %d %d %d\n",&tmp,&tmp2,&tmp3,&tmp4,&tmp5);
      sav1 = tmp; sav2=tmp2; sav3=tmp3; sav4=tmp4; sav5=tmp5;

      fscanf(file_mob_in, "\n");
      
      fscanf(file_mob_in, " %d %d %d %d\n",&tmp,&tmp2,&tmp3,&tmp4);
      position = tmp;  def_position = tmp2;
      if(sound = tmp3)
      {
         localsound = fread_string();
         distantsound = fread_string();
      }
      if(skill_count = tmp4) 
      {
        if(tmp4 > MAX_SKILLS)
					{  cerr << "ERROR!  Too many skills in mob " << virtual_number
									<< endl;
	   				 exit(-4);
        	}
        for(x=0; x<tmp4; x++)
	  if((fscanf(file_mob_in, " %d %d %d\n",&tmp,&tmp2,&tmp3))==3)
	  { skill_num[x] = tmp; skill_learned[x] = tmp2;
	    skill_recognized[x] = tmp3;
          }
      }
    }
    break;
  default:
    fprintf(stderr,"Unknown mob type in mob %d\n",virtual_number);
    exit(-5);
    break;
  }
}
  
int cmob::write(const char *output_file_name)
{
  file_mob_out = fopen(output_file_name, "w");
  return this->write();
}

int cmob::write()
{
  if(!file_mob_out) 
  {
    cerr << "ERROR!  Can't access output file.\n";
    return 0;
  }
  fprintf(file_mob_out,"#%d\n",virtual_number);
  fprintf(file_mob_out,"%s~\n",name_list);
  fprintf(file_mob_out,"%s~\n",short_description);
  fprintf(file_mob_out,"%s\n~\n",long_description);
  fprintf(file_mob_out,"%s\n~\n",description);

  fprintf(file_mob_out,"%d %d %d C\n",act_flags,affection_flags,alignment);

  fprintf(file_mob_out,"%d %d %d %d %d %dd%d+%d\n",
		race, Class, sex, height, weight,
		gold.num, gold.side, gold.bonus);

  fprintf(file_mob_out, "%dd%d+%d %d %dd%d+%d %d %d %d\n",
		XP.num, XP.side, XP.bonus,
		level,
		HP.num, HP.side, HP.bonus,
		AC, thaco, attacks_per_round);

  for(register int i = 0; i < attacks_per_round; i++)
	fprintf(file_mob_out, "%dd%d+%d %d\n",
		damage.num, damage.side, damage.bonus, type);
  fprintf(file_mob_out, "%d %d %d\n", 
	        immunities, resistance, susceptibility);

  // the stats:
  fprintf(file_mob_out, "%dd%d+%d %dd%d+%d %dd%d+%d %dd%d+%d %dd%d+%d %dd%d+%d\n",
	str.num, str.side, str.bonus,
	stradd.num, stradd.side, stradd.bonus,
	dex.num, dex.side, dex.bonus,
	con.num, con.side, con.bonus,
	intel.num, intel.side, intel.bonus,
	wis.num, wis.side, wis.bonus);

  fprintf(file_mob_out, "%d %d %d %d %d\n",
	sav1, sav2, sav3, sav4, sav5);

  fprintf(file_mob_out, "%d %d %d %d\n",
	position, def_position, sound, skill_count);

  if(sound)
  {
    fprintf(file_mob_out,"%s~\n",localsound);
    fprintf(file_mob_out,"%s~\n",distantsound);
  }

  for(
#ifdef HOME
register int 
#endif
       i = 0; i < skill_count; i++)
  {
    fprintf(file_mob_out, "%d %d %d\n",
	skill_num[i], skill_learned[i], skill_recognized[i]);
  }
}



// Section 6: bits
void cmob::set_bit(long &bitfield, long bit)
{  bitfield |= bit; }

void cmob::toggle_bit(long &bitfield, long bit)
{  bitfield ^= bit; }


// Section 7: strings
void cmob::display_name_list(void)
{  if(name_list) cout << name_list; }

void cmob::display_short_description(void)
{ if(short_description) cout << short_description; }

void cmob::display_long_description(void)
{ if(long_description) cout << long_description; }

void cmob::display_description(void)
{ if(description) cout << description; }

void cmob::display_race(void)
{ printf("%s",races[race]); }

void cmob::display_sex(void)
{ printf("%s",sexes[sex]); }

void cmob::display_localsound(void)
{ if(localsound) cout << localsound; }

void cmob::display_distantsound(void)
{ if(distantsound) cout << distantsound; }

void cmob::display_avail_classes(void)
{
		printf("Available classes:\n");
		for(register int i = 0; i < 6; i++)
		{
				printf("%-15s", classes[i].flag);
				if(!((i+1)%4)) printf("\n");
		}
		printf("\n");
}

void cmob::display_avail_races(void)
{
  printf("Available Races:\n");
  for(register int i = 0; races[i][0]; i++)
  {
    printf("%-15s", races[i]);
    if(!((i+1)%4)) printf("\n");
  }
  printf("\n");
}

void cmob::display_avail_sexes(void)
{
  printf("Available Sexes:\n");
  printf("%-15s%-15s%-15s\n","MALE","FEMALE","NEUTRAL");
}

void cmob::display_avail_positions(void)
{
  printf("Available positions:\n");
  printf("%-15s%-15s%-15s%-15s\n",
	positions[0].flag, positions[1].flag,
	positions[2].flag, positions[3].flag);
}


void cmob::set_name_list(void)
{
  char buffer[250];
  cout << endl;
  cout << "Please enter a list of names, seperated by spaces:\n> ";
  cin.getline(buffer, 250);

  if(!buffer) return;

  if(name_list)
    free(name_list); 

  name_list = strdup(buffer);
}

void cmob::set_short_description(void)
{
  char buffer[250];
  cout << endl;
  cout << "Please enter a short description for your mob:\n> ";
  cin.getline(buffer, 250);

  if(!buffer) return;

  if(name_list)
    free(short_description); 

  short_description = strdup(buffer);
}

void cmob::set_long_description(void)
{
  char buffer[250];
  cout << endl;
  cout << "Please enter a long description for your mob:\n> ";
  cin.getline(buffer, 250);

  if(!buffer) return;

  if(name_list)
    free(long_description); 

  long_description = strdup(buffer);
}

char *cmob::edit_tmp_file_and_load(void)
{
  char buffer[30*80];
  int curpos = 0;
  char tmp[100]; 
  char *tmpfilename;
  FILE *tmpfile;
 
  tmpfilename = tempnam(".","MBG");
  //shell to vi
	sprintf(tmp, "vi %s",tmpfilename);
  system(tmp);
  //returned from vi

  tmpfile = fopen(tmpfilename, "r");
  while(!feof(tmpfile))
  {
    buffer[curpos] = fgetc(tmpfile);
    curpos++;
    if(curpos>=30*80)
    { cerr << "Buffer exceeded in edit_tmp_file\n";
      return NULL;
    }
  }
  buffer[curpos-1] = '\0';

  fclose(tmpfile);
 
  unlink(tmpfilename);
  free(tmpfilename);
  return strdup(buffer);
}

void cmob::set_description(void)
{
  char *tmp = edit_tmp_file_and_load();
  if(!tmp) return;
  if(description)
    free(description);
  description = tmp;
}

int cmob::set_race(const char *newrace)
{
  for(register int i = 0; races[i][0]; i++)
  {
    if(!strncasecmp(races[i], newrace, 6))
    {  race = i;  return 0; }
  }
	return 1;
}

int cmob::set_sex(const char *newsex)
{
  for(register int i = 0; i<3; i++)
  {  if(!strncasecmp(newsex, sexes[i], 1))
     {  sex = i; 
        if(immunities || resistance || susceptibility)
	  			sex += 3;
        return 0;
     }
   }
	return 1;
}

int cmob::setp(long &pvar, const char *newpos)
{
  for(register int i = 0;  i<4; i++)
  {
    if(!strncasecmp(positions[i].flag, newpos, 2))
    {  pvar = positions[i].bit;  return 0; }
  }
	return 1;
}

int cmob::set_class(const char *n)
{
		for(register int i = 0; i<6; i++)
		{
				if(!strncasecmp(classes[i].flag, n, 1))
				{
						Class = classes[i].bit;
						return 0;
				}
		}
		return 1;
}

int cmob::set_position(const char *n)
{
  return setp(position, n);
}

int cmob::set_def_position(const char *n)
{
  return setp(def_position, n);
}


// Section 8: Flag Functions
long cmob::test_bit(long field, long bit)
{  return (field & bit); } 

int cmob::toggle_flag(const char *in)
{
  int i;
  for(i = 0; i < NUMFLAGS; i++)
  {
    if(!strncasecmp(in, flags_translation[i].flag, 4))
	break;
  }
  if(i == NUMFLAGS)
			return 1;

  switch(flags_translation[i].FA)
  {
    case 0: act_flags ^= flags_translation[i].bit; break;
    case 1: affection_flags ^= flags_translation[i].bit; break;
  }
	return 0;
}

void cmob::display_avail_flags(void)
{
  printf("\nACTION FLAGS:\n");
  int i = 0;
  while(flags_translation[i].FA == 0)
  {
			printf("%-15s",flags_translation[i].flag);
			if(!((i+1)%4)) printf("\n");
			i++;
  }

  printf("\n\nAffection Flags:\n");
  while(i<NUMFLAGS)
  {
			printf("%-15s",flags_translation[i].flag);
			if(!((i+1)%4)) printf("\n");
			i++;
  }
	printf("\n");
}

void cmob::display_act_flags(void)
{
  int i = 0;  int counter = 0;
  while(flags_translation[i].FA == 0)
  {
    if(test_bit(act_flags, flags_translation[i].bit))
    {
      printf("%-15s", flags_translation[i].flag);
      counter++;
      if(!((counter+1)%4))
	printf("\n");
    }
    i++;
  }
}

void cmob::display_affection_flags(void)
{
  int i = 0;  int counter = 0;
  while(flags_translation[i].FA == 0) i++;

  while(i<NUMFLAGS)
  {
    if(test_bit(affection_flags, flags_translation[i].bit))
    {
      printf("%-15s", flags_translation[i].flag);
      counter++;
      if(!((counter+1)%4))
	printf("\n");
    }
    i++;
  }
}



// Section 9: IRS -- Immuns, Resistance, Sucept...
void cmob::display_avail_irs(void)
{
		for(register int i = 0; i < 7; i++)
		{
				printf("%-10s",imm_types[i].flag);
				if(!((i+1)%4)) printf("\n");
		}
	printf("\n");
}

void cmob::disp_irs(long field)
{
  for(register int i = 0; i < 7; i++)
  {
    if(test_bit(field, imm_types[i].bit))
  	printf("%-10s", imm_types[i].flag);
  }
  printf("\n");
}

void cmob::display_immunities(void)
{
  printf("Immunities:\n");
  disp_irs(immunities);
}

void cmob::display_resistance(void)
{
  printf("Resistance:\n");
  disp_irs(resistance);
}

void cmob::display_susceptibility(void)
{
  printf("Susceptibility:\n");
  disp_irs(susceptibility);
}

int cmob::toggle_irs(long &irs, const char *flag)
{
  register int i;
  for(i = 0; i<7; i++)
  {
    if(!strncasecmp(flag, imm_types[i].flag, 2))
      break;
  }
  if(i==7) return 1;
  irs ^= imm_types[i].bit;
  if((sex < 3) && (susceptibility || immunities || resistance))
    sex += 3;
  return 0;
}

int cmob::toggle_immunities(const char *n)
{ return toggle_irs(immunities, n); }

int cmob::toggle_resistance(const char *n)
{ return toggle_irs(resistance, n); }

int cmob::toggle_susceptibility(const char *n)
{ return toggle_irs(susceptibility, n); }


// Section 10: Positions
void cmob::disppos(long field)
{
  for(register int i = 0; i < 4; i++)
    if(field == positions[i].bit)
	printf("%s", positions[i].flag);
}

void cmob::display_class(void)
{
		for(register int i = 0; i<6; i++)
				if(Class == classes[i].bit)
						printf("%s",classes[i].flag);
}

void cmob::display_position(void)
{
  disppos(position);
}

void cmob::display_def_position(void)
{  
   disppos(def_position);
}



// Section 11: The AREYOU function
int cmob::areyou(const char *compstr)
{
  long compl = atol(compstr);
  if(compl != 0)
    return (compl == virtual_number);

  if((compl == 0) && (virtual_number == 0))
    return 1;

  // at this point, we know compstr is not a number.
  int compstrptr = 0;
  int curpos = 0;
  
  while(name_list[curpos])
  {
    while(toupper(name_list[curpos]) == toupper(compstr[compstrptr]))
    {
      if(name_list[curpos] == '\0' && compstr[compstrptr] == '\0')
	return 1;
      if(name_list[curpos] == ' ' && compstr[compstrptr] == '\0')
        return 1;
      curpos++; compstrptr++;
    }
    while(name_list[curpos] != ' ' && name_list[curpos] != '\0')
	    curpos++;
    while(name_list[curpos] == ' ' && name_list[curpos] != '\0')
				curpos++;

    compstrptr = 0;
  }
  return 0;
}

// Section 12: Sounds
int cmob::aresounds(void)
{ return sound; }

void cmob::setsound(void)
{
  cout << "Press any key to begin editing the local sound...";
  getchar();
  char *tmp = edit_tmp_file_and_load();
  if(!tmp) return;
  if(localsound)
    free(localsound);
  localsound = tmp;
  cout << "Local Sound set to:\n" << localsound;
  cout << "Press any key to begin editing the distant sound...";
  getchar();
  tmp = edit_tmp_file_and_load();
  if(!tmp) return;
  if(distantsound)
    free(distantsound);
  distantsound = tmp;
  sound = 1;
}

// Section 13: Skills
long cmob::get_skill_num(long n)
{ return skill_num[n]; }

long cmob::get_skill_learned(long n)
{ return skill_learned[n]; }

long cmob::get_skill_recognized(long n)
{ return skill_recognized[n]; }

void cmob::add_skill(int num, int learned, int recognized)
{
  skill_num[skill_count] = num;
  skill_learned[skill_count] = learned;
  skill_recognized[skill_count] = recognized;
  skill_count++;
}

void cmob::remove_skill(int skillnum)
{
  register int i;
  for(i = 0; i < skill_count; i++)
    if(skill_num[i] == skillnum)
      break;

  if(i == skill_count)
    return;

  // right now, skill_num[i] is the skill to be removed.
  for(register int c = i; i < skill_count-2; i++)
  {
    skill_num[c] = skill_num[c+1];
    skill_learned[c] = skill_learned[c+1];
    skill_recognized[c] = skill_recognized[c+1];
  }
  skill_count--;
  return;
}

#endif