Here is my version of house code. I chose to put the objects and mobs into a table for
easier expansion. Make sure to create a new area for this, I suggest making it at least
1000 vnums because each persons home takes up 5 rooms. Simply set vnum start, to the first
vnum of the area, and vnum stop as the last vnum of the area. Do not build any rooms in
this area, the code will create the rooms. Then the players will be able to set their own
names and descriptions for their rooms. You shouldn't have any problems, but if you do please let me know.
This was coded for my mud but should work for a Rom 2.4b6 mud. You will need olc in
order for this code to work, and you must have redit delete. I don't require any credit for
this code, but please send comments or suggestions to (email removed)

/*
 * Version 2.0 Updates
 * I used a linked list to keep track of the objects, and mobs that you buy for your house,
 * and their value. Whenever you sell your house it will help to increase the amount that
 * your house is worth. In future releases all improvements to the house will be taken into 
 * account. However this is an excellent starting point, and is easily expandable.
 * Fixed several bugs throughout the code and generally made it nicer. Thanks Davion for finding 
 * some of the bugs I missed.
 */


Changes in merc.h
*****************


Put this somewhere in merc.h probably with the other structures

struct house_item
{
  char *name;
  int cost;
  int vnum;
  int type;
};     

struct house_data
{
    HOUSE_DATA *        next;
    char *              oname;
    char *              objname;
    char *              mobname;
    int                 ovalue;
    int                 mvalue;
    bool                valid;
};                                   


Below:
extern  const   struct  wiznet_type     wiznet_table    [];        

Put this:
extern  const   struct  house_item      house_table     []; 


Below: 
extern          CHAR_DATA         *     char_list;   

Put this:
extern          MAIL_DATA         *     mail_list;         


Below:
typedef struct  shop_data           SHOP_DATA;    

Put this: 
typedef struct  house_data          HOUSE_DATA;   


Below: 
#define IS_AWAKE(ch)            (ch->position > POS_SLEEPING)

Put this:
#define HAS_HOME(ch)        (!IS_NPC(ch) && ch->pcdata->h_vnum != 0 )
#define IS_HOME(ch)        ( ( ch->pcdata->h_vnum != 0 && (ch->in_room->vnum >= ch->pcdata->h_vnum) && (ch->in_room->vnum < ch->pcdata->h_vnum + 5 ) ) )     

/* add these variables to struct pc_data */

    int                 h_vnum;
    int                 hinvite;
    sh_int              horesets;
    sh_int              hmresets;
    bool                hchange;        


Below:
#define BAN_FILE        "ban.txt"   

Put:
#define HOUSE_FILE      "../data/house.txt"     


End changes to merc.h
*********************


Now open up special.c 
*********************

Add this at the end of the other spec_fun's:

DECLARE_SPEC_FUN(       spec_architect          );


add this to the end of the spec_fun table:

 {   "spec_architect",               spec_architect          },   



and at the end of the file add this:

bool spec_architect(CHAR_DATA * ch)
{
    if (ch->fighting != NULL)
        return spec_cast_mage(ch);
    return FALSE;
}


At the end of tables.h put this:
********************************

/* vnum types */
#define OBJ_VNUM  1
#define MOB_VNUM  2    


At the end of tables.c put this
*******************************

/* Now obviously here you are going to want to create your own mobs and objects and set the
vnum's in the table to match them. If it's an object make it obj_vnum, and if it's a mob
make it mob_vnum. */

const struct  house_item  house_table [] =
{
    /* Name */   /* Cost */  /* Vnum */    /* Type */
  {   "Couch",      200,        20706,      OBJ_VNUM    },
  {   "Healer",     500,        20701,      MOB_VNUM    },
  {   NULL,          0,         0,          0,          }
};


in file interp.h add this to the end:
DECLARE_DO_FUN( do_house        );
DECLARE_DO_FUN( do_objbuy       );
DECLARE_DO_FUN( do_mobbuy       );
DECLARE_DO_FUN( do_invite       );
DECLARE_DO_FUN( do_home         );
DECLARE_DO_FUN( do_hname        );
DECLARE_DO_FUN( do_hdesc        );
DECLARE_DO_FUN( do_join         );
DECLARE_DO_FUN( do_boot         );        


in file interp.c add this:
**************************
/* House commands */
    { "house",		do_house,	POS_RESTING,	 0,  1,  LOG_NORMAL, 1 },
    { "objbuy",		do_objbuy,	POS_RESTING,	 0,  1,  LOG_NORMAL, 1 },
    { "mobbuy",		do_mobbuy,	POS_RESTING,	 0,  1,  LOG_NORMAL, 1 },
    { "hdesc",		do_hdesc,	POS_RESTING,	 0,  1,  LOG_NORMAL, 1 },
    { "invite",		do_invite,	POS_RESTING,	 0,  1,  LOG_NORMAL, 1 },
    { "home",		do_home,	POS_RESTING,	 0,  1,  LOG_NORMAL, 1 },
    { "join",		do_join,	POS_RESTING,	 0,  1,  LOG_NORMAL, 1 },
    { "hname",		do_hname,	POS_RESTING,	 0,  1,  LOG_NORMAL, 1 },
    { "boot",           do_boot,        POS_RESTING,     0,  1,  LOG_NORMAL, 1 },


/* If you are a rot mud, or you have multiclassing you might want to remember to make it so
   that a players h_vnum carries over through a reroll. */

              
Changes for db.c
****************

in void clear_char 

below:
ch->max_move                = 100;      

add:
    ch->pcdata->h_vnum          = 0;
    ch->pcdata->horesets        = 0;
    ch->pcdata->hmresets        = 0;         


Changes for save.c
******************

in function fwrite_char

below clans: ( or something similar it can go anywhere in fwrite char basically )
    if (ch->clan)
    {
        fprintf( fp, "Clan %s~\n",clan_table[ch->clan].name);
        if (ch->clead)
            fprintf( fp, "Clead %s~\n",clan_table[ch->clan].name);
    }

add:

    if( ch->pcdata->h_vnum )
        fprintf(fp,"HVnum %d\n", ch->pcdata->h_vnum);
    if( ch->pcdata->horesets )
        fprintf(fp,"HOResets %d\n", ch->pcdata->horesets);
    if( ch->pcdata->hmresets )
        fprintf(fp,"HMResets %d\n", ch->pcdata->hmresets);
                                                            

Changes for recycle.c
*********************    


At the end add:

HOUSE_DATA *house_free;

HOUSE_DATA *new_house(void)
{
    static HOUSE_DATA house_zero;
    HOUSE_DATA *hOuse;

    if (house_free == NULL)
        hOuse = alloc_perm(sizeof(*hOuse));
    else
    {
        hOuse = house_free;
        house_free = house_free->next;
    }

    *hOuse = house_zero;
    VALIDATE(hOuse);
    return hOuse;
}    

void free_house(HOUSE_DATA *hOuse)
{
    if (!IS_VALID(hOuse))
        return;

    free_string( hOuse->oname );
    free_string( hOuse->objname );
    free_string( hOuse->mobname );
    INVALIDATE(hOuse);
    hOuse->next = house_free;
    house_free = hOuse;
}                    


ok now in fread char
********************


below:

 KEY( "Hit",         ch->hitroll,            fread_number( fp ) ); 

add:
            KEY( "HVnum",       ch->pcdata->h_vnum,     fread_number( fp ) );
            KEY( "HResets",     ch->pcdata->horesets,   fread_number( fp ) );
            KEY( "HOResets",    ch->pcdata->horesets,   fread_number( fp ) );
            KEY( "HMResets",    ch->pcdata->hmresets,   fread_number( fp ) ); 


Go to your home directory and then change to your mud directory, from there create the data directory and finally create the house.txt file putting a $ at the end of it save and exit. 
Cut and paste the code below, do a full clean and compile copyover or reboot the mud, and that should be it. If you have any problems or if I left something out please let me know.


/* Make a new file called house.c and cut and paste all the contents below */

/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 **************************************************************************/   

/***************************************************************************
*       ROM 2.4 is copyright 1993-1996 Russ Taylor                         *
*       ROM has been brought to you by the ROM consortium                  *
*           Russ Taylor (rtaylor@efn.org)                                  *
*           Gabrielle Taylor                                               *
*           Brian Moore (zump@rom.org)                                     *
*       By using this code, you have agreed to follow the terms of the     *
*       ROM license, in the file Rom24/doc/rom.license                     *
***************************************************************************/   

#if defined( macintosh )
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "tables.h"
#include "recycle.h"
#include "olc.h"
#include "interp.h"

bool change_exit  args( ( CHAR_DATA *ch, char *argument, int door ) );

void save_area (AREA_DATA *pArea );
void save_house args( ( ) );
void home_sell ( CHAR_DATA *ch, int cost );
CHAR_DATA *  find_architect     args( ( CHAR_DATA * ch ) );
HOUSE_DATA *house_list;

#define MAX_HORESET	5
#define MAX_HMRESETS	5

#define VNUM_START 20700
#define VNUM_STOP  22700

CHAR_DATA * find_architect ( CHAR_DATA *ch )
{
    CHAR_DATA * architect;

    for ( architect = ch->in_room->people; architect != NULL; architect = architect->next_in_room )
    {
        if (!IS_NPC(architect))
            continue;

        if (architect->spec_fun == spec_lookup( "spec_architect" ) )
            return architect;
    }  

    if ( architect == NULL || architect->spec_fun != spec_lookup( "spec_architect" ))
    {
        send_to_char("You can't do that here, find an Architect.\n\r", ch);
        return NULL;
    }

    if ( architect->fighting != NULL )
    {
        send_to_char("Wait until the fighting stops.\n\r",ch );
        return NULL;
    }

    return NULL;
}        

void do_objbuy(CHAR_DATA *ch, char *argument)
{
    char arg[MSL];
    char arg1[MSL];
    char buf[MSL];
    OBJ_DATA *obj;
    HOUSE_DATA *hOuse;
    int i;
 
    argument = one_argument( argument, arg );
    argument = one_argument( argument, arg1 );

    if ( !HAS_HOME( ch ) )
    {
        send_to_char("If you only had a home...\n\r",ch);
        return;
    }

    if ( !IS_HOME( ch ) )
    {
	send_to_char("You gotta be in your house.\n\r",ch);
	return;
    }

    if (arg[0] == '\0')
    {
	send_to_char("Syntax: objbuy <list>\n\rSyntax: objbuy buy <name>",ch);
	return;
    }

    if (!str_cmp(arg,"list"))
    {
	send_to_char("The following objects are available for purchase:\n\r",ch);
        send_to_char("{cName:             Cost:{x\n\r", ch );
        send_to_char("{Y========================{x\n\r", ch );
        for ( i = 0; house_table[i].name != NULL; i++ )
        {
             if ( house_table[i].type != OBJ_VNUM )
                 continue;
             printf_to_char( ch, "%-10s        %-5d\n\r", house_table[i].name, house_table[i].cost );
        }

        return;
    }

    if (!str_cmp(arg, "buy"))
    {
        if (arg1[0] == '\0')
        {
            send_to_char( "To buy an item type objbuy buy <item>.\n\r",ch );
            return;
        }
         
        for (i = 0; house_table[i].name != NULL; i++)           
        {
             if (is_name(arg1, house_table[i].name) && house_table[i].type == OBJ_VNUM)         
             {
                 if (ch->gold >= house_table[i].cost) 
                 {
                     if ( (obj = create_object(get_obj_index(house_table[i].vnum), ch->level ) )  == NULL ) 
                     {
                         send_to_char( "That object could not be found contact an imm.\n\r", ch );
                         return;
                     }

                     if( ch->pcdata->horesets > MAX_HORESET )
                     {
  	                send_to_char("Sorry you can only have 5 resetting objects.\n\r",ch);
	                return;
                     }

                     ch->pcdata->horesets++;
                     ch->gold -= house_table[i].cost;  
                     sprintf(buf,"%d", house_table[i].vnum);
                     redit_oreset(ch,buf);
                     sprintf(buf," ");
                     save_area(ch->in_room->area);
          
                     obj = create_object( get_obj_index( house_table[i].vnum ), ch->level );
          
                     for ( hOuse = house_list; hOuse != NULL; hOuse = hOuse->next )
                     {                                                     
                          if ( !str_cmp( obj->name, hOuse->objname ) ) 
                              break;

                          hOuse = new_house();
                          free_string( hOuse->oname );
                          hOuse->oname = str_dup( ch->name );
                          free_string( hOuse->objname );
                          hOuse->objname = str_dup( obj->name );
                          hOuse->ovalue = house_table[i].cost;
                          hOuse->next = house_list;
                          house_list = hOuse;
                          save_house();
                     }

          	     return;
                 }

                 else
                 {
                    printf_to_char( ch, "Sorry %s but you need %d gold for that.\n\r", ch->name, house_table[i].cost );
                    return;
                 }
             }
        }
    }

    send_to_char( "To buy an item type objbuy buy <item>.\n\r",ch );
    return;
}

void do_mobbuy(CHAR_DATA *ch, char *argument)
{
    char arg[MSL];
    char arg1[MSL];
    CHAR_DATA *mob;
    char buf[MSL];  
    HOUSE_DATA *hOuse; 
    int i;
 
    argument = one_argument( argument, arg );
    argument = one_argument( argument, arg1 );

    if ( !HAS_HOME( ch ) )
    {
        send_to_char("If you only had a home...\n\r",ch);
        return;
    }

    if ( !IS_HOME( ch ) )
    {
	send_to_char("You gotta be in your house.\n\r",ch);
	return;
    }

    if (arg[0] == '\0')
    {
        send_to_char("Syntax: mobbuy <list>\n\rSyntax: mobbuy buy <name>",ch); 
	return;
    }

    if (!str_cmp(arg,"list"))
    {
	send_to_char("The following mobiles are available for purchase:\n\r",ch);
        send_to_char("{cName:             Cost:{x\n\r", ch );
        send_to_char("{Y========================{x\n\r", ch );
        for ( i = 0; house_table[i].name != NULL; i++ )
        {
             if ( house_table[i].type != MOB_VNUM )
                 continue;
             printf_to_char( ch, "%-10s        %-5d\n\r", house_table[i].name, house_table[i].cost );
        }

        return;

    }

    if (!str_cmp(arg, "buy"))
    {
        if (arg1[0] == '\0')
        {
            send_to_char( "To buy an item type mobbuy buy <item>.\n\r",ch );
            return;
        }           

        for (i = 0; house_table[i].name != NULL; i++)
        {        
             if (is_name(arg1, house_table[i].name) && house_table[i].type == MOB_VNUM)
             {
                 if (ch->gold >= house_table[i].cost)
                 {                  
                     mob = create_mobile(get_mob_index(house_table[i].vnum) );
                 
                     if ( mob == NULL ) 
                     {
                         send_to_char( "That mob could not be found contact an imm.\n\r", ch );
                         return;
                     }            

                     if( ch->pcdata->hmresets > MAX_HMRESETS )
                     {      
                       	send_to_char("Sorry you can only have 5 resetting mobiles.\n\r",ch);
	                return;
                     }

                     ch->pcdata->hmresets++;
                     ch->gold -= house_table[i].cost;
                     sprintf(buf,"%d", house_table[i].vnum);  
                     redit_mreset(ch,buf);
                     sprintf(buf," ");
                     save_area(ch->in_room->area);

                     mob = create_mobile( get_mob_index( house_table[i].vnum ) );
          
                     for ( hOuse = house_list; hOuse != NULL; hOuse = hOuse->next )
                     {                                                     
                          if ( !str_cmp( mob->name, hOuse->mobname ) ) 
                              break;

                          hOuse = new_house();
                          free_string( hOuse->oname );
                          hOuse->oname = str_dup( ch->name );
                          free_string( hOuse->mobname );
                          hOuse->mobname = str_dup( mob->name );
                          hOuse->mvalue = house_table[i].cost;
                          hOuse->next = house_list;
                          house_list = hOuse;
                          save_house();
                     }

                     return;                            
                 }

                 else
                 {

                   printf_to_char( ch, "Sorry %s but you need %d gold for a %s.\n\r", ch->name, house_table[i].cost, house_table[i].name );                       
                   return;
                 }
             }
        }
    }
       
    send_to_char("Syntax: mobbuy <list>\n\rSyntax: mobbuy buy <name>",ch); 
    return; 
}

void do_house( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *architect;
    char arg[MIL];
    int osec;
    char buf[MSL];
    int i,i2;
    int cost = 100000;
    HOUSE_DATA *hOuse;

    architect = find_architect( ch );

    if (!architect)
        return;
 
    argument = one_argument( argument, arg );

    if (IS_NPC(ch))
    {
	send_to_char("Sorry, you'll have to just wander, mobile.\n\r",ch);
	return;
    }

    if ( arg[0] == '\0' && HAS_HOME( ch ) )
    {
        send_to_char( "You already bought a house. To sell it type house <sell>.\n\r", ch );
        send_to_char( "You can also value your house. Type house <value>\n\r", ch );
        return;
    }

    if ( !str_cmp( arg, "sell" ) && HAS_HOME( ch ) )
    {
        home_sell( ch, cost );
        return;
    }

    if ( !str_cmp( arg, "value" ) && HAS_HOME( ch ) )
    {
        int value,t;
       
        for ( hOuse = house_list; hOuse != NULL; hOuse = hOuse->next )
        {                                                     
             if ( !str_cmp( ch->name, hOuse->oname ) ) 
                 break;

                 value += ( hOuse->ovalue + hOuse->mvalue );
                 t++;
                 save_house();
    
        }

        printf_to_char( ch, "You have a total of %d mobs and objects in your house.\n\r", t );
        printf_to_char( ch, "Your house is valued at a total of %d gold.\n\r", ( cost / 2 ) + value );
        return;        
    }

    if ( HAS_HOME( ch ) )
    {
        send_to_char( "You already own a house. To sell it type house <sell>.\n\r", ch );
        return;
    }

    if (ch->gold < cost)
    {
        printf_to_char( ch, "I'm sorry but it cost %d gold to buy a house.\n\r", cost );
	return;
    }

    i = VNUM_START;

    while (get_room_index(i) != NULL)
    {
	i++;

	if (i > VNUM_STOP - 5)
	{
            send_to_char("Sorry all of the house vnums are used up! Tell an immortal.\n\r", ch );
	    return;
	}
    }

    send_to_char("Okay... Attempting creation of your home.\n\r\n\r",ch);
    ch->gold -= cost;
    osec = ch->pcdata->security;  
    ch->pcdata->security = 5;

    for (i2 = 4;i2 >= 0;i2--)
    {
    	sprintf(buf,"%d",i+i2);
 	
  	if( !redit_create( ch, buf ) )
	{
      	   send_to_char("Unable to create your house. Contact an Immortal.\n\r",ch);
	   return;
	}
		
        ch->desc->editor = ED_ROOM;
        char_from_room( ch );
        char_to_room( ch, ch->desc->pEdit );
        SET_BIT( ((ROOM_INDEX_DATA *)ch->desc->pEdit)->area->area_flags, AREA_CHANGED );
	sprintf(buf,"%s's Home",ch->name);
	redit_name(ch,buf);
    }

/*
 *  Link the rooms together
 *      3
 *      |
 *   2--1--4
 *      |
 *	5
 */

    sprintf(buf,"link %d",i+1);
    change_exit(ch,buf,DIR_WEST);
    sprintf(buf,"link %d",i+2);
    change_exit(ch,buf,DIR_NORTH);
    sprintf(buf,"link %d",i+3);
    change_exit(ch,buf,DIR_EAST);
    sprintf(buf,"link %d",i+4);
    change_exit(ch,buf,DIR_SOUTH);
    if ( osec > 1 )
    ch->pcdata->security = osec;
    send_to_char("\n\rHURRAY! Your house was made successfully.\n\r",ch);
    ch->pcdata->h_vnum = i;
    save_area(ch->in_room->area);
    edit_done(ch);
    return;
}

void do_hname( CHAR_DATA *ch, char *argument )
{
    int cost = 500;

    if ( !HAS_HOME( ch ) )
    {
        send_to_char("If you only had a home...\n\r",ch);
        return;
    }

    if ( !IS_HOME( ch ) )
    {
        send_to_char( "You've got to be in your house to do that.\n\r", ch );
	return;

    }

    if (ch->gold < cost)
    {
        printf_to_char( ch, "It cost %d to change the name of a room in your house.\n\r", cost );
	return;
    }

    if (argument[0] == '\0')
    {
	send_to_char("Change the name to what?\n\r",ch);
	return;
    }

    ch->gold -= cost;
    send_to_char("Ok.\n\r",ch);
    redit_name(ch,argument);
    save_area(ch->in_room->area);
    edit_done(ch);
    return;
}

void do_hdesc( CHAR_DATA *ch, char *argument )
{
    int cost = 500;

    if ( !HAS_HOME( ch ) )
    {
        send_to_char("If you only had a home...\n\r",ch);
        return;
    }

    if ( !IS_HOME( ch ) )
    {
	send_to_char("You gotta be in your house.\n\r",ch);
	return;
    }

    if (ch->gold < cost)
    {
        printf_to_char( ch, "It cost % gold to change your description.\n\r", cost );
	return;
    }

    ch->gold -= cost;
    send_to_char("Ok.\n\r",ch);
    ch->desc->pEdit     = ch->in_room;
    ch->desc->editor    = 2;
    ch->pcdata->hchange	= TRUE;
    redit_desc(ch,"");
    edit_done(ch);
    save_area(ch->in_room->area);
    return;
}

void do_home( CHAR_DATA *ch, char *argument )
{
    char buf[MSL];
    CHAR_DATA *victim;
    ROOM_INDEX_DATA *location;

    if (IS_NPC(ch) && IS_SET(ch->act,ACT_PET))
    {
        send_to_char("Only players can go home.\n\r",ch);
        return;
    }

    if ( !HAS_HOME( ch ) )
    {
	send_to_char("If you only had a home...\n\r",ch);
	return;
    }

    if(IS_NPC(ch))
	location = get_room_index(ch->master->pcdata->h_vnum);
    else
	location = get_room_index(ch->pcdata->h_vnum);

    if (location == NULL)
    {
        send_to_char( "Yikes write a note to immortal and let them know your house is Null.\n\r", ch );
	return;
    }

    act( "$n prays for transportation!", ch, 0, 0, TO_ROOM );

    if ( ch->in_room == location )
        return;
   
    if ( IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL)
    ||   IS_AFFECTED(ch, AFF_CURSE))
    {
        send_to_char( "ShadowStorm has forsaken you.\n\r", ch );
	return;
    }

    if ( ( victim = ch->fighting ) != NULL )
    {
	int lose,skill;

	skill = get_skill(ch,skill_lookup("recall"));

	if ( number_percent() < 80 * skill / 100 )
	{
	    check_improve(ch,skill_lookup("recall"),FALSE,6);
	    WAIT_STATE( ch, 4 );
	    sprintf( buf, "You failed!.\n\r");
	    send_to_char( buf, ch );
	    return;
	}

	lose = (ch->desc != NULL) ? 25 : 50;
	gain_exp( ch, 0 - lose );
	check_improve(ch,skill_lookup("recall"),TRUE,4);
	sprintf( buf, "You recall from combat!  You lose %d exps.\n\r", lose );
	send_to_char( buf, ch );
	stop_fighting( ch, TRUE );
    }

    act( "$n disappears.", ch, NULL, NULL, TO_ROOM );

    char_from_room( ch );
    char_to_room( ch, location );
    act( "$n appears in the room.", ch, NULL, NULL, TO_ROOM );
    do_look( ch, "auto" );

    if (ch->pet != NULL)
        do_home(ch->pet,"");
 
    if (ch->mount != NULL)
    {
        char_from_room( ch->mount );
        char_to_room( ch->mount, ch->in_room );
    }   

    return;
}

void do_invite(CHAR_DATA *ch,char *argument)
{
    CHAR_DATA *victim;
    char buf[MSL];

    if (argument[0] == '\0')
    {
	send_to_char("Invite whom to your home?\n\r",ch);
	return;
    }

    if ((victim = get_char_world(ch,argument)) == NULL)
    {
	send_to_char("Who is that?\n\r",ch);
	return;
    }

    if ( !IS_HOME( ch ) )
    {
        send_to_char("Can't invite someone to your house when you aren't in it.\n\r",ch);
	return;
    }

    if (ch == victim)
    {
	send_to_char("Lonely person, huh?\n\r",ch);
	return;
    }
 
    sprintf(buf,"%s has invited you to come to their house!\n\r",ch->name);
    send_to_char(buf,victim);

    send_to_char("You have invited them to come in.\n\r",ch);
    victim->pcdata->hinvite = ch->pcdata->h_vnum;
}

void do_join(CHAR_DATA *ch,char *argument)
{
    int ohvnum = 0;

    if (ch->pcdata->hinvite == 0)
    {
	send_to_char("You haven't been invited anywhere.\n\r",ch);
	return;
    }

    ohvnum = ch->pcdata->h_vnum;
    ch->pcdata->h_vnum = ch->pcdata->hinvite;
    do_home(ch,"");
    ch->pcdata->h_vnum = ohvnum;
    ch->pcdata->hinvite = 0;
}

void home_sell( CHAR_DATA *ch, int cost )
{
    char buf[MSL];
    int i,t;
    HOUSE_DATA *hOuse;
    int value;

    send_to_char( "Ok. Attempting to sell your home.\n\r\n\r", ch );
    
    for ( i = ch->pcdata->h_vnum; i < ch->pcdata->h_vnum + 5; i++ )
    {
         sprintf( buf, "%d", i );
         redit_delete( ch, buf );
    }            

    if ( ch->pcdata->security <= 5 )
    ch->pcdata->security = 0;
    ch->gold += ( cost / 2 );
    ch->pcdata->h_vnum = 0;
    send_to_char( "\n\rYou have successfully sold your house.\n\r", ch );

    for ( hOuse = house_list; hOuse != NULL; hOuse = hOuse->next )
    {                                                     
         if ( !str_cmp( ch->name, hOuse->oname ) ) 
             break;

         value += ( hOuse->ovalue + hOuse->mvalue );
         t++;
         save_house();
    }

    printf_to_char( ch, "You recieve %d gold for selling it.\n\r", ( cost / 2 ) + value );
    printf_to_char( ch, "You had a total of %d mobs and objects in your house.\n\r", t );
    return;
}

void do_boot( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *victim;

    if ( argument[0] == '\0' )
    {     
        send_to_char( "Who would you like to boot out of your house?\n\r", ch );
        return;
    }

    if ((victim = get_char_world(ch,argument)) == NULL)
    {
        send_to_char("Who is that?\n\r",ch);
        return;
    }                  
    
    if ( !IS_HOME( ch ) )
    {
        send_to_char("You can't boot someone if your not in your house!\n\r", ch );
        return;
    }            

    if ((victim->in_room->vnum < ch->pcdata->h_vnum) || (victim->in_room->vnum > ch->pcdata->h_vnum + 4))
    {
        send_to_char("You can't boot someone if their not in your house!\n\r",ch);
        return;
    }       

    printf_to_char( ch, "You get in %s's face and yell at %s to get out of your house!\n\r", victim->name, victim->sex == 0 ? "It" : victim->sex == 1 ? "Him" : "Her" );
    printf_to_char( victim, "%s begins yelling at you, and tells you to get out of %s house!\n\r", ch->name, ch->sex == 0 ? "It's" : ch->sex == 1 ? "His" : "Her" );  
    printf_to_char( victim, "You have been kicked out of %s's house!\n\r", ch->name );  
    do_recall( victim, "" );
    return;
}

void save_house()
{
  FILE *fp;
  HOUSE_DATA *hOuse;

  if ( ( fp = file_open( HOUSE_FILE, "w" ) ) == NULL )
  {
      logf2("The house file is gone!\n\r");
      return;
  }              

  for ( hOuse = house_list; hOuse != NULL; hOuse = hOuse->next )
  {
       fprintf(fp,"Oname %s~\n", hOuse->oname );
       fprintf(fp,"Objname %s~\n", hOuse->objname );
       fprintf(fp,"Mobname %s~\n", hOuse->mobname );
       fprintf(fp,"Ovalue %d\n", hOuse->ovalue );
       fprintf(fp,"Mvalue %d\n\n", hOuse->mvalue );
 }

 fprintf(fp, "$\n");
 logf2("House saved.");
 file_close(fp);
 return;
}


void load_house()
{
  FILE *fp;
  char *word;
  HOUSE_DATA *hlist;
  HOUSE_DATA *hOuse;

  if (file_exists(HOUSE_FILE))
  {
      fp = file_open( HOUSE_FILE, "r" );

      hlist = NULL;

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

          if(word[0] == '$' )
             return;

          if (!str_cmp(word, "Oname" ) )
          {
              hOuse = new_house();
              if (house_list == NULL)
              house_list = hOuse;
              else
              hlist->next = hOuse;
              hlist = hOuse;
              hOuse->oname = str_dup(fread_string(fp));
          }                                 
         
          if (!str_cmp(word, "Objname" ) )
              hOuse->objname = str_dup(fread_string(fp));
            
          if (!str_cmp(word, "Mobname" ) )
              hOuse->mobname = str_dup(fread_string(fp));

          if (!str_cmp(word, "Ovalue" ) )
              hOuse->ovalue = fread_number(fp);
          
          if (!str_cmp(word, "Mvalue" ) )
              hOuse->mvalue = fread_number(fp);
      }
  }

  return;

}