ur/
ur/boards/
ur/clans/
ur/councils/
ur/homes/
ur/planets/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "mud.h"


HOME_DATA * first_home;
HOME_DATA * last_home;
static	OBJ_DATA *	rgObjNest	[MAX_NEST];
int file_ver;

#if defined(KEY)
#undef KEY
#endif

#define KEY( literal, field, value )					\
				if ( !str_cmp( word, literal ) )	\
				{					\
				      field = value;			\
				      fMatch = TRUE;			\
				      break;				\
				}

char *	const	home_flags	[] =
{
"basic","r1","r2","r3","r4","r5","r6","r7","r8",
"r9","r10","r11", "r12", "r13", "r14","r15","r16",
"r17","r18", "r19", "r20", "r21", "r22","r23","r24",
"r25", "r26", "r27", "r28", "r29", "r30", "r31" , "r32",
"r33","r34"
};

HOME_DATA *home_from_entrance( int vnum )
{
	HOME_DATA *home;
	
	for ( home = first_home; home; home = home->next )
	{
		if ( vnum == home->entrance )
			return home;
	}
	return NULL;
}

/*
 * Get pointer to home structure from the home vnun.
 */
HOME_DATA *home_from_vnum( int vnum )
{
    HOME_DATA *home;
    
    for ( home = first_home; home; home = home->next )
	{
       if ( vnum >= home->firstroom && vnum <= home->lastroom )
            return home;
	}
    return NULL;
}

HOME_DATA *get_home( char *name )
{
	HOME_DATA *home;

    for ( home = first_home; home; home = home->next )
		if ( !str_cmp( name, home->name ) )
			return home;
    
    for ( home = first_home; home; home = home->next )
		if ( nifty_is_name( name, home->name ) )
			return home;

    for ( home = first_home; home; home = home->next )
		if ( !str_prefix( name, home->name ) )
			return home;
    
    for ( home = first_home; home; home = home->next )
		if ( nifty_is_name_prefix( name, home->name ) )
			return home;
	
	return NULL;
}



int get_homeflag( char *type )
{
	int x;

    for ( x = 0; x < (sizeof(home_flags) / sizeof(home_flags[0]) ); x++ )
      if ( !str_cmp( type, home_flags[x] ) )
        return x;
    return -1;
}

void fread_home( HOME_DATA *home, FILE *fp )
{
	char buf[MAX_STRING_LENGTH];
	char *word;
	bool fMatch;
	
	for ( ; ; )
	{
		word   = feof( fp ) ? "End" : fread_word( fp );
		fMatch = FALSE;
		
		switch ( UPPER(word[0]) )
		{
			case '*':
				fMatch = TRUE;
				fread_to_eol( fp );
				break;
			
			case 'C':
				KEY( "Class",       home->class,            fread_number( fp ) );
				KEY( "Copilot",     home->copilot,          fread_string( fp ) );
				break;
			
			case 'D':
				KEY( "Description",	home->description,	fread_string( fp ) );
				break;
				
			case 'E':
				if ( !str_cmp( word, "End" ) )
				{
					if (!home->flags)
						home->flags = 0;
					if (!home->name)
						home->name		= STRALLOC( home->filename );
					if (!home->origname)
						home->origname	= STRALLOC( home->name );
					if (!home->owner)
						home->owner			= STRALLOC( "Unowned" );
					if (!home->copilot)
						home->copilot 	= STRALLOC( "" );
					if (!home->pilot)
						home->pilot   	= STRALLOC( "" );  		
					if ( home->firstroom && !home->entrance)
						home->entrance = home->firstroom;
					home->in_room=NULL;
					home->next_in_room=NULL;
					home->prev_in_room=NULL;
					return;
				}
				KEY( "Entrance",   home->entrance,        fread_number( fp ) );
				break;
				
			case 'F':
				KEY( "Filename",	home->filename,		fread_string_nohash( fp ) );
				KEY( "Firstroom",   home->firstroom,        fread_number( fp ) );
				KEY( "Flags",       home->flags,			fread_number( fp ) );
				break;
			
			case 'L':
				KEY( "Lastroom",   home->lastroom,        fread_number( fp ) );
				break;
				
			case 'N':
				KEY( "Name",	home->name,		fread_string( fp ) );
				break;
			
			case 'O':
				KEY( "OrigName",		 home->origname,       fread_string( fp ) );
				KEY( "Owner",	home->owner,		fread_string( fp ) );
				break;
				
			case 'P':	
				KEY( "Pilot",            home->pilot,            fread_string( fp ) ); 
				KEY( "Price",            home->price,            fread_number( fp ) ); 
				break;
			
			case 'T':
				KEY( "Type",		home->type,		fread_number( fp ) );
				break;
		}
		
		if ( !fMatch )
		{
			sprintf( buf, "Fread_home: no match: %s", word );
			bug( buf, 0 );
		}
	}
}

/*
 * Load in all the home files.
 */
void load_homes( )
{
    FILE *fpList;
    char *filename;
    char homelist[256];
    char buf[MAX_STRING_LENGTH];
    first_home	= NULL;
    last_home	= NULL;
    
    log_string( "Loading homes..." );

    sprintf( homelist, "%s%s", HOMEDIR, HOME_LIST );
    fclose( fpReserve );

    if ( ( fpList = fopen( homelist, "r" ) ) == NULL )
    {
	perror( homelist );
	exit( 1 );
    }

    for ( ; ; )
    {
    
	filename = feof( fpList ) ? "$" : fread_word( fpList );

	if ( filename[0] == '$' )
	  break;
	         
	if ( !load_home_file( filename ) )
	{
	  sprintf( buf, "Cannot load home file: %s", filename );
	  bug( buf, 0 );
	}

    }
    fclose( fpList );
    log_string(" Done homes " );
    fpReserve = fopen( NULL_FILE, "r" );
    return;
}

/*
 * Load a home file
 */

bool load_home_file( char *homefile )
{
    char filename[256];
    HOME_DATA *home;
    FILE *fp;
    bool found;
        
    CREATE( home, HOME_DATA, 1 );

    found = FALSE;
    sprintf( filename, "%s%s", HOMEDIR, homefile );

    if ( ( fp = fopen( filename, "r" ) ) != NULL )
    {

		found = TRUE;
		for ( ; ; )
		{
			char letter;
			char *word;
			int iNest;

			for ( iNest = 0; iNest < MAX_NEST; iNest++ )
				rgObjNest[iNest] = NULL;

			letter = fread_letter( fp );
			if ( letter == '*' )
			{
				fread_to_eol( fp );
				continue;
			}

			if ( letter != '#' )
			{
				bug( "Load_home_file: # not found.", 0 );
				break;
			}

			word = fread_word( fp );
			if ( !str_cmp( word, "HOME"	) )
				fread_home( home, fp );
			else if ( !str_cmp( word, "OBJECT" ) )
				fread_obj_home( home, fp, OS_CARRY);
			else if ( !str_cmp( word, "CORPSE" ) )
				fread_obj_home( home, fp, OS_CORPSE);
			
			else if ( !str_cmp( word, "END"	) )	       
				break;
			
			else
			{
				char buf[MAX_STRING_LENGTH];

				sprintf( buf, "Load_home_file: bad section: %s.", word );
				bug( buf, 0 );
				break;
			}
		}
		fclose( fp );
    }
    if ( !(found) )
		DISPOSE( home );
    else
    {      
		LINK( home, first_home, last_home, next, prev );
    }
    
    return found;
}

void save_home2( HOME_DATA *home )
{
    FILE *fp;
    char filename[256];
    char buf[MAX_STRING_LENGTH];
	OBJ_DATA *contents;

    if ( !home || home == NULL )
    {
		bug( "save_home2: null home pointer!", 0 );
		return;
    }
        
    if ( !home->filename || home->filename[0] == '\0' )
    {
		sprintf( buf, "save_home2: %s has no filename", home->name );
		bug( buf, 0 );
		return;
	}
 
	sprintf( filename, "%s%s", HOMEDIR, home->filename );
    
	fclose( fpReserve );
    if ( ( fp = fopen( filename, "w" ) ) == NULL )
    {
    	bug( "save_home2: fopen", 0 );
    	perror( filename );
    }
    else
    {
		fprintf( fp, "#HOME\n" );
		fprintf( fp, "Name         %s~\n",	home->name		    );
		fprintf( fp, "Filename     %s~\n",	home->filename		);
		fprintf( fp, "Description  %s~\n",	home->description	);
		fprintf( fp, "Owner        %s~\n",	home->owner			);
		fprintf( fp, "Pilot        %s~\n",      home->pilot     );
		fprintf( fp, "Copilot      %s~\n",      home->copilot   );
		fprintf( fp, "Class        %d\n",	home->class			);
		fprintf( fp, "Firstroom    %d\n",	home->firstroom		);
		fprintf( fp, "Lastroom     %d\n",	home->lastroom		);
		fprintf( fp, "Type         %d\n",	home->type			);
		fprintf( fp, "Flags        %d\n",	home->flags    );
		fprintf( fp, "Price        %ld\n", home->price );
		fprintf( fp, "Entrance    %d\n",  home->entrance );
		fprintf( fp, "End\n\n"						);
		{
			int room;
			ROOM_INDEX_DATA *pRoomIndex;
			if ( home->firstroom == home->lastroom )
			{
				room = home->firstroom;
				if ( (pRoomIndex = get_room_index(room)) == NULL )
				{
					sprintf( buf, "save_home2: 'OBJ': bad room vnum %d.", room );
					bug ( buf, 0 );
				}
				else 
				{
					contents = pRoomIndex->last_content;
					if (contents)
						fwrite_obj_home(supermob, contents, fp, 0, OS_CORPSE );
					/*if (contents)
						fwrite_obj_home(supermob, contents, fp, 0, OS_CARRY );*/
				}
			}
			else
			{
				for ( room = home->firstroom; room <= home->lastroom; room++ )
				{
					if ( (pRoomIndex = get_room_index(room)) == NULL )
					{
						sprintf( buf, "save_home2: 'OBJ': bad room vnum %d.", room );
						bug ( buf, 0 );
						continue;
					}
					else 
					{
						contents = pRoomIndex->last_content;
						if (contents)
							fwrite_obj_home(supermob, contents, fp, 0, OS_CORPSE );
						/*if (contents)
							fwrite_obj_home(supermob, contents, fp, 0, OS_CARRY );*/
					}
				}
			}
		}
		fprintf( fp, "#END\n"						);
	}
	fclose( fp );
	fpReserve = fopen( NULL_FILE, "r" );
    return;
}


void do_sethome( CHAR_DATA *ch, char *argument )
{
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
	char arg3[MAX_INPUT_LENGTH];
    HOME_DATA *home;
    int  tempnum,value;
    ROOM_INDEX_DATA *roomindex;
    
    if ( IS_NPC( ch ) )
    {
	send_to_char( "Huh?\n\r", ch );
	return;
    }

    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );
	strcpy( arg3, argument );

    value = is_number( arg3 ) ? atoi( arg3 ) : -1;

    if ( atoi(arg3) < -1 && value == -1 )
      value = atoi(arg3);


    if ( arg1[0] == '\0' || arg2[0] == '\0' || arg1[0] == '\0' )
    {
	send_to_char( "Usage: sethome <home> <field> <values>\n\r", ch );
	send_to_char( "\n\rField being one of:\n\r", ch );
	send_to_char( "filename name owner copilot pilot description \n\r", ch );
	send_to_char( "firstroom lastroom entrance\n\r", ch );
	return;
    }

    home = get_home( arg1 );
    if ( !home )
	{
		send_to_char( "No such home.\n\r", ch );
		return;
    }
    
    if ( !str_cmp( arg2, "owner" ) )
	{
		STRFREE( home->owner );
		home->owner = STRALLOC( argument );
		send_to_char( "Done.\n\r", ch );
		save_home2( home );
		return;
	}
	
	if ( !str_cmp( arg2, "pilot" ) )
	{
		STRFREE( home->pilot );
		home->pilot = STRALLOC( argument );
		send_to_char( "Done.\n\r", ch );
		save_home2( home );
		return;
	}

	if ( !str_cmp( arg2, "copilot" ) )
	{
		STRFREE( home->copilot );
		home->copilot = STRALLOC( argument );
		send_to_char( "Done.\n\r", ch );
		save_home2( home );
		return;
	}
	if ( !str_cmp( arg2, "firstroom" ) )
	{   
		tempnum = atoi(argument); 
		roomindex = get_room_index(tempnum);
		if (roomindex == NULL)
		{
			send_to_char("That room doesn't exist.\n\r",ch);
			return;
		} 
		home->firstroom = tempnum;
		home->lastroom = tempnum;
		send_to_char( "You will now need to set the other rooms in the home.\n\r", ch );
		save_home2( home );
		return;
	}
	
	if ( !str_cmp( arg2, "lastroom" ) )
	{   
		tempnum = atoi(argument); 
		roomindex = get_room_index(tempnum);
		if (roomindex == NULL)
		{
			send_to_char("That room doesn't exist.\n\r",ch);
			return;
		}
		if ( tempnum < home->firstroom )
		{
			send_to_char("The last room on a home must be greater than or equal to the first room.\n\r",ch);
			return;
    	}
		home->lastroom = tempnum;
		send_to_char( "Done.\n\r", ch );
		save_home2( home );
		return;
	}
	
	if ( !str_cmp( arg2, "entrance" ) )
	{   
		tempnum = atoi(argument); 
		roomindex = get_room_index(tempnum);
		if (roomindex == NULL)
		{
			send_to_char("That room doesn't exist.\n\r",ch);
			return;
		}
		if ( tempnum < home->firstroom || tempnum > home->lastroom )
		{
			send_to_char("The entrance must be between the first and last room.\n\r",ch);
			return;
    	}
		home->entrance = tempnum;
		send_to_char( "Done.\n\r", ch );
		save_home2( home );
		return;
	}

    if ( !str_cmp( arg2, "type" ) )
    {
	if ( !str_cmp( argument, "mob" ) )
	  home->type = MOB_HOME;
	else
	{
	   send_to_char( "home type must be either: hapan, imperial, civilian or mob.\n\r", ch );
	   return;
	}
	send_to_char( "Done.\n\r", ch );
	save_home2( home );
	return;
    }

    if ( !str_cmp( arg2, "name" ) )
    {
	STRFREE( home->name );
	home->name = STRALLOC( argument );
	send_to_char( "Done.\n\r", ch );
	save_home2( home );
	return;
    }

    if ( !str_cmp( arg2, "filename" ) )
    {
	DISPOSE( home->filename );
	home->filename = str_dup( argument );
	send_to_char( "Done.\n\r", ch );
	save_home2( home );
	write_home_list( );
	return;
    }
 
    if ( !str_cmp( arg2, "desc" ) )
    {
	STRFREE( home->description );
	home->description = STRALLOC( argument );
	send_to_char( "Done.\n\r", ch );
	save_home2( home );
	return;
    }


	if ( !str_cmp( arg2, "class" ) )
    {   
		if ( !str_cmp( argument, "apartment" ) )
			home->class = APARTMENT_HOME;
		else if ( !str_cmp( argument, "midsize" ) )
			home->class = MIDSIZE_HOME;
		else if ( !str_cmp( argument, "giant" ) )
			home->class = GIANT_HOME;
		else
		{
			send_to_char( "home class must be either: aparment, midsize or giant.\n\r", ch );
			return;
		}
		send_to_char( "Done.\n\r", ch );
		save_home2( home );
		return;
    }
	
	if ( !str_cmp( arg2, "flags" ) )
    {

	if ( !argument || argument[0] == '\0' )
	{
	   send_to_char( "Usage: sethome <home> flags <flag> [flag]...\n\r", ch );
	   send_to_char( "canflyindoors\n\r", ch );
	   return;
	}
	while ( argument[0] != '\0' )
	{
	   argument = one_argument( argument, arg3 );
	   value = get_homeflag( arg3 );
	   if ( value < 0 || value > 31 )
	     ch_printf( ch, "Unknown flag: %s\n\r", arg3 );
	   else
	   {
	       TOGGLE_BIT(home->flags, 1 << value);
	   }
	}
	send_to_char( "Done.\n\r", ch );
	save_home2( home );
	return;
    }

	if ( !str_cmp( arg2, "price" ) ) 
	{
		long int price;
		price = atoi(arg3);
		if (price > 0) {
			home->price = price;
			ch_printf(ch,"%s is now %ld gold",home->name, home->price);
		}
		else {
			send_to_char("Bad Price",ch);
			return;
		}
		return;
	}
    do_sethome( ch, "" );
    return;
}

void do_showhome( CHAR_DATA *ch, char *argument )
{   
    HOME_DATA *home;

    if ( IS_NPC( ch ) )
    {
	send_to_char( "Huh?\n\r", ch );
	return;
    }

    if ( argument[0] == '\0' )
    {
	send_to_char( "Usage: showhome <home>\n\r", ch );
	return;
    }

    home = get_home( argument );
    if ( !home )
    {
	send_to_char( "No such home\n\r", ch );
	return;
    }
    set_char_color( AT_YELLOW, ch );
    ch_printf( ch, "%s %s : %s\n\rFilename: %s\n\r",
		home->type == PLAYER_HOME ? "PlayerHome" : (home->type == EMPTY_HOME ? "Emptyhome" : "Mob" ),
		home->class == APARTMENT_HOME ? "Apartment" :(home->class == MIDSIZE_HOME ? "Regular Home" : "Unknown" ), 
		home->name,	home->filename);
    ch_printf( ch, "Description: %s\n\rOwner: %s   Pilot: %s   Copilot: %s\n\r",
    			home->description,
    			home->owner, home->pilot,  home->copilot );
	ch_printf( ch, "Firstroom: %d   Lastroom: %d   Entrance: %d\n\r",
    			home->firstroom,
    			home->lastroom,
				home->entrance);
    if (get_trust(ch) == MAX_LEVEL)
		ch_printf( ch, "Home Flags: %s\n\r", flag_string(home->flags, home_flags));
	
    return;
}

void do_makehome( CHAR_DATA *ch, char *argument )
{
    HOME_DATA *home;
    char arg[MAX_INPUT_LENGTH];
    
    argument = one_argument( argument, arg );
    
    if ( !argument || argument[0] == '\0' )
    {
	send_to_char( "Usage: makehome <filename> <home name>\n\r", ch );
	return;
    }

    CREATE( home, HOME_DATA, 1 );
    LINK( home, first_home, last_home, next, prev );

    home->name		= STRALLOC( argument );
	home->origname		= STRALLOC( argument );
    home->description	= STRALLOC( "" );
    home->owner 	= STRALLOC( "Unowned" );
    home->copilot       = STRALLOC( "" );
    home->pilot         = STRALLOC( "" );
    home->type          = EMPTY_HOME;
	home->firstroom		= 100;
	home->lastroom		= 100;
	home->entrance		= 100;
    home->in_room=NULL;
    home->next_in_room=NULL;
    home->prev_in_room=NULL;
    home->filename = str_dup( arg );
    save_home2( home );
    write_home_list( );
	
}


void do_homes( CHAR_DATA *ch, char *argument )
{
    HOME_DATA *home;
	ROOM_INDEX_DATA *room; 
    int count;
    
    if ( !IS_NPC(ch) )
    {
      count = 0;
      send_to_char( "&YThe following homes are owned by you or by your organization:\n\r", ch );
      send_to_char( "\n\r&WHome                               Owner\n\r",ch);
      for ( home = first_home; home; home = home->next )
      {   
		  room = get_room_index(home->firstroom);
		  set_char_color( AT_BLUE, ch );

		  if ( !str_cmp(home->owner, ch->name) )
		  {
			  if  ( room->area->planet )
				  ch_printf( ch, "&R[&WOwner&R]&B%-35s     %s.\n\r",home->name, room->area->planet->name);
			  else
				  ch_printf( ch, "&R[&WOwner&R]&B%-35s     %s.\n\r",home->name,"somewhere");
		  }
		  else if ( !str_cmp(home->pilot, ch->name) || !str_cmp(home->copilot, ch->name) )
		  {
			  if  ( room->area->planet )
				  ch_printf( ch, "&R[&WMember&R]&B%-35s     %s.\n\r",home->name, room->area->planet->name);
			  else
				  ch_printf( ch, "&R[&WMember&R]&B%-35s     %s.\n\r",home->name, "somewhere");
		  }
		  else if ( str_cmp(home->owner,"Unowned") )
		  {
			  if  ( room->area->planet )
				  ch_printf( ch, "&R[&WOwned&R]&B%-35s      %s.\n\r", home->name, room->area->planet->name );
			  else
				  ch_printf( ch, "&R[&WOwned&R]&B%-35s      %s.\n\r", home->name, "somewhere" );
		  }
		  else if ( !str_cmp(home->owner, "Unowned") )
			  ch_printf( ch, "&R[&WUnowned&R]&B%-35s      %ld to buy.\n\r", home->name, get_home_value(home) );
		  else continue;
		  count++;
      }

      if ( !count )
      {
        send_to_char( "There are no homes owned by you.\n\r", ch );
      }    
    }
}

void write_home_list( )
{
    HOME_DATA *thome;
    FILE *fpout;
    char filename[256];

    sprintf( filename, "%s%s", HOMEDIR, HOME_LIST );
    fpout = fopen( filename, "w" );
    if ( !fpout )
    {
         bug( "FATAL: cannot open home.lst for writing!\n\r", 0 );
         return;
    }
    for ( thome = first_home; thome; thome = thome->next )
    fprintf( fpout, "%s\n", thome->filename );
    fprintf( fpout, "$\n" );
    fclose( fpout );
}

long int get_home_value( HOME_DATA *home )
{
     long int price;
       
	 if ( !home->price )
	 {
		 if (home->class == APARTMENT_HOME)
			price = 5000;
		 else if (home->class == MIDSIZE_HOME)
     		price = 50000; 
		 else if (home->class == GIANT_HOME) 
			price = 500000;
		 else 
			price = 2000;
        
		 if ( (home->lastroom - home->firstroom) < 0 )
		 {
			 price += ((home->lastroom - home->firstroom) * 2 );
		 }

		 price *= 10;
	 }
	 else
		 price = home->price;
     
     return price;
}

bool is_hotel( CHAR_DATA *ch , HOME_DATA *home )
{
   if ( !str_cmp("Public",home->owner) )
          return TRUE;
             
   return FALSE; 
}

bool check_member( CHAR_DATA *ch , HOME_DATA *home )
{

	if ( IS_NPC(ch) && home->type == MOB_HOME )
		return TRUE;
	if ( !str_cmp("Unowned", home->owner ) )
		return TRUE;
	if ( IS_NPC(ch) && IS_SET( ch->act, ACT_PET) 
		&& ch->master 
		&&  ( !str_cmp(ch->master->name,home->owner) || !str_cmp(ch->master->name,home->pilot) 
		|| !str_cmp(ch->master->name,home->copilot) || !str_cmp("Public",home->owner) ) ) 
		return TRUE;

   if ( !str_cmp(ch->name,home->owner) || !str_cmp(ch->name,home->pilot) 
   || !str_cmp(ch->name,home->copilot) || !str_cmp("Public",home->owner) )
      return TRUE;
   
   return FALSE;
}

bool extract_home( HOME_DATA *home )
{   
    ROOM_INDEX_DATA *room;
    
    if ( ( room = home->in_room ) != NULL )
    {               
        UNLINK( home, room->first_home, room->last_home, next_in_room, prev_in_room );
        home->in_room = NULL;
    }
    return TRUE;
}

bool home_to_room(HOME_DATA *home , int vnum )
{
    ROOM_INDEX_DATA *hometo;
    
    if ( (hometo=get_room_index(vnum)) == NULL )
            return FALSE;
    LINK( home, hometo->first_home, hometo->last_home, next_in_room, prev_in_room );
    home->in_room = hometo; 
    return TRUE;
}

void echo_to_home( int color , HOME_DATA *home , char *argument )
{
     int room;
     for ( room = home->firstroom ; room <= home->lastroom ;room++ )
     {
         echo_to_room( color , get_room_index(room) , argument );
     }  
     
}

void resethome( HOME_DATA *home )
{
	 if (home->origname)
		home->name = home->origname;
     
     if ( str_cmp("Public",home->owner) && home->type != MOB_HOME )
     {
        STRFREE( home->owner );
        home->owner = STRALLOC( "Unowned" );
        STRFREE( home->pilot );
        home->pilot = STRALLOC( "" );
        STRFREE( home->copilot );
        home->copilot = STRALLOC( "" );
     }
     
     save_home2(home);               
}

void do_resethome( CHAR_DATA *ch, char *argument )
{    
     HOME_DATA *home;
     
     home = get_home( argument );
     if (home == NULL)
     {
        send_to_char("&RNo such home!",ch);
        return;
     } 
     
     resethome( home );         
}

/*
 * Write an object and its contents.
 */
void fwrite_obj_home( CHAR_DATA *ch, OBJ_DATA *obj, FILE *fp, int iNest,
		 sh_int os_type )
{
    EXTRA_DESCR_DATA *ed;
    AFFECT_DATA *paf;
    sh_int wear, wear_loc, x;

    if ( iNest >= MAX_NEST )
    {
	bug( "fwrite_obj: iNest hit MAX_NEST %d", iNest );
	return;
    }

    /*
     * Slick recursion to write lists backwards,
     *   so loading them will load in forwards order.
     */
    if ( obj->prev_content )
	fwrite_obj( ch, obj->prev_content, fp, iNest, OS_CORPSE );

    /*
     * Castrate storage characters.
     */
/*    if ( obj->item_type == ITEM_KEY && !IS_OBJ_STAT(obj, ITEM_CLANOBJECT ))
	return;*/

    /*
     * Catch deleted objects					-Thoric
     */
    if ( obj_extracted(obj) )
	return;

    /*
     * Do NOT save prototype items!				-Thoric
     */
    if ( IS_OBJ_STAT( obj, ITEM_PROTOTYPE ) )
	return;

    /* Corpse saving. -- Altrag */
    fprintf( fp, (os_type == OS_CORPSE ? "#CORPSE\n" : "#OBJECT\n") );

    if ( iNest )
	fprintf( fp, "Nest         %d\n",	iNest		     );
    if ( obj->count > 1 )
	fprintf( fp, "Count        %d\n",	obj->count	     );
    if ( QUICKMATCH( obj->name, obj->pIndexData->name ) == 0 )
	fprintf( fp, "Name         %s~\n",	obj->name	     );
    if ( QUICKMATCH( obj->short_descr, obj->pIndexData->short_descr ) == 0 )
	fprintf( fp, "ShortDescr   %s~\n",	obj->short_descr     );
    if ( QUICKMATCH( obj->description, obj->pIndexData->description ) == 0 )
	fprintf( fp, "Description  %s~\n",	obj->description     );
    if ( QUICKMATCH( obj->action_desc, obj->pIndexData->action_desc ) == 0 )
	fprintf( fp, "ActionDesc   %s~\n",	obj->action_desc     );
    fprintf( fp, "Vnum         %d\n",	obj->pIndexData->vnum	     );
    if ( os_type == OS_CORPSE && obj->in_room )
      fprintf( fp, "Room         %d\n",   obj->in_room->vnum         );
    if ( obj->extra_flags != obj->pIndexData->extra_flags )
	fprintf( fp, "ExtraFlags   %d\n",	obj->extra_flags     );
    if ( obj->wear_flags != obj->pIndexData->wear_flags )
	fprintf( fp, "WearFlags    %d\n",	obj->wear_flags	     );
    wear_loc = -1;
    for ( wear = 0; wear < MAX_WEAR; wear++ )
	for ( x = 0; x < MAX_LAYERS; x++ )
	   if ( obj == save_equipment[wear][x] )
	   {
		wear_loc = wear;
		break;
	   }
	   else
	   if ( !save_equipment[wear][x] )
		break;
    if ( wear_loc != -1 )
	fprintf( fp, "WearLoc      %d\n",	wear_loc	     );
    if ( obj->item_type != obj->pIndexData->item_type )
	fprintf( fp, "ItemType     %d\n",	obj->item_type	     );
    if ( obj->weight != obj->pIndexData->weight )
      fprintf( fp, "Weight       %d\n",	obj->weight		     );
    if ( obj->level )
      fprintf( fp, "Level        %d\n",	obj->level		     );
    if ( obj->timer )
      fprintf( fp, "Timer        %d\n",	obj->timer		     );
    if ( obj->cost != obj->pIndexData->cost )
      fprintf( fp, "Cost         %d\n",	obj->cost		     );
    if ( obj->value[0] || obj->value[1] || obj->value[2]
    ||   obj->value[3] || obj->value[4] || obj->value[5] )
      fprintf( fp, "Values       %d %d %d %d %d %d\n",
	obj->value[0], obj->value[1], obj->value[2],
	obj->value[3], obj->value[4], obj->value[5]     );

    switch ( obj->item_type )
    {
    case ITEM_PILL: /* was down there with staff and wand, wrongly - Scryn */
    case ITEM_POTION:
	if ( IS_VALID_SN(obj->value[1]) )
	    fprintf( fp, "Spell 1      '%s'\n",
		skill_table[obj->value[1]]->name );

	if ( IS_VALID_SN(obj->value[2]) )
	    fprintf( fp, "Spell 2      '%s'\n",
		skill_table[obj->value[2]]->name );

	if ( IS_VALID_SN(obj->value[3]) )
	    fprintf( fp, "Spell 3      '%s'\n",
		skill_table[obj->value[3]]->name );

	break;

    case ITEM_DEVICE:
	if ( IS_VALID_SN(obj->value[3]) )
	    fprintf( fp, "Spell 3      '%s'\n",
		skill_table[obj->value[3]]->name );

	break;
    case ITEM_SALVE:
	if ( IS_VALID_SN(obj->value[4]) )
	    fprintf( fp, "Spell 4      '%s'\n",
		skill_table[obj->value[4]]->name );

	if ( IS_VALID_SN(obj->value[5]) )
	    fprintf( fp, "Spell 5      '%s'\n",
		skill_table[obj->value[5]]->name );
	break;
    }

    for ( paf = obj->first_affect; paf; paf = paf->next )
    {
	/*
	 * Save extra object affects				-Thoric
	 */
	if ( paf->type < 0 || paf->type >= top_sn )
	{
	  fprintf( fp, "Affect       %d %d %d %d %d\n",
	    paf->type,
	    paf->duration,
	     ((paf->location == APPLY_WEAPONSPELL
	    || paf->location == APPLY_WEARSPELL
	    || paf->location == APPLY_REMOVESPELL
	    || paf->location == APPLY_STRIPSN)
	    && IS_VALID_SN(paf->modifier))
	    ? skill_table[paf->modifier]->slot : paf->modifier,
	    paf->location,
	    paf->bitvector
	    );
	}
	else
	  fprintf( fp, "AffectData   '%s' %d %d %d %d\n",
	    skill_table[paf->type]->name,
	    paf->duration,
	     ((paf->location == APPLY_WEAPONSPELL
	    || paf->location == APPLY_WEARSPELL
	    || paf->location == APPLY_REMOVESPELL
	    || paf->location == APPLY_STRIPSN)
	    && IS_VALID_SN(paf->modifier))
	    ? skill_table[paf->modifier]->slot : paf->modifier,
	    paf->location,
	    paf->bitvector
	    );
    }

    for ( ed = obj->first_extradesc; ed; ed = ed->next )
	fprintf( fp, "ExtraDescr   %s~ %s~\n",
	    ed->keyword, ed->description );

    fprintf( fp, "End\n\n" );

    if ( obj->first_content )
	fwrite_obj_home( ch, obj->last_content, fp, iNest + 1, OS_CORPSE );

    return;
}



/***************************************************************************
**      MORTAL COMMANDS TODO WITH THE NEW HOMES CODE                      **
**      This involves things like buyhome and sell home                   **
**                                                                        **
**                                                                        **
**                                                                        **
**                                                                        **
****************************************************************************/

void do_councilsellhome(CHAR_DATA *ch, char *argument )
{
	long         price;
	HOME_DATA   *home;
	ROOM_INDEX_DATA *room;
	
	if ( IS_NPC(ch) || !ch->pcdata )
	{
		send_to_char( "&ROnly players can do that!\n\r" ,ch );
		return;
	}
	
	{
		home = home_from_entrance( ch->in_room->vnum);
		if ( !home )
		{    
			act( AT_PLAIN, "I see no home here.", ch, NULL, argument, TO_CHAR );
			return;
		}
		room = ch->in_room;
		
		if ( str_cmp(home->owner,ch->name)
			&& str_cmp(home->pilot,ch->name)
			&& str_cmp(home->copilot,ch->name))    	        
		{
			send_to_char("&RHey, thats not your home!\n\r",ch);
			return;
		}
		
		price = get_home_value( home );
		
		ch->gold += ( price - price/10 );
		ch_printf(ch, "&GYou receive %ld credits from selling your home.\n\r" , price - price/10 );
		
		act( AT_PLAIN, "$n walks over to a terminal and makes a credit transaction.",ch, NULL, argument , TO_ROOM );
		
		STRFREE( home->owner );
		home->owner = STRALLOC( "Unowned" );
		save_home2( home );
	}
}


void do_councilbuyhome(CHAR_DATA *ch, char *argument )
{
	long         price;
	HOME_DATA   *home;
	ROOM_INDEX_DATA *room;
	AREA_DATA *pArea;
	
	if ( IS_NPC(ch) || !ch->pcdata )
	{
		send_to_char( "&ROnly players can do that!\n\r" ,ch );
		return;
	}

	{
		home = home_from_entrance( ch->in_room->vnum);
		if ( !home )
		{
			act( AT_PLAIN, "I see no home here, please goto the entrance.", ch, NULL, argument, TO_CHAR );
			return;
		}
		room = ch->in_room;
		
		for ( pArea = first_bsort; pArea; pArea = pArea->next_sort )
		{
			if ( room->area == pArea )
			{
				send_to_char( "&RThis area isn't installed yet!\n\r&w", ch);
				return;
			}
		}

		if ( str_cmp( home->owner , "Unowned" ) )
		{
			send_to_char( "&RThat home isn't for sale!\n\r" ,ch );
			return;
		}
		price = get_home_value( home );
		if ( ch->gold < price )
		{
			ch_printf(ch, "&RThis home costs %ld. You don't have enough credits!\n\r" , price );
			return;
		}
		if ( argument[0] == '\0' )
		{
			send_to_char( "Set the room name.  A very brief single line room description.\n\r", ch );
			send_to_char( "Usage: Buyhome <Room Name>\n\r", ch );
			return;
		}
		STRFREE( room->name );
		room->name = STRALLOC( argument );

		ch->gold -= price;
		ch_printf(ch, "&G%s pays %ld credits to purchace this fine home.\n\r", ch->name , price );
		
		act( AT_PLAIN, "$n walks over to a terminal and makes a credit transaction.",ch, NULL, argument , TO_ROOM );
		STRFREE( home->owner );
		home->owner = STRALLOC( ch->name );

		save_home2( home );
		fold_area( room->area, room->area->filename, FALSE );
	}
}

void do_roommate(CHAR_DATA *ch, char *argument )
{
    HOME_DATA *home;
    char arg1[MAX_INPUT_LENGTH];
	ROOM_INDEX_DATA	*location;
	AREA_DATA *pArea;

    argument = one_argument( argument, arg1 );
    if ( !ch->desc )
	{
		send_to_char( "You have no descriptor.\n\r", ch );
		return;
	}
	switch( ch->substate )
	{
	default:
		break;
	case SUB_ROOM_DESC:
		location = ch->dest_buf;
		if ( !location )
		{
			bug( "redit: sub_room_desc: NULL ch->dest_buf", 0 );
			location = ch->in_room;
		}
		STRFREE( location->description );
		location->description = copy_buffer( ch );
		stop_editing( ch );
		ch->substate = ch->tempnum;
		for ( pArea = first_bsort; pArea; pArea = pArea->next_sort )
		{
			if ( location->area == pArea )
			{
				send_to_char( "&RThis area isn't installed yet!\n\r&w", ch);
				return;
			}
		}
		fold_area( location->area, location->area->filename, FALSE );
		return;
	}

    location = ch->in_room;
	if ( arg1[0] == '\0' || !str_cmp( arg1, "?" ) )
	{
		send_to_char( "Syntax: roommate <field> value\n\r",		ch );
		send_to_char( "\n\r",ch );
		send_to_char( "Field being one of:\n\r",ch );
		send_to_char( "  add remove desc info\n\r",ch );
		return;
    }
	if ( ( home = home_from_entrance(ch->in_room->vnum) ) == NULL )
	{
		send_to_char("&G&WYou must be in the entrance of the home to do that!\n\r",ch);
		return;
	}
	
	if ( str_cmp( home->owner , ch->name ) )
	{
		{
			send_to_char( "&RThis isn't your house!" ,ch );
			return;
		}
	}
	if ( arg1[0] == '\0' )
	{
		send_to_char( "Syntax:\n\r\tRoommate [add/remove] [roommate name]\n\r",ch);
		return;
	}

	if ( !str_cmp("add", arg1) )
	{
		if (argument[0] == '\0')
		{
			send_to_char( "&RAdd whom?\n\r" ,ch );
			return;
		}

		if ( str_cmp( home->pilot , "" ) )
		{
			if ( str_cmp( home->copilot , "" ) )
			{
				send_to_char( "&RYou allready two roomates..\n\rTry Removing one first\n\r" ,ch );
				return;
			}
			STRFREE( home->copilot );
			home->copilot = STRALLOC( argument );
			send_to_char( "Second Roommate Added.\n\r", ch );
			save_home2( home );
			return;
		}
		STRFREE( home->pilot );
		home->pilot = STRALLOC( argument );
		send_to_char( "First Roommate Added.\n\r", ch );
		save_home2( home );
		return;
	}
	if ( !str_cmp("remove", arg1) )
	{
		if (argument[0] == '\0')
		{
			send_to_char( "&RRemove which roommate?\n\r" ,ch );
			return;
		}

		if ( !str_cmp( home->pilot , argument ) )
		{
			STRFREE( home->pilot );
			home->pilot = STRALLOC( "" );
			send_to_char( "First Roommate Removed.\n\r", ch );
			save_home2( home );
			return;
		}
		if ( !str_cmp( home->copilot , argument ) )
		{
			STRFREE( home->copilot );
			home->copilot = STRALLOC( "" );
			send_to_char( "Second Roommate Removed.\n\r", ch );
			save_home2( home );
			return;
		}
		
		send_to_char( "&RThat person isn't listed as a roommate.\n\r" ,ch );
		return;
	}
	if ( !str_cmp( arg1, "desc" ) )
    {
		if ( ch->substate == SUB_REPEATCMD )
			ch->tempnum = SUB_REPEATCMD;
		else
			ch->tempnum = SUB_NONE;
		ch->substate = SUB_ROOM_DESC;
		ch->dest_buf = location;
		start_editing( ch, location->description );
		return;
    }
	if ( !str_cmp( arg1, "info" ) )
	{
		ch_printf( ch, "&WOwner: &B%-15.15s   &WRoommate1: &B%-15.15s   &WRoommate2: &B%-15.15s\n\r",
			home->owner, home->pilot,  home->copilot );
		return;
	}
}

void fread_obj_home( HOME_DATA *home, FILE *fp, sh_int os_type )
{
    OBJ_DATA *obj;
    char *word;
    int iNest;
    bool fMatch;
    bool fNest;
    bool fVnum;
    ROOM_INDEX_DATA *room;

	room = NULL;
    CREATE( obj, OBJ_DATA, 1 );
    obj->count		= 1;
    obj->wear_loc	= -1;
    obj->weight		= 1;

    fNest		= TRUE;		/* Requiring a Nest 0 is a waste */
    fVnum		= TRUE;
    iNest		= 0;

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

		switch ( UPPER(word[0]) )
		{
		case '*':
			fMatch = TRUE;
			fread_to_eol( fp );
			break;
		
		case 'A':
			if ( !str_cmp( word, "Affect" ) || !str_cmp( word, "AffectData" ) )
			{
				AFFECT_DATA *paf;
				int pafmod;

				CREATE( paf, AFFECT_DATA, 1 );
				if ( !str_cmp( word, "Affect" ) )
					paf->type	= fread_number( fp );
				else
				{
					int sn;
					
					sn = skill_lookup( fread_word( fp ) );
					if ( sn < 0 )
						bug( "Fread_obj_home: unknown skill.", 0 );
					else
						paf->type = sn;
				}
				paf->duration	= fread_number( fp );
				pafmod		= fread_number( fp );
				paf->location	= fread_number( fp );
				paf->bitvector	= fread_number( fp );
				if ( paf->location == APPLY_WEAPONSPELL	|| paf->location == APPLY_WEARSPELL
					|| paf->location == APPLY_REMOVESPELL )
					paf->modifier		= slot_lookup( pafmod );
				else
					paf->modifier		= pafmod;
				LINK(paf, obj->first_affect, obj->last_affect, next, prev );
				fMatch				= TRUE;
				break;
			}
			KEY( "Actiondesc",	obj->action_desc,	fread_string( fp ) );
			break;

		case 'C':
			KEY( "Cost",	obj->cost,		fread_number( fp ) );
/*			KEY( "Count",	obj->count,		fread_number( fp ) ); Should Not Be Loaded */
			break;

		case 'D':
			KEY( "Description",	obj->description,	fread_string( fp ) );
			break;

		case 'E':
			KEY( "ExtraFlags",	obj->extra_flags,	fread_number( fp ) );

			if ( !str_cmp( word, "ExtraDescr" ) )
			{
				EXTRA_DESCR_DATA *ed;

				CREATE( ed, EXTRA_DESCR_DATA, 1 );
				ed->keyword		= fread_string( fp );
				ed->description		= fread_string( fp );
				LINK(ed, obj->first_extradesc, obj->last_extradesc, next, prev );
				fMatch 				= TRUE;
			}

			if ( !str_cmp( word, "End" ) )
			{
				if ( !fNest || !fVnum )
				{
					bug( "Fread_obj_home: incomplete object.", 0 );
					if ( obj->name )
						STRFREE( obj->name        );
					if ( obj->description )
						STRFREE( obj->description );
					if ( obj->short_descr )
						STRFREE( obj->short_descr );
					DISPOSE( obj );
					return;
				}
				else
				{
					sh_int wear_loc = obj->wear_loc;
					if ( !obj->name )
						obj->name = QUICKLINK( obj->pIndexData->name );
					if ( !obj->description )
						obj->description = QUICKLINK( obj->pIndexData->description );
					if ( !obj->short_descr )
						obj->short_descr = QUICKLINK( obj->pIndexData->short_descr );
					if ( !obj->action_desc )
						obj->action_desc = QUICKLINK( obj->pIndexData->action_desc );
					LINK(obj, first_object, last_object, next, prev );
					obj->pIndexData->count += obj->count;
					if ( !obj->serial )
					{
						cur_obj_serial = UMAX((cur_obj_serial + 1 ) & (BV30-1), 1);
						obj->serial = obj->pIndexData->serial = cur_obj_serial;
					}
					if ( fNest )
						rgObjNest[iNest] = obj;
					numobjsloaded += obj->count;
					++physicalobjects;
					if ( file_ver > 1 || obj->wear_loc < -1
						||   obj->wear_loc >= MAX_WEAR )
						obj->wear_loc = -1;
				    /* Corpse saving. -- Altrag */
					if ( os_type == OS_CORPSE )
					{
						if ( !room )
						{
							bug( "Fread_obj: Corpse without room", 0);
							room = get_room_index(ROOM_VNUM_LIMBO);
						}
						obj = obj_to_room( obj, room );
					}
					else if ( iNest == 0 || rgObjNest[iNest] == NULL )
					{
						int slot;
						bool reslot = FALSE;
						
						if ( file_ver > 1 && wear_loc > -1 && wear_loc < MAX_WEAR )
						{
							int x;

							for ( x = 0; x < MAX_LAYERS; x++ )
							{
								if ( !save_equipment[wear_loc][x] )
								{
									save_equipment[wear_loc][x] = obj;
									slot = x;
									reslot = TRUE;
									break;
								}
							}
							if ( x == MAX_LAYERS )
								bug( "Fread_obj_home: too many layers %d", wear_loc );
						}
						if ( reslot )
							save_equipment[wear_loc][slot] = obj;
					}
					else
					{
						if ( rgObjNest[iNest-1] )
						{
							separate_obj( rgObjNest[iNest-1] );
							obj = obj_to_obj( obj, rgObjNest[iNest-1] );
						}
						else
							bug( "Fread_obj_home: nest layer missing %d", iNest-1 );
					}
					if ( fNest )
						rgObjNest[iNest] = obj;
					return;
				}
			}
			break;
			
			case 'I':
				KEY( "ItemType",	obj->item_type,		fread_number( fp ) );
				break;
			case 'L':
				KEY( "Level",	obj->level,		fread_number( fp ) );
				break;

			case 'N':
				KEY( "Name",	obj->name,		fread_string( fp ) );
				if ( !str_cmp( word, "Nest" ) )
				{
					iNest = fread_number( fp );
					if ( iNest < 0 || iNest >= MAX_NEST )
					{
						bug( "Fread_obj_home: bad nest %d.", iNest );
						iNest = 0;
						fNest = FALSE;
					}
					fMatch = TRUE;
				}
				break;
				
			case 'R':
			    if ( !str_cmp( word, "Room" ) )
				{
					int room_vnum;
					room_vnum = fread_number(fp);
					room = get_room_index( room_vnum );
					obj = obj_to_room( obj, room );
					fMatch = TRUE;
					break;
				}


			case 'S':
				KEY( "ShortDescr",	obj->short_descr,	fread_string( fp ) );
				if ( !str_cmp( word, "Spell" ) )
				{
					int iValue;
					int sn;

					iValue = fread_number( fp );
					sn     = skill_lookup( fread_word( fp ) );

					if ( iValue < 0 || iValue > 5 )
						bug( "Fread_obj_home: bad iValue %d.", iValue );
					else if ( sn < 0 )
						bug( "Fread_obj_home: unknown skill.", 0 );
					else
						obj->value[iValue] = sn;
					fMatch = TRUE;
					break;
				}

				break;

			case 'T':
				KEY( "Timer",	obj->timer,		fread_number( fp ) );
				break;

			case 'V':
				
				if ( !str_cmp( word, "Values" ) )
				{
					int x1,x2,x3,x4,x5,x6;
					char *ln = fread_line( fp );

					x1=x2=x3=x4=x5=x6=0;
					sscanf( ln, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6 );
					/* clean up some garbage */
					if ( file_ver < 3 )
						x5=x6=0;

					obj->value[0]	= x1;
					obj->value[1]	= x2;
					obj->value[2]	= x3;
					obj->value[3]	= x4;
					obj->value[4]	= x5;
					obj->value[5]	= x6;
					fMatch		= TRUE;
					break;

				}
				
				if ( !str_cmp( word, "Vnum" ) )
				{
					int vnum;

					vnum = fread_number( fp );
					if ( ( obj->pIndexData = get_obj_index( vnum ) ) == NULL )
					{
						fVnum = FALSE;
						bug( "Fread_obj_home: bad vnum %d.", vnum ); 
					}
					else
					{
						fVnum = TRUE;
						obj->cost = obj->pIndexData->cost;
						obj->weight = obj->pIndexData->weight;
						obj->item_type = obj->pIndexData->item_type;
						obj->wear_flags = obj->pIndexData->wear_flags;
						obj->extra_flags = obj->pIndexData->extra_flags;
					}
					fMatch = TRUE;
					break;
				}
				break;

			case 'W':		KEY( "WearFlags",	obj->wear_flags,	fread_number( fp ) );
				KEY( "WearLoc",	obj->wear_loc,		fread_number( fp ) );

				KEY( "Weight",	obj->weight,		fread_number( fp ) );
				break;
		}

		if ( !fMatch )
		{
			EXTRA_DESCR_DATA *ed;
			AFFECT_DATA *paf;

			bug( "Fread_obj_home: no match.", 0 );

			bug( word, 0 );
			fread_to_eol( fp );
			if ( obj->name )
				STRFREE( obj->name        );
			if ( obj->description )
				STRFREE( obj->description );
			if ( obj->short_descr )
				STRFREE( obj->short_descr );
			while ( (ed=obj->first_extradesc) != NULL )
			{
				STRFREE( ed->keyword );
				STRFREE( ed->description );
				UNLINK( ed, obj->first_extradesc, obj->last_extradesc, next, prev );
				DISPOSE( ed );
			}
			while ( (paf=obj->first_affect) != NULL )
			{
				UNLINK( paf, obj->first_affect, obj->last_affect, next, prev );
				DISPOSE( paf );
			}
			DISPOSE( obj );
			return;
		}
    }
}

void do_freehomes(CHAR_DATA *ch, char *argument) 
{
	HOME_DATA *home;
	ROOM_INDEX_DATA *room; 
	int count = 0;
	home_classes category;

	if ( IS_NPC(ch) )
		return;

	send_to_char( "&Y\n\rThe following homes are for sale:\n\r", ch );

	for (category = APARTMENT_HOME; category <= GIANT_HOME; category++)
	{
		if (category == APARTMENT_HOME)
			send_to_char( "\n\r&BOne Or Two Room Apartments\n\r", ch );
		if (category == MIDSIZE_HOME)
			send_to_char( "\n\r&RMid Sized Houses\n\r", ch );
		if (category == GIANT_HOME)
			send_to_char( "\n\r&GGiant Sized Estates\n\r", ch );
		send_to_char( "&WHome                               Price                Location\n\r", ch );
		
		set_char_color( AT_BLUE, ch );

		for ( home = first_home; home; home = home->next )
		{   
			room = get_room_index(home->firstroom);
			if ( !room )
				continue;
			if (home->type == MOB_HOME)
				continue;
			if (home->class != category)
				continue;
			set_char_color( AT_BLUE, ch );

			if ( !str_cmp(home->owner,"Unowned") )
			{
				if ( room->area->planet )
				{
					ch_printf( ch, "%-34s %ld to buy \t%s.\n\r",
						home->name, get_home_value(home), room->area->planet->name);
				}
				else
				{
					ch_printf( ch, "%-34s %ld to buy \t%s.\n\r",
						home->name, get_home_value(home), "somewhere");
				}
				count++;
			}
			else
				continue;
		}
		if ( !count )
			send_to_char( "There are no homes currently for sale.\n\r", ch );
	}
	send_to_char( "\n\r", ch );
}