struct room_data * first_room; // Pointer to first room in list of rooms loaded into memory
struct room_data * last_room; // Pointer to last room in list of rooms loaded into memory
// Load quest data
void load_aquests( void )
{
struct room_data *room = NULL, *room_next = NULL;
for( room = first_room; room; room = room_next )
{
room_next = room->next;
// Do stuff
}
return;
}
struct room_data * first_room; // Pointer to first room in list of rooms loaded into memory
struct room_data * last_room; // Pointer to last room in list of rooms loaded into memory
// Load quest data
void load_aquests( void )
{
struct room_data *room = NULL, *room_next = NULL;
for( room = first_room; room; room = room_next )
{
if( !(room = get_room_index(x)) ) // Make sure room exists
continue;
// Do stuff
}
return;
}
void load_aquests( void )
{
AQUEST_INDEX_DATA *pAquestIndex;
int i = 0;
int x = 0;
for ( i = 0; i < MAX_AQUESTS; i++ )
{
long vnum;
int iHash;
pAquestIndex = alloc_perm( sizeof(*pAquestIndex) );
vnum = aquest_table[i].vnum;
fBootDb = FALSE;
if ( get_aquest_index( vnum ) != NULL )
{
bug( "Load_aquests: vnum %d duplicated.", vnum );
exit( 1 );
}
fBootDb = TRUE;
pAquestIndex->vnum = vnum;
for (x = 0; x < MAX_AQMOBS; x++);
pAquestIndex->kills[x] = aquest_table[i].mob_kills[x];
for (x = 0; x < MAX_AQOBJS; x++);
pAquestIndex->loots[x] = aquest_table[i].obj_loots[x];
pAquestIndex->status = ELIGIBLE;
iHash = vnum % MAX_KEY_HASH;
pAquestIndex->next = aquest_index_hash[iHash];
aquest_index_hash[iHash]= pAquestIndex;
top_aquest_index++;
top_vnum_aquest = top_vnum_aquest < vnum ? vnum : top_vnum_aquest; /*$
}
}
TestThere's quite a bit of code involved with both of my projects, instancing AND aquests. I'd be happy to post -everything- if need be, or even upload the entire mud if somebody's willing to look at it. Also, thanks for mentioning Valgrind. I'm in class right now but I'll look into it this afternoon when I get home.
void signal_handler(int sig) {
bool signal_shutdown = FALSE;
switch(sig) {
case SIGBUS:
log("Received SIGBUS. Shutting down…");
signal_shutdown = TRUE;
break;
case SIGTERM:
log("Received SIGTERM. Shutting down…");
signal_shutdown = TRUE;
break;
case SIGABRT:
log("Received SIGABRT. Shutting down with core dump…");
break;
case SIGSEGV:
log("Received SIGSEGV. Shutting down…");
signal_shutdown = TRUE;
break;
case SIGINT:
log("Received SIGINT. Shutting down…");
signal_shutdown = TRUE;
break;
}
if (signal_shutdown) {
Crash_save_all();
abort();
}
}
void fread_aquest( CHAR_DATA *ch, FILE *fp )
{
AQUEST_DATA *aq;
char *word;
bool fMatch;
bool fVnum;
bool first;
char *log = "";
fVnum = FALSE;
aq = NULL;
first = TRUE; /* used to counter fp offset */
word = feof( fp ) ? "End" : fread_word( fp );
if (!str_cmp(word,"Vnum" ))
{
log = "vnum";
long vnum;
first = FALSE; /* fp will be in right place */
vnum = fread_long( fp );
if ( get_obj_index( vnum ) == NULL )
{
bug( "Fread_aquest: bad vnum %ld.", vnum );
}
else
{
aq = create_aquest(get_aquest_index(vnum));
}
}
if (aq == NULL)
{
aq = new_aqdata();
}
fVnum = TRUE;
for ( ; ; )
{
if (first)
first = FALSE;
else
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;
switch ( UPPER(word[0]) )
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
if ( !str_cmp( word, "End" ) )
{
log = "End";
extern AQUEST_DATA *aqdata_free;
if ( fVnum && aq->pIndexData == NULL )
{
bug( "Fread_aquest: incomplete aquest.", 0 );
aq->next = aqdata_free;
aqdata_free = aq;
return;
}
else
{
aquest_to_char(aq, ch, aq->status);
return;
}
}
break;
case 'K':
if ( !str_cmp( word, "Kills" ) )
{
log = "Kills";
int x;
for( x = 0; x < MAX_AQMOBS; x++)
aq->kills[x] = fread_number(fp);
fMatch = TRUE;
break;
}
break;
case 'L':
if ( !str_cmp( word, "Loots" ) )
{
log = "Loots";
int x;
for( x = 0; x < MAX_AQOBJS; x++)
aq->loots[x] = fread_number(fp);
fMatch = TRUE;
break;
}
break;
case 'S':
KEY( "Status", aq->status, fread_number( fp ) );
log = "Status";
break;
case 'V':
if ( !str_cmp( word, "Vnum" ) )
{
log = "Vnum";
int vnum;
vnum = fread_long( fp );
if ( ( aq->pIndexData = get_aquest_index( vnum ) ) == NULL )
bug( "Fread_aquest: bad vnum %ld.", vnum );
else
fVnum = TRUE;
fMatch = TRUE;
break;
}
break;
}
if ( !fMatch )
{
char log_buf[MSL];
sprintf(log_buf, "Fread_aquest: no match W(%s) L(%s)", word, log );
bug( log_buf, 0 );
fread_to_eol( fp );
}
}
}
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
if ( !str_cmp( word, "End" ) )
{
log = "End";
extern AQUEST_DATA *aqdata_free;
if ( fVnum && aq->pIndexData == NULL )
{
bug( "Fread_aquest: incomplete aquest.", 0 );
aq->next = aqdata_free;
aqdata_free = aq;
return;
}
else
{
aquest_to_char(aq, ch, aq->status);
return;
}
}
break;
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
case 'E':
if ( !str_cmp( word, "End" ) )
{
log = "End";
extern AQUEST_DATA *aqdata_free;
if ( fVnum && aq->pIndexData == NULL )
{
bug( "Fread_aquest: incomplete aquest.", 0 );
aq->next = aqdata_free;
aqdata_free = aq;
return;
}
else
{
aquest_to_char(aq, ch, aq->status);
return;
}
}
break;
void load_aquests( void )
{
AQUEST_INDEX_DATA *pAquestIndex;
int i = 0;
int x = 0;
for ( i = 0; i < MAX_AQUESTS; i++ )
{
long vnum;
int iHash;
pAquestIndex = alloc_perm( sizeof(*pAquestIndex) );
vnum = aquest_table[i].vnum;
fBootDb = FALSE;
if ( get_aquest_index( vnum ) != NULL )
{
bug( "Load_aquests: vnum %d duplicated.", vnum );
//exit( 1 );
abort( );
}
fBootDb = TRUE;
pAquestIndex->vnum = vnum;
for (x = 0; x < MAX_AQMOBS; x++)
{
pAquestIndex->mvnums[x] = aquest_table[i].mobs[x];
pAquestIndex->kills[x] = aquest_table[i].mob_kills[x];
}
for (x = 0; x < MAX_AQOBJS; x++)
{
pAquestIndex->ovnums[x] = aquest_table[i].objs[x];
pAquestIndex->loots[x] = aquest_table[i].obj_loots[x];
}
pAquestIndex->status = ELIGIBLE;
iHash = vnum % MAX_KEY_HASH;
pAquestIndex->next = aquest_index_hash[iHash];
aquest_index_hash[iHash]= pAquestIndex;
top_aquest_index++;
top_vnum_aquest = top_vnum_aquest < vnum ? vnum : top_vnum_aquest; /* OLC */
}
}
/*
* Create an instance of an object.
*/
AQUEST_DATA *create_aquest( AQUEST_INDEX_DATA *pAquestIndex )
{
AQUEST_DATA *aq;
int x;
if ( pAquestIndex == NULL )
{
bug( "Create_aquest: NULL pAquestIndex.", 0 );
//exit( 1 );
abort( );
}
aq = new_aqdata();
for (x = 0; x < MAX_AQMOBS; x++)
{
aq->kills[x] = 0;
aq->mvnums[x] = pAquestIndex->mvnums[x];
}
for (x = 0; x < MAX_AQOBJS; x++)
{
aq->loots[x] = 0;
aq->ovnums[x] = pAquestIndex->ovnums[x];
}
aq->vnum = pAquestIndex->vnum;
aq->status = ELIGIBLE;
aq->pIndexData = pAquestIndex;
aq->next = aqdata_list;
aqdata_list = aq;
return aq;
}
void aquest_to_char( AQUEST_DATA *aquest, CHAR_DATA *ch, int status )
{
int x;
aquest->next = ch->aquest_data;
ch->aquest_data = aquest;
for (x = 0; x < MAX_AQMOBS; x++);
{
aquest->kills[x] = 0;
aquest->mvnums[x] = aquest->pIndexData->mvnums[x];
}
for (x = 0; x < MAX_AQOBJS; x++);
{
aquest->loots[x] = 0;
aquest->ovnums[x] = aquest->pIndexData->ovnums[x];
}
aquest->status = status;
return;
}
if (!str_cmp(arg1, "everything") )that outputs this:
{
AQUEST_DATA *alist;
for (alist = ch->aquest_data; alist != NULL; alist = alist->next)
{
chprintf(ch, "Vnum: %ld (%ld)\n\r", alist->vnum, alist->pIndexData->vnum);
chprintf(ch, "M1: %ld (%ld)\n\r", alist->mvnums[0], alist->pIndexData->mvnums[0]);
chprintf(ch, "M2: %ld (%ld)\n\r", alist->mvnums[1], alist->pIndexData->mvnums[1]);
chprintf(ch, "M3: %ld (%ld)\n\r", alist->mvnums[2], alist->pIndexData->mvnums[2]);
chprintf(ch, "O1: %ld (%ld)\n\r", alist->ovnums[0], alist->pIndexData->ovnums[0]);
chprintf(ch, "O2: %ld (%ld)\n\r", alist->ovnums[1], alist->pIndexData->ovnums[1]);
chprintf(ch, "O3: %ld (%ld)\n\r", alist->ovnums[2], alist->pIndexData->ovnums[2]);
chprintf(ch, "Status: %d (%d)\n\r", alist->status, alist->pIndexData->status);
}
return;
}
Quest Type: [Once]
Quest Title: [Begin your training…]
Prerequisite Quest(s): [20401]
Completion Mob: [20450]
Side available: [UM]
Class available: [All]
Level: [2]
Quest Description:
Seek out the captured slaves, punish 10 of them and then speak with mother.
She is pleased with those who obey her, do not let her down.
Quest Completion Description:
FOR THE HORDE!!!
Speak Quest Dialog:
I am delighted to see you have the stomach to punish those
who oppose us. Your journey has begun! pwn da n00bs!
Req# Type Amount Vnum – debug info – Quest_vnum Qreq_vnum
——- —— ——— ——— – —> – ——— ———
[0 ] [Speak ] [1 ] [20450 ] [20402 ] [20418 ]
[1 ] [Kill ] [10 ] [20416 ] [20402 ] [20417 ]
Item# Class Amount Vnum Short Description
——- ————– —— ——— —————–
[0 ] [Warlock ] [1 ] [40035 ] [the Matron Mothers sigil of Honor for Warlocks]
[1 ] [Necromancer ] [1 ] [40034 ] [the Matron Mothers sigil of Honor for Necromancers]
[2 ] [Illusionist ] [1 ] [40033 ] [the Matron Mothers sigil of Honor for Illusionists]
[3 ] [DeathKnight ] [1 ] [40032 ] [the Matron Mothers sigil of Honor for Death Knights]
[4 ] [Frost-Augur ] [1 ] [40031 ] [the Matron Mothers sigil of Honor for Frost Augurs ]
[5 ] [All ] [1 ] [1201 ] [A Restring Token]
[6 ] [Assassin ] [1 ] [40039 ] [the Matron Mothers sigil of Honor for Assassins]
[7 ] [All ] [5 ] [20417 ] [some butchered meat]
[8 ] [Barbarian ] [1 ] [40038 ] [the Matron Mothers sigil of Honor for Barbarians]
[9 ] [Warrior ] [1 ] [40037 ] [the Matron Mothers sigil of Honor for Warriors]
[10 ] [Witch ] [1 ] [40036 ] [the Matron Mothers sigil of Honor for Witches]
Crado K'dan, the ancient Undead Archmagi needs your assistance with ….
[1] (D) [Begin your training…]
Command: Choose a quest number, list, or done
(Difficulty: XXXXXX) [Begin your training…]
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
Seek out the captured slaves, punish 10 of them and then speak with mother.
She is pleased with those who obey her, do not let her down.
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
[Quest Requirements:]
Speak to The Matron Mother Reborn
Kill 10 of a human slave
Do you accept or decline?
I am delighted to see you have the stomach to punish those
who oppose us. Your journey has begun! pwn da n00bs!
FOR THE HORDE!!!
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
You recieve A Restring Token.
You recieve the Matron Mothers sigil of Honor for Assassins.
You recieve [5] some butchered meat.
You receive 115 silver coins.
[You are working on 8 quest at the moment.]
-+-+-+-+-+-+-+-+-+-+-+-+-+Quest Log+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
[1] (D) [Trouble in a half shell]
0 of 1 a giant turtle
[2] (D) [Herbs, Herbs, Herbs….]
0 of 1 a skeleton warrior
[3] (D) [Stones and Bones]
0 of 10 a tempered spirit
[4] (D) [Knight Only]
0 of 1 a giant turtle
[5] (D) [Fighter Only]
0 of 1 a giant turtle
[6] (D) [Priest Only]
0 of 1 a giant turtle
[7] (D) [Thief Only]
0 of 1 a giant turtle
[8] (D) [Wizard Only]
0 of 1 a giant turtle
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
Command: Choose a quest number, list, done
Secondly, for my "instancing" code I've gotten the mud to successfully copy rooms, exits, mobs, mobprogs, etc, and for SOME reason objects crash when they try to copy. For lack of a better description, I've just copied the "oedit_copy" code verbatim (which works fine, btw). I set log messages to see if I could track down what happened, and it's supposed to log "copying obj1->name to obj2->name". But it's crashing when it tries to access obj2->name (or any property of the object). Whenever I oedit the object, or use oedit_copy, it works fine. I even tried calling oedit_copy in my function instead of doing a property by property assignment, THAT crashed. But it works for mobs and rooms perfectly so I'm pulling my hair out trying to figure out wtf's going wrong.
The last thing I can think to mention is that when I get the mud to crash through gdb, the backtrace doesn't show me anything. I"d be happy to post code here, but there would be a LOT of it to have to go through. If anybody has run into some similar problems, I'd appreciate any help I could get. Thanks for your time.
-Josh