Need some help with a player housing snippet...

Posted by Toy on Wed 30 Jun 2004 02:39 AM — 8 posts, 26,078 views.

#0
bool set_house( CHAR_DATA *ch, int vnum, bool apartment)
{
   HOME_DATA *tmphome, *shome = NULL;
   char buf[MAX_STRING_LENGTH];
   ROOM_INDEX_DATA *location=NULL;
   EXIT_DATA *pexit=NULL;
   OBJ_INDEX_DATA *obj, *key = NULL;

   if (!ch || !ch->name || vnum <= 0)
	   return FALSE;

    CREATE(tmphome, HOME_DATA, 1);

	tmphome->name = STRALLOC(ch->name);
	tmphome->apartment = apartment;
	tmphome->vnum[0] = vnum;

	if (first_home)
	{
		bool found = FALSE;

		for ( shome = first_home; shome; shome = shome->next )
		{
			if ( strcmp(tmphome->name, shome->name) < 0 )
			{
				INSERT( tmphome, shome, first_home, next, prev );
				found = TRUE;
				break;
			}
		}

		if (!found)
			LINK( tmphome, first_home, last_home, next, prev );
	}
	else
	{
		LINK( tmphome, first_home, last_home, next, prev );
	}

	update_house_list();
	fwrite_house(tmphome);

	if ((location = get_room_index(vnum)) == NULL)
		return FALSE;

        if (apartment)
		sprintf( buf, "%s's Apartment", tmphome->name);
	else
		sprintf( buf, "%s's House", tmphome->name);

	STRFREE( location->name );
	location->name = STRALLOC( buf );
	STRFREE( location->description );
	if (apartment)
	    location->description = STRALLOC( "A room surrounds you, filled with the dirt and filth of previous tenants.\n\rA spray painted frame of the last tenant can be seen on the floor in a \n\rfar corner.\n\r");
	else
	    location->description = STRALLOC( "This is your desc. You can edit this with HOUSE DESC.\n\r");

	location->sector_type = 0;

#ifndef EXTENDED_ROOMS
        SET_BIT( location->room_flags, ROOM_NO_SUMMON );
        SET_BIT( location->room_flags, ROOM_NO_ASTRAL );
        SET_BIT( location->room_flags, ROOM_INDOORS );
        SET_BIT( location->room_flags, ROOM_SAFE );
#else
        xSET_BIT( location->room_flags, ROOM_NO_SUMMON );
        xSET_BIT( location->room_flags, ROOM_NO_ASTRAL );
        xSET_BIT( location->room_flags, ROOM_INDOORS );
        xSET_BIT( location->room_flags, ROOM_SAFE );
#endif

	for ( pexit = location->first_exit; pexit; pexit = pexit->next )
	{
		SET_BIT( pexit->exit_info, EX_ISDOOR );
		SET_BIT( pexit->exit_info, EX_CLOSED);
		SET_BIT( pexit->exit_info, EX_LOCKED);
		SET_BIT( pexit->exit_info, EX_NOPASSDOOR);
		SET_BIT( pexit->exit_info, EX_PICKPROOF);
		SET_BIT( pexit->exit_info, EX_BASHPROOF);
		SET_BIT( pexit->exit_info, EX_NOMOB);

		if (!apartment)
			pexit->key = location->vnum;

		if (pexit->rexit)
		{
			SET_BIT( pexit->rexit->exit_info, EX_ISDOOR );
		        SET_BIT( pexit->rexit->exit_info, EX_CLOSED);
		        SET_BIT( pexit->rexit->exit_info, EX_LOCKED);
			SET_BIT( pexit->rexit->exit_info, EX_NOPASSDOOR);
		        SET_BIT( pexit->rexit->exit_info, EX_PICKPROOF);
		        SET_BIT( pexit->rexit->exit_info, EX_BASHPROOF);
			SET_BIT( pexit->rexit->exit_info, EX_NOMOB);

		        if (!apartment)
				pexit->rexit->key = location->vnum;
		}

	}

	if (apartment)
		return TRUE;

	if ( (obj = get_obj_index(location->vnum)) != NULL)
	{
		delete_obj(obj);
		save_residence(location);
	}

	sprintf( buf, "%s's House Key", tmphome->name);
        key = make_object( location->vnum, 0, buf);
	key->value[0] = location->vnum;
	key->item_type = ITEM_TREASURE;
        key->level = 1;
        STRFREE( key->short_descr );
	key->short_descr = STRALLOC( buf );
	SET_BIT( key->wear_flags, ITEM_TAKE );
	SET_BIT( key->wear_flags, ITEM_HOLD );

	xREMOVE_BIT(key->extra_flags, ITEM_PROTOTYPE);

	save_residence(location);

	return TRUE;
}
#1
For the most part the code works fine. The problem I'm running into is on the making of the key. It creates the key, and gives it a vnum.

Name: Test's House Key
Vnum: 798 Type: treasure Count: 1 Gcount: 1
Serial#: 781 TopIdxSerial#: 781 TopSerial#: 781
Short description: Test's House Key
Long description : Some god dropped a newly created Test's House Key here.
Wear flags : take hold
Extra flags:
Magic flags: none
Number: 1/1 Weight: 1/1 Layers: 0 Wear_loc: -1
Cost: 0 Gold, 0 Silver, 0 Copper
Rent: 0 Timer: 0 Level: 1
In room: 0 In object: (none) Carried by: Test
Index Values : 798 0 0 0 0 0.
Object Values: 798 0 0 0 0 0.

The problem is the object doesn't save into the area file. After every reboot/hotboot, this occurs:

A puff of ethereal smoke dissipates around you!
Comm: Loading player data for: Test (1K)
Log: [*****] FILE: ../player/t/Test LINE: 80
Log: [*****] BUG: Fread_obj: incomplete object.
Log: Hotboot recovery complete.

Can someone point out my problem?
-Toy
USA #2
Does the area have sufficiently large ranges to contain the key?
#3
If you mean does it have enough object vnums for the key, yeah. the vnums run 300-799, around 200 of the vnums unused. The code makes a key depending on the room used as a house, and the room chosen was 798. But after the key is made, if I use olist, it doesn't show the key in the area file.

-Toy
Canada #4
Does this code call fold_area at any point afterwards? If not, then you will have an invoked object, and later there will be no index data to compare to. That may be the issue.
USA #5
The other possibility being that the object vnum range isn't sufficient to hold the key. Stock Smaug has 3 different ranges to consider, and the fact that it's not showing up in the area's olist leads me to beleive this is your problem. Extend the object vnum range, fold the area, and then see what you get.
#6
How strange. I tested out the theory about the object needing more space, so I made an empty area with 10,000 vnums worth of rooms and objects. So I set the house vnum 10000 for sale, purchased it and received the key. Aassigned the area, and sure enough the key was in the olist matching the proper house.

Oh yeah, this line in the code saves the area:

save_residence(location);

Why would it have to have so many empty vnums to save the key properly?

-Toy
USA #7
You need an object vnum for every room vnum you have. It has to be the same physical range, not just same size.