26 Apr, 2009, Malek Kervanes wrote in the 1st comment:
Votes: 0
Hi. I'm trying to design a DIKU-style room system.

I can get it to load the zone list, the zone info, and a room, but I can't get it to end properly.

Here's the code that's hemming it up:

for ( ;; )
{
char * section;

section = fread_word( ptrZone );

if ( !strcmp( section, "$0" ) ) break;

bug( section );

if ( section[0] != '#' )
{
bug( "LOAD_WORLD: Bad format detected." );
abort();
}

if ( !strcmp( section, "#0" ) ) break;
else if ( !strcmp( section, "#ZONE" ) ) load_zone( ptrZone );
else if ( !strcmp( section, "#ROOM" ) ) load_room( ptrZone );
else
{
bug( "LOAD_WORLD: Bad section name" );
abort();
}
}


and here's the zone file:
#ZONE
Test Zone~
Malek Kervanes~

#ROOM
1
Floating in the Emptiness~
You are floating in the emptiness of the void before creation. There
are bits of nothingness floating around you, awaiting the spark of
divine inspiration.
~
0
S

#0


And here's the log/buf files
BUGS
Apr 26 14:11:06: #ZONE
Apr 26 14:11:06: #ROOM
Apr 26 14:11:06: Fread_word: EOF encountered.

LOGS
Apr 26 14:11:06: Program starting.
Apr 26 14:11:06: Load_helps: getting all help files.
Apr 26 14:11:06: Ready to load the zone files
Apr 26 14:11:06: Zone list loaded.
Apr 26 14:11:06: Zone info for 'Test Zone' loaded.
Apr 26 14:11:06: Ready to load rooms.
Apr 26 14:11:06: Room 'Floating in the Emptiness' loaded.


I've spent 3 days looking at this code, and can't figure it out. I know that when someone points it out to me, it's gonna be a boneheaded mistake, but *shrugs* I wanna get this done, so I can move on to the next steps.
26 Apr, 2009, Sharmair wrote in the 2nd comment:
Votes: 0
First, I really have little idea what you mean by "DIKU style", though it does seem by the
little info that can be gleaned here that your room data format might be basically a stripped
down DIKU type room, the file format looks closer to MERC.

Though I can't really be sure without seeing your load_room function, as this code seems to
be either pulled out, or at least inspired by MERC (or a derivative), I would guess the room
function in using #0 as the end of room section and your file has no $0 terminator.
26 Apr, 2009, Malek Kervanes wrote in the 3rd comment:
Votes: 0
Okay, here's each function.

void load_world()
{
FILE * ptrList;
FILE * ptrZone;
char * zName;
char zList[20];

log_string( "Ready to load the zone files" );

sprintf( zList, "../zones/zone.lst" );


if ( ( ptrList = fopen( zList, "r" ) ) == NULL )
{
bug( "LOAD_WORLD: Error opening zone list." );
abort();
}

log_string( "Zone list loaded." );

for ( ; ; )
{
zName = fread_word( ptrList );

if ( zName[0] == '$' )
break;

if ( ( ptrZone = fopen( zName, "r" ) ) == NULL )
{
bug( "Cannot open zone %s.", zName );
abort();
}

for ( ;; )
{
char * section;

section = fread_word( ptrZone );

if ( !strcmp( section, "#0" ) ) break;

bug( section );

if ( section[0] != '#' )
{
bug( "LOAD_WORLD: Bad format detected." );
abort();
}

if ( !strcmp( section, "#0" ) ) break;
else if ( !strcmp( section, "#ZONE" ) ) load_zone( ptrZone );
else if ( !strcmp( section, "#ROOM" ) ) load_room( ptrZone );
else
{
bug( "LOAD_WORLD: Bad section name" );
abort();
}
}
fclose(ptrZone);
log_string( "Zone file closed" );
}

fclose(ptrList);
log_string( "List file closed." );
return;
}


void load_zone( FILE *fp )
{
DATA_ZONE *pZone;

if ( (pZone = malloc(sizeof(*pZone))) == NULL )
{
bug( "LOAD_ZONE: Cannot allocate memory." );
abort();
}

pZone->name = fread_string(fp);
pZone->builder = fread_string(fp);

if ( zone_first == NULL ) zone_first = pZone;
if ( zone_last != NULL ) zone_last->next = pZone;

zone_last = pZone;
pZone->next = NULL;

log_string( "Zone info for '%s' loaded.", pZone->name );
return;
}


void load_room( FILE *fp )
{
DATA_ROOM * pRoom;
int door;

log_string( "Ready to load rooms." );
if ( ( pRoom = malloc(sizeof(*pRoom))) == NULL )
{
bug( "LOAD_ROOM: Cannot allocate memory." );
abort();
}

pRoom->rmId = fread_number(fp);
pRoom->rmName = fread_string(fp);
pRoom->rmDesc = fread_string(fp);
pRoom->rmTerrain = fread_number(fp);

log_string( "Room '%s' loaded.", pRoom->rmName );

for ( door = 0; door <= 5; door++ ) pRoom->exit[door] = NULL;

for ( ;; )
{
DATA_EXIT * pExit;
char letter;
int dir;

if ( ( pExit = malloc(sizeof(*pExit))) == NULL )
{
bug( "LOAD_ROOM: Cannot allocate exit memory." );
abort();
}

letter = fread_letter(fp);
if ( letter == 'S' ) break;
else if ( letter == 'D' )
{
dir = fread_number(fp);
pExit->exDesc = fread_string(fp);
pExit->tRoom = getRoomId(fread_number(fp));
}
}

if ( room_first == NULL ) room_first = pRoom;
if ( room_last != NULL ) room_last->next = pRoom;

room_last = pRoom;
pRoom->next = NULL;

fclose(fp);
return;
}


DATA_ROOM *getRoomId( sh_int id )
{
DATA_ROOM *sRoom;

for ( sRoom = room_last; sRoom != NULL; sRoom = sRoom->next )
{
if ( sRoom->rmId == id )
return sRoom;
}

return NULL;
}
26 Apr, 2009, Sharmair wrote in the 4th comment:
Votes: 0
Ok, your problem with reaching the end of file (EOF) is probably from closing the file
after the one room is loaded (at the end of load_room). Note that you are also leaking
memory from allocating an exit structure before you even know you have an exit, you
should only allocate after you know you have a 'D'. The exit load is also unfinished,
but I assume you know that and are just not done.
26 Apr, 2009, Malek Kervanes wrote in the 5th comment:
Votes: 0
the EOF problem WAS the fact that the file was closed after one room. I also moved the exit allocation to after I know I have an exit.

Thanks, Sharmair!

Oh, and my exit struct only has 4 elements:

DATA_ROOM *tRoom
char * keyword
char *exDesc
sh_int exNum


I plan on adding more elements (key, etc) as they become implemented.
26 Apr, 2009, Malek Kervanes wrote in the 6th comment:
Votes: 0
new issue.

I'm trying to put a player in a room. I went for the simple route, and tried adding this line:

dChar->room = getRoomId( ROOM_START );


to the clear_mobile function. (using SocketMud 2.4 as a base.)

However, when I try to use a 'look' command, I receive a seg fault, and so I go into gdb and it shows that the dChar->room sublist is empty.

How do I do this?
27 Apr, 2009, Sharmair wrote in the 7th comment:
Votes: 0
Your getRoomId function probably should be using room_first instead of room_last. As it
is, you are only searching for the target room at the last room (the function will always
either return the last room or NULL). This would not be your problem here though if you
only have one room (with one room, room_first is the same as room_last).

It is a little unclear what you mean by a room sublist. If you mean a room contents list
like most MUDs have (maybe a list of characters and a list of objects, or it could be just
one list) the line you show would not add the character to that list, but only set the room
the character is in on the character, so you might just not be actually adding anything
to the room sublist.

Other possible things to look at would be: Is ROOM_START the id of an existing room
and does the look function handle the case if getRoomId returns NULL. For that matter,
does the base have a function to handle putting a character in a room? If so, you should
just use that, if not, you probably should write one to handle all the details of putting
a character in a room (the changes to the character, the changes to the room and any
side effects the placement of a character in a room would have). That way you can just
use a call to the function whenever you want to put a character someplace.
27 Apr, 2009, Malek Kervanes wrote in the 8th comment:
Votes: 0
I'll take a try at using room_first.

What I meant by a room sublist is like this:

dChar->room->next

basically the way the room is linked to the next room.

Yes, ROOM_START is a constant for 1, which is the ID of an existing room. The cmd_look function doesn't handle what to do if getRoomId returns NULL. Yeah, I know….bonehead mistake. I'm using SocketMUD, which has no room system to begin with, which is why I'm doing this. And, I'm thinking about creating a function to handle putting a character in a room. This morning I took a glance through the MERC code, which does just that…there's a function to put a character in a room.

*slams head against desk*
27 Apr, 2009, Malek Kervanes wrote in the 9th comment:
Votes: 0
Alrighty then!

I fiddled with the code some over my lunch break, and was able to get it to work.

I went to one list variable, and threw together a quick to_room() function, and got it to work. The character now saves properly, and cmd_look() works properly.

*bounces happily*

Thanks guys!
0.0/9