[Bug] Mob resets do not work properly when limits are specified
< Newer Topic
:: Older Topic >
AFKMud 2.02
Pages:<< prev 1 next >>
#1 Jan 12, 2008 5:26 pm
Black Hand
GroupAdministrators
Posts3,697
JoinedJan 1, 2002
Bug: Mob resets do not work properly when limits are specified
Danger: Low - The only real affect is that a reset will trigger more of a mob that someone actally wants.
Discovered in: AFKMud 2.02
Found by: Many people over time
Fixed by: Remcon
---
mobindex.cpp, mob_index::create_mobile
Locate:
Below that, add:
character.cpp
Near the top with other prototypes, locate:
Below that, add:
character.cpp, char_data::extract
Locate:
Change to:
hotboot.cpp
Near the top, locate:
Below that, add:
hotboot.cpp, save_mobile
Locate:
Below that, add:
hotboot.cpp, load_mobile
Locate:
Below that, add:
Locate:
Change to:
character.h, class char_data
Locate:
Below that, add:
roomindex.h, class reset_data
Locate:
Below that, add:
roomindex.cpp
Near the top, locate:
Below that, add:
roomindex.cpp, room_index::reset
Locate:
Change to:
Locate:
Change to:
Locate:
Change to:
Locate:
Below that, add:
Locate:
Change to:
Locate:
Change to:
Locate:
Change to:
reset.cpp
At the bottom of reset.cpp, add the following new function:
The basic problem here is that resets for mobs can specify a limit to how many of them should be loaded at any given time. This ( I think? ) worked just fine when resets were still based on the area as a whole. No more than X number of mobs would load. But when things were converted to room based resets, the counts went out the window. Each room could specify its own limit, which was meaningless in the big picture. Remcon's fix takes a different approach by tying each reset number to the mobs it creates and then keeping track of them to see if they should be reset again when the area reset is called.
Danger: Low - The only real affect is that a reset will trigger more of a mob that someone actally wants.
Discovered in: AFKMud 2.02
Found by: Many people over time
Fixed by: Remcon
---
mobindex.cpp, mob_index::create_mobile
Locate:
mob->home_vnum = -1; mob->sector = -1; mob->timer = 0;
Below that, add:
mob->resetvnum = -1; mob->resetnum = -1;
character.cpp
Near the top with other prototypes, locate:
void set_title( char_data *, char * );
Below that, add:
void update_room_reset( char_data *, bool );
character.cpp, char_data::extract
Locate:
if( mount ) { mount->unset_actflag( ACT_MOUNTED ); mount = NULL; position = POS_STANDING; }
Change to:
if( mount ) { update_room_reset( this, true ); mount->unset_actflag( ACT_MOUNTED ); mount = NULL; position = POS_STANDING; }
hotboot.cpp
Near the top, locate:
bool write_to_descriptor_old( int, char *, size_t );
Below that, add:
void update_room_reset( char_data *, bool );
hotboot.cpp, save_mobile
Locate:
fprintf( fp, "Level %d\n", mob->level ); fprintf( fp, "Gold %d\n", mob->gold );
Below that, add:
fprintf( fp, "Resetvnum %d\n", mob->resetvnum ); fprintf( fp, "Resetnum %d\n", mob->resetnum );
hotboot.cpp, load_mobile
Locate:
mob->tempnum = -9998; /* Yet another hackish fix! */ if( !mob->to_room( pRoomIndex ) ) log_printf( "char_to_room: %s:%s, line %d.", __FILE__, __FUNCTION__, __LINE__ );
Below that, add:
update_room_reset( mob, false );
Locate:
case 'R': KEY( "Room", inroom, fread_number( fp ) ); break;
Change to:
case 'R': KEY( "Room", inroom, fread_number( fp ) ); KEY( "Resetvnum", mob->resetvnum, fread_number( fp ) ); KEY( "Resetnum", mob->resetnum, fread_number( fp ) ); break;
character.h, class char_data
Locate:
int heading; /* The skyship's directional heading */
Below that, add:
int resetvnum; int resetnum;
roomindex.h, class reset_data
Locate:
short arg9; short arg10; short arg11;
Below that, add:
bool sreset;
roomindex.cpp
Near the top, locate:
reset_data *make_reset( char, int, int, int, short, short, short, short, short, short, short, short );
Below that, add:
void update_room_reset( char_data *, bool );
roomindex.cpp, room_index::reset
Locate:
char *filename = area->filename; int level = 0, num, lastnest;
Change to:
char *filename = area->filename; int level = 0, num, lastnest, onreset = 0;
Locate:
for( rst = resets.begin(); rst != resets.end(); ++rst ) { reset_data *pReset = (*rst); switch( pReset->command )
Change to:
for( rst = resets.begin(); rst != resets.end(); ++rst ) { reset_data *pReset = (*rst); ++onreset; switch( pReset->command )
Locate:
if( pMobIndex->count >= pReset->arg2 ) { mob = NULL; break; }
Change to:
if( !pReset->sreset ) { mob = NULL; break; }
Locate:
if( pRoomIndex->is_dark( mob ) ) mob->set_aflag( AFF_INFRARED );
Below that, add:
mob->resetvnum = pRoomIndex->vnum; mob->resetnum = onreset; pReset->sreset = false;
Locate:
for( dst = pReset->resets.begin(); dst != pReset->resets.end(); ++dst ) { reset_data *tReset = (*dst); switch( tReset->command )
Change to:
for( dst = pReset->resets.begin(); dst != pReset->resets.end(); ++dst ) { reset_data *tReset = (*dst); ++onreset; switch( tReset->command )
Locate:
for( gst = tReset->resets.begin(); gst != tReset->resets.end(); ++gst ) { reset_data *gReset = (*gst); int iNest; to_obj = lastobj; switch( gReset->command )
Change to:
for( gst = tReset->resets.begin(); gst != tReset->resets.end(); ++gst ) { reset_data *gReset = (*gst); int iNest; to_obj = lastobj; ++onreset; switch( gReset->command )
Locate:
for( dst = pReset->resets.begin(); dst != pReset->resets.end(); ++dst ) { int iNest; reset_data *tReset = (*dst); to_obj = lastobj; switch( tReset->command )
Change to:
for( dst = pReset->resets.begin(); dst != pReset->resets.end(); ++dst ) { int iNest; reset_data *tReset = (*dst); to_obj = lastobj; ++onreset; switch( tReset->command )
reset.cpp
At the bottom of reset.cpp, add the following new function:
// Update the mobile resets to let it know to reset it again void update_room_reset( char_data *ch, bool setting ) { room_index *room; list::iterator pst; int nfind = 0; if( !ch ) return; if( !( room = get_room_index( ch->resetvnum ) ) ) return; for( pst = room->resets.begin(); pst != room->resets.end(); ++pst ) { list ::iterator tst; reset_data *pReset = *pst; if( ++nfind == ch->resetnum ) { pReset->sreset = setting; return; } for( tst = pReset->resets.begin(); tst != pReset->resets.end(); ++tst ) { list ::iterator gst; reset_data *tReset = *tst; if( ++nfind == ch->resetnum ) { tReset->sreset = setting; return; } for( gst = tReset->resets.begin(); gst != tReset->resets.end(); ++gst ) { reset_data *gReset = *gst; if( ++nfind == ch->resetnum ) { gReset->sreset = setting; return; } } } } }
The basic problem here is that resets for mobs can specify a limit to how many of them should be loaded at any given time. This ( I think? ) worked just fine when resets were still based on the area as a whole. No more than X number of mobs would load. But when things were converted to room based resets, the counts went out the window. Each room could specify its own limit, which was meaningless in the big picture. Remcon's fix takes a different approach by tying each reset number to the mobs it creates and then keeping track of them to see if they should be reset again when the area reset is called.
Pages:<< prev 1 next >>