/*
* Alert: As of bpl14, this function returns the following codes:
* < 0 Victim died.
* = 0 No damage.
* > 0 How much damage done.
*/
long damage(struct char_data *ch, struct char_data *victim, long dam, int attacktype)
{
int i;
if (GET_POS(victim) <= POS_DEAD) {
/* This is "normal"-ish now with delayed extraction. -gg 3/15/2001 */
if (PLR_FLAGGED(victim, PLR_NOTDEADYET) || MOB_FLAGGED(victim, MOB_NOTDEADYET))
return (-1);
log("SYSERR: Attempt to damage corpse '%s' in room #%d by '%s'.",
GET_NAME(victim), GET_ROOM_VNUM(IN_ROOM(victim)), GET_NAME(ch));
die(victim, ch);
return (-1); /* -je, 7/7/92 */
}
for ( ch = char_list; ch != NULL; ch = ch->next )
{
ch_next = ch->next;
/* … */
for ( ch = char_list; ch != NULL; ch = ch_next )
^^^^^^^
{
ch_next = ch->next;
/* … */
Since I improved pet, people started to use it, and problem rised fast for the simplest reason.
pet logs with char, so they ALWAYS are char->next.
Since ROM code just loop through char_list using char->next as iterator, anything that makes ->next invalidated while in the loop screw everything.
When you code you do not do that without a safe iterator when you can modify your list.
How did you solved this ? puting is_valid(char) everytime you use a char ?
Other way ?
Personaly, since there is few loops I just made those iterator global and check when I extract char…it is ugly as hell but works.
I welcome any better solution though, I do not like the kind of hack I did but see nothing better ( I prefer to code in JAVA where I know how to solve these kind of problem, C is only for the mud)
I do not use the memory recycling factory either..I allocate and deallocate memory myself,this way valgrind can actually tell me wich variable where not initialised or if I have memory leak.