Declare those variables, xcoord, ycoord, and zcoord at the top of the do_redit function? I can't seem to get this. Whew. I tried following the flow from top to bottom of the entire build.c. Does this function I am trying to implement have to be in a certain area? I was trying to put it inside do_rset, copying the IF statements I see there that specify what to do when a certain rset command word is typed. I.E. when a builder types rset rsize.
Here is what I have now, and the error is that structure has no member named x, y, z, xcoord, ycoord, zcoord
void do_redit( CHAR_DATA *ch, char *argument )
{
char arg [MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char arg3[MAX_INPUT_LENGTH];
char buf [MAX_STRING_LENGTH];
ROOM_INDEX_DATA *location, *tmp;
EXTRA_DESCR_DATA *ed;
char dir;
EXIT_DATA *xit, *texit;
int value;
int edir, ekey, evnum;
char *origarg = argument;
set_char_color( AT_PLAIN, ch );
if ( !ch->desc )
{
send_to_char( "You have no descriptor.\n\r", ch );
return;
}
}
***************took out some code for posting**************
if ( !str_cmp( arg, "teledelay" ) )
{
if ( !argument || argument[0] == '\0' )
{
send_to_char( "Set the delay of the teleport. (0 = off).\n\r", ch );
send_to_char( "Usage: redit teledelay <value>\n\r", ch );
return;
}
location->tele_delay = atoi( argument );
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg, "televnum" ) )
{
if ( !argument || argument[0] == '\0' )
{
send_to_char( "Set the vnum of the room to teleport to.\n\r", ch );
send_to_char( "Usage: redit televnum <vnum>\n\r", ch );
return;
}
location->tele_vnum = atoi( argument );
send_to_char( "Done.\n\r", ch );
return;
}
/* added to for rsize */
if ( !str_cmp( arg, "rsize" ) )
{
char *xcoord;
char *ycoord;
char *zcoord;
argument = one_argument( argument, xcoord);
argument = one_argument( argument, ycoord);
argument = one_argument( argument, zcoord);
room->x = atoi(xcoord);
room->y = atoi(ycoord);
room->z = atoi(zcoord);
ch_printf(ch, "Room size set to:\n\r\tWidth: %d\n\r\tLength %d\n\r\tHeight %d\n\r", room->x, room->y, room->z);
if ( !argument || argument[0] == '\0' )
{
send_to_char( "Set the room size: width, length, height.\n\r", ch );
send_to_char( "Usage: redit rsize <value> <value> <value>\n\r", ch );
return;
}
return;
}
/* end of rsize addition */
Well, thats pretty good for not knowing what your doing, but here is how I would have it:
/* added to for rsize */
if ( !str_cmp( arg, "rsize" ) )
{
char *xcoord;
char *ycoord;
char *zcoord;
argument = one_argument( argument, xcoord);
argument = one_argument( argument, ycoord);
argument = one_argument( argument, zcoord);
//Putting this here to verify that what your entering is valid
if ( !xcoord || xcoord[0] == '\0' || !ycoord || ycoord[0] == '\0' || !zcoord ||zcoord[0] == '\0')
{
send_to_char( "Set the room size: width, length, height.\n\r", ch );
send_to_char( "Usage: redit rsize <value> <value> <value>\n\r", ch );
return;
}
//Didn't realize it was location and not room
location->x = atoi(xcoord);
location->y = atoi(ycoord);
location->z = atoi(zcoord);
ch_printf(ch, "Room size set to:\n\r\tWidth: %d\n\r\tLength %d\n\r\tHeight %d\n\r", location->x, location->y, location->z);
return;
}
/* end of rsize addition */
You wanna verify that what your entering is good info, othewise things will be screwed up. x/y/zcoord should be declared just fine, but as for location->x/y/z, did you add them to the structure in mud.h? If not, open mud.h, and search for "room_index_data". When you find the structure for it(not a pointer, but something that looks like this), add the following bold lines:
struct room_index_data
{
ROOM_INDEX_DATA * next;
ROOM_INDEX_DATA * next_sort;
CHAR_DATA * first_person;
CHAR_DATA * last_person;
OBJ_DATA * first_content;
OBJ_DATA * last_content;
EXTRA_DESCR_DATA * first_extradesc;
EXTRA_DESCR_DATA * last_extradesc;
AREA_DATA * area;
EXIT_DATA * first_exit;
EXIT_DATA * last_exit;
SHIP_DATA * first_ship;
SHIP_DATA * last_ship;
#ifdef OLC_SHUTTLE
SHUTTLE_DATA * first_shuttle;
SHUTTLE_DATA * last_shuttle;
#endif
char * name;
char * description;
int vnum;
EXT_BV room_flags;
MPROG_ACT_LIST * mpact; /* mudprogs */
int mpactnum; /* mudprogs */
MPROG_DATA * mudprogs; /* mudprogs */
sh_int mpscriptpos;
int progtypes; /* mudprogs */
int x; /* rooms size */
int y; /* rooms size */
int z; /* rooms size */
sh_int light;
sh_int sector_type;
sh_int tunnel; /* max people that will fit */
};
It won't be exactly the same, but similiar. So add those bold lines, and save the file. This makes it so that ROOM_INDEX_DATA has the appropriate branch of the room data tree, so it knows how and where to store the info you want. Make clean, and recompile. That should fix it, if not, let us know, and we'll help out as we can. And if you paste the full errors from your shell, that would be much easier as well.
Wow, thanks for the help. That worked great. Your explanation of the structure helps a lot (although I admit it is still sinking in). After getting the same sort of message for db.c I was able to think it out and fix what I had wrong there too.
But now I have a problem with tables.c
I tried to add the following in order to make the new command 'rsize'.
This is in tables.c in function skill_name
#ifdef USE_IMC
if ( skill == do_rsockets ) return "do_rsockets";
#endif
if ( skill == do_rsize ) return "do_rsize";
if ( skill == do_rstat ) return "do_rstat";
#ifdef USE_IMC
if ( skill == do_rtell ) return "do_rtell";
if ( skill == do_rwho ) return "do_rwho";
if ( skill == do_rwhois ) return "do_rwhois";
#endif
if ( skill == do_sacrifice ) return "do_sacrifice";
This is in tables.c in function skill_function
#endif
if ( !str_cmp( name, "do_rpstat" )) return do_rpstat;
#ifdef USE_IMC
if ( !str_cmp( name, "do_rquery" )) return do_rquery;
if ( !str_cmp( name, "do_rreply" )) return do_rreply;
#endif
if ( !str_cmp( name, "do_rreset" )) return do_rreset;
if ( !str_cmp( name, "do_rset" )) return do_rset;
if ( !str_cmp( name, "do_rsize" )) return do_rsize;
#ifdef USE_IMC
if ( !str_cmp( name, "do_rsockets" )) return do_rsockets;
#endif
if ( !str_cmp( name, "do_rstat" )) return do_rstat;
#ifdef USE_IMC
if ( !str_cmp( name, "do_rtell" )) return do_rtell;
if ( !str_cmp( name, "do_rwho" )) return do_rwho;
if ( !str_cmp( name, "do_rwhois" )) return do_rwhois;
This is in mud.h
DECLARE_DO_FUN( do_rgrub );
DECLARE_DO_FUN( do_rip );
DECLARE_DO_FUN( do_rlist );
DECLARE_DO_FUN( do_rolldie );
DECLARE_DO_FUN( do_rpfind );
DECLARE_DO_FUN( do_rreset );
DECLARE_DO_FUN( do_rset );
DECLARE_DO_FUN( do_rsize );
DECLARE_DO_FUN( do_rstat );
DECLARE_DO_FUN( do_sacrifice );
DECLARE_DO_FUN( do_save );
When I compile it will compile, but fails at the last moment(after compiling tables.c) with the errors:
table.o(.text + 0x79f1): in function 'skill_name': tables.c:1255: undefined reference to '_do_rsize'
and the same as above, except line 611 in 'skill_function'
What did I do wrong? Do I need to edit commands.dat, or is it something else? I was going to use cedit to add it online, but is there something else I did that you can see?
Thanks,
Gadush
Actually, since you didn't make it a command on its own, but one within another command(do_redit), you don't need any of those lines for the do_rsize command, since do_rsize doesn't exist. All you need to do to use your function is the following:[quote]redit rsize 10 20 30[quote]. That should do it. This is the advantage of putting it inside of another function, less work with tables.c and mud.h for these line.
So, just remove those three lines that you put in, and access this command through redit. Hope that helps.
Well, that worked, as far as compiling goes. =)
However, when I log on and type
redit rsize 10 10 10
or redit rsize with no args,
I get a Segmentation Fault (core dumped) and the mud crashes.
I went into area directory and found the stack dump:
Exception: STATUS_ACCESS_VIOLATION at eip=004C85B0
eax=00000031 ebx=77F5BC44 ecx=0022FA1C edx=00000031 esi=610ABF4F edi=00000000
ebp=0022C0C8 esp=0022C0B8 program=c:\smaug\smaug\dist\src\smaug.exe
cs=001B ds=0023 es=0023 fs=0038 gs=0000 ss=0023
Stack trace:
Frame Function Args
0022C0C8 004C85B0 (0022FA1C, 77F5BC44, 0A385438, 00AB0280)
0022E558 00464BF6 (0A385438, 0022FA16, 00000041, 0022F1B0)
0022F9C8 004C7B40 (0A385438, 0022FA16, 00574E50, 0022F8C4)
0022FE28 0047C4F1 (0057A210, 00000000, 00000039, 0022FE68)
0022FEF0 0047B5DA (00000002, 6160312C, 0A040330, 0022FF24)
0022FF40 61005018 (610CFEE0, FFFFFFFE, 000007E4, 610CFE04)
0022FF90 610052ED (00000000, 00000000, 00000000, 80576C70)
0022FFB0 00558641 (0047B1EF, 037F0009, 0022FFF0, 77E7EB69)
0022FFC0 0040103C (002285D0, 002285CC, 7FFDF000, BA1AFCF4)
0022FFF0 77E7EB69 (00401000, 00000000, 78746341, 00000020)
End of stack trace
Any suggestions?
Thanks for you patience and help, by the way.
Gadush
Oh, DUH, looking a little closer, I see that I did something really stupid. Here is what you should use:
/* added to for rsize */
if ( !str_cmp( arg, "rsize" ) )
{
char xcoord[MAX_STRING_LENGTH];
char ycoord[MAX_STRING_LENGTH];
char zcoord[MAX_STRING_LENGTH];
argument = one_argument( argument, xcoord);
argument = one_argument( argument, ycoord);
argument = one_argument( argument, zcoord);
//Putting this here to verify that what your entering is valid
if ( !xcoord || xcoord[0] == '\0' || !ycoord || ycoord[0] == '\0' || !zcoord ||zcoord[0] == '\0')
{
send_to_char( "Set the room size: width, length, height.\n\r", ch );
send_to_char( "Usage: redit rsize <value> <value> <value>\n\r", ch );
return;
}
//Didn't realize it was location and not room
location->x = atoi(xcoord);
location->y = atoi(ycoord);
location->z = atoi(zcoord);
ch_printf(ch, "Room size set to:\n\r\tWidth: %d\n\r\tLength %d\n\r\tHeight %d\n\r", location->x, location->y, location->z);
return;
}
Now, what I had before was a pointer to character string. The one_argument function need a normal string passed to is, which is what it is now. This is an array of characters that can be the length of MAX_STRING_LENGTH(defined in mud.h). Sorry about that, but that should fix it for you.
Thanks so very much! I was trying to figure out how to use gdb, from Nick's great post on the subject, but I was having some trouble. The rsize command works great. Now I am going to add it to rstat, as you suggested, and then see about appending the numbers to the room title, if possible, so it shows
A Small House 10 x 10 x 20
or whatever.
Thanks for all the help. This place is a great resource for people like me, who are just trying to learn.
Gadush
Well, I added this to rstat, and got that working(I hope).
But I seem to be having a problem with loading the room info with new sizes.
1. Start the mud and log on
2. load my new area(proto)
2. goto a room in new area and use command
redit rsize 10 10 10
and get the message the room sizes were set accordingly.
3. use rstat
and get correct room sizes displayed right after title, just like I want. So far so good.
4. do savearea
5. do save
6. shutdown mud now
7. start the mud again, and load the area
8. rstat the room. Room sizes are back to 0 x 0 x 0
So, I opened the .are of that area, and looked at the room. There are the new sizes, just as I specified. So, I guess that means it is saving right, but not loading right.
9. Reread the post on saving/loading new variables on a mob.
Went over the code changes, in db.c, to void load_rooms
/*
* Load a room section.
*/
void load_rooms( AREA_DATA *tarea, FILE *fp )
{
ROOM_INDEX_DATA *pRoomIndex;
char buf[MAX_STRING_LENGTH];
char *ln;
if ( !tarea )
{
bug( "Load_rooms: no #AREA seen yet." );
shutdown_mud( "No #AREA" );
exit( 1 );
}
for ( ; ; )
{
int vnum;
char letter;
int door;
int iHash;
bool tmpBootDb;
bool oldroom;
int x1, x2, x3, x4, x5, x6, x7, x8, x9;
letter = fread_letter( fp );
if ( letter != '#' )
{
bug( "Load_rooms: # not found." );
if ( fBootDb )
{
shutdown_mud( "# not found" );
exit( 1 );
}
else
return;
}
vnum = fread_number( fp );
if ( vnum == 0 )
break;
tmpBootDb = fBootDb;
fBootDb = FALSE;
if ( get_room_index( vnum ) != NULL )
{
if ( tmpBootDb )
{
bug( "Load_rooms: vnum %d duplicated.", vnum );
shutdown_mud( "duplicate vnum" );
exit( 1 );
}
else
{
pRoomIndex = get_room_index( vnum );
sprintf( buf, "Cleaning room: %d", vnum );
log_string_plus( buf, LOG_BUILD, sysdata.log_level );
clean_room( pRoomIndex );
oldroom = TRUE;
}
}
else
{
oldroom = FALSE;
CREATE( pRoomIndex, ROOM_INDEX_DATA, 1 );
pRoomIndex->first_person = NULL;
pRoomIndex->last_person = NULL;
pRoomIndex->first_content = NULL;
pRoomIndex->last_content = NULL;
}
fBootDb = tmpBootDb;
pRoomIndex->area = tarea;
pRoomIndex->vnum = vnum;
pRoomIndex->first_extradesc = NULL;
pRoomIndex->last_extradesc = NULL;
if ( fBootDb )
{
if ( !tarea->low_r_vnum )
tarea->low_r_vnum = vnum;
if ( vnum > tarea->hi_r_vnum )
tarea->hi_r_vnum = vnum;
}
pRoomIndex->name = fread_string( fp );
pRoomIndex->description = fread_string( fp );
/* Area number fread_number( fp ); */
ln = fread_line( fp );
x1=x2=x3=x4=x5=x6=x7=x8=x9=0;
sscanf( ln, "%d %d %d %d %d %d %d %d %d",
&x1, &x2, &x3, &x4, &x5, &x6, &x7, &x8, &x9);
pRoomIndex->room_flags = x2;
pRoomIndex->sector_type = x3;
pRoomIndex->tele_delay = x4;
pRoomIndex->tele_vnum = x5;
pRoomIndex->tunnel = x6;
pRoomIndex->x = x7;
pRoomIndex->y = x8;
pRoomIndex->z = x9;
if (pRoomIndex->sector_type < 0 || pRoomIndex->sector_type == SECT_MAX)
{
bug( "Fread_rooms: vnum %d has bad sector_type %d.", vnum ,
pRoomIndex->sector_type);
pRoomIndex->sector_type = 1;
}
pRoomIndex->light = 0;
pRoomIndex->first_exit = NULL;
pRoomIndex->last_exit = NULL;
Any help would be great. Sorry for the persistant questioning, but I think I am learning. I did manage to get rstat how I wanted it. And I would not have without these forums.
Thanks,
Gadush
Hmmm.
I rebooted the mud instead of shutting it down, and when it reloaded the correct sizes were in. Is this normal?
Gadush
So it is reading it properly, or no? If not, double check that the order its being written in is the proper way thats its getting read.
It seems to work great now. I went back through and commented out three variables xcoord, ycoord, and zcoord, that were not being used anymore with the new method you showed me. They were giving a warning message that they were unused, so I commented them out and recompiled clean. When I started the mud, the sizes were still 0 x 0 x 0, but then I rebooted the mud instead of just shutting it down, and the sizes loaded as I had specified.
I just wondered if it had to do with rebooting as opposed to shutdown mud now command?
Gadush
Actually what I commented out was the three pointers *xcoord, *ycoord, *zcoord, in build.c. I had declared them in do_redit.
That does not seem to me that it could have the effect I described though. But better to remove them, yes?
Gadush
Yes, remove them, they won't do anything. And there shouldn't be much difference between shutdown and reboot, except that reboot allows you to specify a time, I think. But it should definitely not affect how it boots the next time.
(Unless by reboot, you mean copyover.)