On Aug 4, David Klasinc wrote > > Ok, I've done, what Sammy and George were suggesting and the result is, > that still, nothing is working.. *grumble* > Then I have this in my check_fall() where I check if ch is falling and > since it's called every 2 seconds I've also put in few room spells that > are supposed to take hp from char... > > void check_fall(void) > { > int fall_dmg; > struct char_data *ch, *next_ch; > for (ch = character_list; ch; ch = next_ch) { > next_ch = ch->next; > > if (ROOM_AFFECTED(IN_ROOM(ch), RAFF_ACID_RAIN)) > gen_damage(ch, GET_MAX_HIT(ch) * 10 / 100, SPELL_ACID_RAIN); > > if (ch && ((SECT(IN_ROOM(ch)) == SECT_FLYING)) && (!AFF_FLAGGED(ch, AFF_FLY > !(IS_NPC(ch) && MOB_FLAGGED(ch, MOB_WINGS)) && > !(IS_NPC(ch) && MOB_FLAGGED(ch, MOB_NOACT)) && > !(GET_LEVEL(ch) > LVL_IMMORT)) { > > .... etc etc etc ... > Then there are usual checks, for the falling... as goes... first we check > if ch is there... remember, we got in a syslog, that ch was set to NULL > and that everything should work... Then we check if there is air in the > room, if ch is maybe affected by flying, is this a mob with wings? and no > act mobs (these are my dummy mobs, that just sit there with mobprogs > hooked on them) and if ch is maybe immortal... Ok.. and mud crashes > here... Your FREE() macro is doing nothing for you here, because its another level of the stack you're freeing at. void check_fail(...) { ... /* ch = 0x807ee85 */ gen_damage(0x807ee85, ...); Now, in gen_damage(), you have... gen_damage(ch, ...) { ... /* ch = 0x807ee85 */ free(ch); ch = NULL; /* ch = 0x0 */ ... } (The actual free() and ch = NULL probably occur within a function called by gen_damage(), but the effects are still the same.) But now you return to the previous stack level, so ch is still the same as before the gen_damage() call. /* ch = 0x807ee85 */ if (ch && ((SECT(IN_ROOM(ch)) == SECT_FLYING)) && ... And the game crashes. If you still don't see why this is happening, consider a simpiler program which does the same thing: void foo(int i) { i = 0; } void main() { int j = 10; foo(j); printf("%d\n", j); } which should be obvious that it will print 10, because j is passed by value, not by reference. To fix your problem, you could have gen_damage() return a special value indicating that the character has been freed. In check_fall(), you would test the return value, and return from check_fall() if the player died. if (ROOM_AFFECTED(IN_ROOM(ch), RAFF_ACID_RAIN)) if (gen_damage(ch, GET_MAX_HIT(ch) * 10 / 100, SPELL_ACID_RAIN) < 0) return; if (ch && ((SECT(IN_ROOM(ch)) == SECT_FLYING)) && ... Other solutions are throwing an exception in extract_char(), so the rest of that function would be skipped, or moving extracted chars to a storage room and freeing at the game_loop() level of the game. Eric +------------------------------------------------------------+ | Ensure that you have read the CircleMUD Mailing List FAQ: | | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html | +------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/08/00 PST