----------------------------------------------------------------------- Fixed Mobile Resets v1.0 by Xerves (February 26 2002) Xerves is the admin/owner of Rafermand (mud.rafermand.net port 3002) Website: http://www.rafermand.net Contact: xerves@rafermand.net ----------------------------------------------------------------------- As the name applies above, this snippet fixes the loading problems in Smaug when it comes to mobiles (perhaps all of Diku, but anyway). Instead of trying to load mobiles according to the numbered theory that it works on now, each mob is loaded based on its own unique serial. This allows you to place a mob and it will pop at that location and only pop if it has perrished. There is only one downside to this code is that you cannot say setup 5 mobiles to load in the beginning and have it swell to 40 if they aren't killed quickly. If you don't use this in your game, then it is suggested that you install this fix to help you get on your way. PLEASE READ: The following will attempt to set all number based resets for a mobile back to 1, so please make a copy of your code, areas, and building areas before you attempt to install this code. If for some reason you don't like how it works, you will have to renumber all your resets. You have been warned.... --------------------------------------------------------------------------------- Files being modified: act_wiz.c build.c db.c handler.c mud.h reset.c --------------------------------------------------------------------------------- ACT_WIZ.C --------------------------------------------------------------------------------- In do_mstat find this line pager_printf_color( ch, "\n\r&c%s: &C%-20s", IS_NPC(victim) ? "Mobile name" : "Name", victim->name ); Change it to look like this if (IS_NPC(ch)) pager_printf_color( ch, "\n\r&c%s: &C%-20s &cSerial: &C%-6d", IS_NPC(victim) ? "Mobile name" : "Name", victim->name, victim->pIndexData->serial ); else pager_printf_color( ch, "\n\r&c%s: &C%-20s", IS_NPC(victim) ? "Mobile name" : "Name", victim->name ); --------------------------------------------------------------------------------- BUILD.C --------------------------------------------------------------------------------- In parse_reset find these lines if ( !str_cmp( arg1, "mob" ) ) { if ( !get_mob_index(val1) ) { send_to_char( "Reset: MOB: no such mobile\n\r", ch ); return NULL; } if ( !get_room_index(val2) ) { send_to_char( "Reset: MOB: no such room\n\r", ch ); return NULL; } if ( val3 < 1 ) val3 = 1; letter = 'M'; } Change them to if ( !str_cmp( arg1, "mob" ) ) { if ( !get_mob_index(val1) ) { send_to_char( "Reset: MOB: no such mobile\n\r", ch ); return NULL; } if ( !get_room_index(val2) ) { send_to_char( "Reset: MOB: no such room\n\r", ch ); return NULL; } val3 = 1; //The numbered reset, not using it anymore so just leave it at 1... letter = 'M'; } --------------------------------------------------------------------------------- DB.C --------------------------------------------------------------------------------- Find these near the top of db.c int numobjsloaded; int physicalobjects; int last_pkroom; Add the following right below... bool serial_list[MAX_LOADED_MOBS]; int serialmobsloaded; //not quite the same as nummobsloaded, it has the ability to use past serials for "reset mobs" to reset mobs properly. In boot_db find these following declarations sh_int wear, x; Change them to int wear, x; Just a bit farther down boot_db find these variables nummobsloaded = 0; numobjsloaded = 0; physicalobjects = 0; sysdata.maxplayers = 0; Add the following right under them. serialmobsloaded = 0; for (x = 0; x < MAX_LOADED_MOBS; x++) serial_list[x] = 0; Find the following in create_mobile xCLEAR_BITS(mob->no_affected_by); mob->no_resistant = 0; mob->no_immune = 0; mob->no_susceptible = 0; /* * Insert in list. */ add_char( mob ); pMobIndex->count++; nummobsloaded++; Right below it add this serialmobsloaded++; mob->pIndexData->serial = serialmobsloaded; serial_list[mob->pIndexData->serial] = TRUE; if ((serialmobsloaded * 100 / MAX_LOADED_MOBS) >= 90) bug("Serialmobsloaded has reached %d, which is over 90 percent of the total of %d", serialmobsloaded, MAX_LOADED_MOBS); if (serialmobsloaded == MAX_LOADED_MOBS) { bug("Serialmobsloaded has reached the maximum value allowed, would suggest increasing MAX_LOADED_MOBS, till then, shutting down the mud!!!!"); exit(1); } In do_memory find the following lines ch_printf_color( ch, "&wPotion Val: &W%-16d &wScribe/Brew: &W%d/%d\n\r", sysdata.upotion_val, sysdata.scribed_used, sysdata.brewed_used ); ch_printf_color( ch, "&wPill Val: &W%-16d &wGlobal loot: &W%d\n\r", sysdata.upill_val, sysdata.global_looted ); Right below this add these lines ch_printf_color( ch, "&wSerialCnt: &W%d\n\r", serialmobsloaded); --------------------------------------------------------------------------------- HANDLER.C --------------------------------------------------------------------------------- In extract_char find the following lines if ( ( wch = get_char_room( ch, "healer" ) ) != NULL ) { act( AT_MAGIC, "$n mutters a few incantations, waves $s hands and points $s finger.", wch, NULL, NULL, TO_ROOM ); act( AT_MAGIC, "$n appears from some strange swirling mists!", ch, NULL, NULL, TO_ROOM ); sprintf(buf, "Welcome back to the land of the living, %s", capitalize( ch->name ) ); do_say( wch, buf ); } else act( AT_MAGIC, "$n appears from some strange swirling mists!", ch, NULL, NULL, TO_ROOM ); ch->position = POS_RESTING; return; } if ( IS_NPC(ch) ) { --ch->pIndexData->count; --nummobsloaded; Right below the last line before the } add this serial_list[ch->pIndexData->serial] = FALSE; --------------------------------------------------------------------------------- MUD.C --------------------------------------------------------------------------------- Find the following #define MAX_KEY_HASH 2048 #define MAX_STRING_LENGTH 4096 /* buf */ #define MAX_INPUT_LENGTH 1024 /* arg */ #define MAX_INBUF_SIZE 1024 Right below it add this #define MAX_LOADED_MOBS 100000 //maximum serials for mobs...if for some reason you have more than 100k, increase in 100k incriments, this //will increase RAM 12.5K a shot, but force another 100k item loop in db.c, so don't make it too high In the structure for mob_index_data, add this to the end of it int serial; //Used to identify mobiles for resets.... In the structure for reset_data, add this to the end of it int serial; //For mobile Resets, removing the "numbered" crap for resets. Find the following global variables extern int cur_obj; extern int cur_obj_serial; extern bool cur_obj_extracted; extern obj_ret global_objcode; Right below it add this extern bool serial_list[MAX_LOADED_MOBS]; extern int serialmobsloaded; //not quite the same as nummobsloaded, it has the ability to use past serials for "reset mobs" to reset mobs properly. --------------------------------------------------------------------------------- RESET.C --------------------------------------------------------------------------------- Find the following in edit_reset argument = one_argument(argument, arg); if ( !*arg || !is_number(arg) ) { send_to_char( "Usage: reset edit \n\r", ch ); return; } num = atoi(arg); if ( !(pReset = find_reset(pArea, aRoom, num)) ) { send_to_char( "Reset not found.\n\r", ch ); return; } if ( !(reset = parse_reset(pArea, argument, ch)) ) { send_to_char( "Error in reset. Reset not changed.\n\r", ch ); return; } Right below it add this reset->serial = pReset->serial; Find the following down a bit below if ( !str_cmp(arg, "add") ) { if ( (pReset = parse_reset(pArea, argument, ch)) == NULL ) { send_to_char( "Error in reset. Reset not added.\n\r", ch ); return; } add_reset(pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3); Change the last line to look like this reset = add_reset(pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3); reset->serial = ++serialmobsloaded; serial_list[reset->serial] = FALSE; Find the following below a few lines down if ( !str_cmp(arg, "place") ) { if ( (pReset = parse_reset(pArea, argument, ch)) == NULL ) { send_to_char( "Error in reset. Reset not added.\n\r", ch ); return; } place_reset(pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3); Again change the last line to look like this pReset->serial = ++serialmobsloaded; serial_list[pReset->serial] = FALSE; reset = place_reset(pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3); reset->serial = ++serialmobsloaded; serial_list[reset->serial] = FALSE; Find the following down a few lines if ( !str_cmp(arg, "insert") ) { argument = one_argument(argument, arg); if ( !*arg || !is_number(arg) ) { send_to_char( "Usage: reset insert \n\r", ch ); return; } num = atoi(arg); if ( (reset = find_reset(pArea, aRoom, num)) == NULL ) { send_to_char( "Reset not found.\n\r", ch ); return; } if ( (pReset = parse_reset(pArea, argument, ch)) == NULL ) { send_to_char( "Error in reset. Reset not inserted.\n\r", ch ); return; } Right after that add the following pReset->serial = ++serialmobsloaded; serial_list[pReset->serial] = FALSE; Find the following if ( !str_prefix( arg, "mobile" ) ) { argument = one_argument(argument, arg); if ( arg[0] == '\0' || !is_number(arg) ) { send_to_char( "Reset which mobile vnum?\n\r", ch ); return; } if ( !(pMob = get_mob_index(atoi(arg))) ) { send_to_char( "Mobile does not exist.\n\r", ch ); return; } argument = one_argument(argument, arg); if ( arg[0] == '\0' ) num = 1; else if ( !is_number(arg) ) { send_to_char( "Reset how many mobiles?\n\r", ch ); return; } else num = atoi(arg); if ( !(pRoom = find_room(ch, argument, aRoom)) ) return; pReset = make_reset('M', 0, pMob->vnum, num, pRoom->vnum); Directly after that add this pReset->serial = ++serialmobsloaded; pReset->arg2 = 1; serial_list[pReset->serial] = FALSE; In the declarations for instaroom add this (note not do_instaroom, just instaroom) RESET_DATA *reset; Find the following line just a few lines down add_reset( pArea, 'M', 1, rch->pIndexData->vnum, rch->pIndexData->count, pRoom->vnum ); Change it to reset = add_reset(pArea, 'M', 1, rch->pIndexData->vnum, 1, pRoom->vnum); reset->serial = rch->pIndexData->serial; serial_list[reset->serial] = TRUE; In the declarations of reset_area add this int currentserial; Find the following lines down just a few lines if ( pMobIndex->count >= pReset->arg2 ) { mob = NULL; break; } mob = create_mobile(pMobIndex); Replace those lines with these if (pReset->serial == 0) { mob = create_mobile(pMobIndex); pReset->serial = serialmobsloaded; serial_list[pReset->serial] = TRUE; } else { if (serial_list[pReset->serial] == FALSE) { currentserial = serialmobsloaded; serialmobsloaded = pReset->serial-1; mob = create_mobile(pMobIndex); serialmobsloaded = currentserial; serial_list[pReset->serial] = TRUE; } else { mob = NULL; break; } } In list_resets find the following line in the M case sprintf( pbuf, "%s (%d) -> %s (%d) [%d]", mname, pReset->arg1, rname, pReset->arg3, pReset->arg2 ); Change it to sprintf( pbuf, "%s (%d) -> %s (%d) [%d]", mname, pReset->arg1, rname, pReset->arg3, pReset->serial ); In add_reset find the folling line case 'M': tarea->last_mob_reset = pReset; break; Change it to case 'M': tarea->last_mob_reset = pReset; pReset->arg2 = -1; break; --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- Well that is pretty much it. Do a make clean and compile and start praying :-). Anyway, once you get things done, you really don't have to set anything. The serial system works on its own without any work down by the immortals. You cannot change the serial values either (if you for some reason wanted to add a way to do that, it wouldn't be too hard though, there is one on the mob_index_data and one on the reset_data). Only thing you might have to change is the 100,000 mob limit on the array. If you have nearly that mobs loaded, just increase it to 200,000. If you have any questions or had problems with the install, please contact me and I will try to help out. Email is rafermand@insightbb.com Thanks and good luck.