> > 4. How about something like this (pseudocode, unchecked, variables names will > differ)... > > for (currmob = top_of_table; *currmob; currmob = nextmob) { > nextmob = currmob->next; > > /* Main Mob Code goes in here */ > > if (argument == REMOVE_PLAYER) { /* <--- Or something like that. */ > if (player_to_be_removed == nextmob) > nextmob = nextmov->next; > > /* Code to remove player in here. */ > } > > /* Rest of Mob Code goes in here */ > } Matter of fact, I thought of this, but beacause I was in a hurry, I didn't have time to jot this idea down as one of the non functional ones. Let's first assume you're not running mobprogs or spec_procs which both allow you to cause instant extraction of a charater, because there's no good way to check if a char exists or not without recreating the entire character_index and restarting your for loop from the top. This would mean that you would have to traverse the list at least once for every mob until such a time that a given mob does not remove someone (which means multiple mob_activity cycles for that mob, and all those previous to it). Let's say though that aside from those difficult to check circumstances, that we have a mob whos type extracts mobs. Now, we can monitor this behavior pretty easily, say we have 5 mobs in a room, and the first simply purges the room. So, mob1 exists, but the next mobs in the character list are all gone - mobs2 through mob5. We had previously saved our next char as next_char=mob1->next, however, that was pointing to mob2. We see that mob2 has been removed, and from there we go to next_char=mob2->next ... and suddenly crash beccause we're accessing information in a structure that has been freed. This dealing with extractions in a graceful, and most of all efficient way is actually a common theme in quite a few forums, and funny enough the efficient solution I used for my mud was based off of a garbage collection memory management system. It seems a little obscured but here's the pseudo code: struct list_struct { struct char_data *character; struct list_struct *next; } before game execution: generate a list of all npcs -> (struct list_struct *) master_list (see note below about load_mobile()) also have a null storage list. -> secondary_list within main game loop: void our_function() { extern struct list_struct *master_list,*secondary_list; struct list_struct *current,*temp_list; temp_list=master_list; while(temp_list) { current=temp_list; /* could have just said temp_list = temp_list->next, but *shrug*/ REMOVE_FROM_LIST(current,temp_list,next); current->next = secondary_list; secondary_list=temp_list; /* in extract_char, we also check for existance of character first in the master list (which we remove of course) and then in the secondary list (which we also remove) If any extractions occur in the following structure, we need ->no<- references to that fact from within this loop as we're operating only on the head of the list */ perform_mobile_activity(current->character); } master_list=secondary_list; } Your only obligation is then to make sure that in load_mobile or synonymous functions that you add the entry in master_list. This can (and should) be coupled with the addition of the mobile to the character_list. --> THE PAYOFF <-- The end result of this is that you may extract characters from within your mobile activity loops without error, whether it's from mob programs, spec_procs, ..i'm not sure where random or timed dg scripts trigger from, but i'd recommend placing them in the perform_mobile_activity loop. This only requires a bit more memory to make a character list, and that character list is then reversed each time it is read out. This should not cause any trouble for anyone since you should never expect the order of the character list to remain constant, or have any functions which depend on it being so. Or you'll crash as if you would if you have the stock mobile_activity and tried to extract chars :) I haven't looked, but I'm sure there's a few more of these rarely triggered flaws around, like I said though, i'll put out a patch when I have time, probably later tonight. George - this just shooting in the dark, or something that's already been taken care of? PjD +------------------------------------------------------------+ | Ensure that you have read the CircleMUD Mailing List FAQ: | | http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html | +------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/15/00 PST