From d57e05fcd76dca796df261485934f1cb2f2d4072 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 21 May 2006 10:35:08 +0000 Subject: [PATCH] crashbug dying clone-mages --- src/common/kernel/unit.c | 175 ++++++++++++++++++++------------------- src/common/util/attrib.c | 10 ++- src/res/messages.xml | 2 +- 3 files changed, 95 insertions(+), 92 deletions(-) diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index 571607630..344209cd0 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -181,97 +181,98 @@ distribute_items(unit * u) void destroy_unit(unit * u) { - region *r = u->region; - boolean zombie = false; - unit *clone; - - if (!ufindhash(u->no)) return; - - if (!fval(u->race, RCF_ILLUSIONARY)) { - item ** p_item = &u->items; - unit * u3; - - /* u->faction->no_units--; */ /* happens in u_setfaction now */ - - if (r) for (u3 = r->units; u3; u3 = u3->next) { - if (u3 != u && u3->faction == u->faction && playerrace(u3->race)) { - i_merge(&u3->items, &u->items); - u->items = NULL; - break; - } - } - u3 = NULL; - while (*p_item) { - item * item = *p_item; - if (item->number && item->type->flags & ITF_NOTLOST) { - if (u3==NULL) { - u3 = r->units; - while (u3 && u3!=u) u3 = u3->next; - if (!u3) { - zombie = true; - break; - } - } - if (u3) { - i_add(&u3->items, i_remove(p_item, item)); - } - } - if (*p_item == item) p_item=&item->next; - } + region *r = u->region; + boolean zombie = false; + unit *clone; + + if (!ufindhash(u->no)) return; + + if (!fval(u->race, RCF_ILLUSIONARY)) { + item ** p_item = &u->items; + unit * u3; + + /* u->faction->no_units--; */ /* happens in u_setfaction now */ + + if (r) for (u3 = r->units; u3; u3 = u3->next) { + if (u3 != u && u3->faction == u->faction && playerrace(u3->race)) { + i_merge(&u3->items, &u->items); + u->items = NULL; + break; + } + } + u3 = NULL; + while (*p_item) { + item * item = *p_item; + if (item->number && item->type->flags & ITF_NOTLOST) { + if (u3==NULL) { + u3 = r->units; + while (u3 && u3!=u) u3 = u3->next; + if (!u3) { + zombie = true; + break; + } + } + if (u3) { + i_add(&u3->items, i_remove(p_item, item)); + } + } + if (*p_item == item) p_item=&item->next; + } if (u->items && strlen(u->faction->passw)>0) { distribute_items(u); } - } - - /* Wir machen das erst nach dem Löschen der Items. Der Klon darf keine - * Items haben, sonst Memory-Leak. */ - - clone = has_clone(u); - if (clone && rng_int()%100 < 90) { - attrib *a; - int i; - - /* TODO: Messages generieren. */ - u->region = clone->region; - u->ship = clone->ship; - u->building = clone->building; - u->hp = 1; - i = u->no; - uunhash(u); - uunhash(clone); - u->no = clone->no; - clone->no = i; - uhash(u); - uhash(clone); - set_number(u, 1); - set_spellpoints(u, 0); - a = a_find(u->attribs, &at_clone); - a_remove(&u->attribs, a); - a = a_find(clone->attribs, &at_clonemage); - a_remove(&clone->attribs, a); - fset(u, UFL_LONGACTION); - set_number(clone, 0); - u = clone; - zombie = false; - } + } + + /* Wir machen das erst nach dem Löschen der Items. Der Klon darf keine + * Items haben, sonst Memory-Leak. */ + + clone = has_clone(u); + if (clone && rng_int()%100 < 90) { + attrib *a; + int i; + + /* TODO: Messages generieren. */ + u->region = clone->region; + u->ship = clone->ship; + u->building = clone->building; + u->hp = 1; + i = u->no; + uunhash(u); + uunhash(clone); + u->no = clone->no; + clone->no = i; + uhash(u); + uhash(clone); + set_number(u, 1); + set_spellpoints(u, 0); + a = a_find(u->attribs, &at_clone); + if (a!=NULL) a_remove(&u->attribs, a); + a = a_find(clone->attribs, &at_clonemage); + if (a!=NULL) a_remove(&clone->attribs, a); + fset(u, UFL_LONGACTION); + set_number(clone, 0); + u = clone; + zombie = false; + } - if (zombie) { - u_setfaction(u, findfaction(MONSTER_FACTION)); - scale_number(u, 1); - u->race = u->irace = new_race[RC_ZOMBIE]; - } else { - if (u->number) set_number(u, 0); - handle_event(&u->attribs, "destroy", u); - if (r && !fval(r->terrain, SEA_REGION)) - rsetmoney(r, rmoney(r) + get_money(u)); - dhash(u->no, u->faction); - u_setfaction(u, NULL); - if (r) leave(r, u); - uunhash(u); - if (r) choplist(&r->units, u); - u->next = udestroy; - udestroy = u; - } + if (zombie) { + u_setfaction(u, findfaction(MONSTER_FACTION)); + scale_number(u, 1); + u->race = u->irace = new_race[RC_ZOMBIE]; + } else { + if (u->number) set_number(u, 0); + handle_event(&u->attribs, "destroy", u); + if (r && !fval(r->terrain, SEA_REGION)) { + rsetmoney(r, rmoney(r) + get_money(u)); + } + dhash(u->no, u->faction); + u_setfaction(u, NULL); + if (r) leave(r, u); + uunhash(u); + if (r) choplist(&r->units, u); + u->next = udestroy; + udestroy = u; + } } unit * diff --git a/src/common/util/attrib.c b/src/common/util/attrib.c index fad6f8610..16569f188 100644 --- a/src/common/util/attrib.c +++ b/src/common/util/attrib.c @@ -156,6 +156,7 @@ a_unlink(attrib ** pa, attrib * a) attrib ** pnexttype = pa; attrib ** pnext = NULL; + assert(a!=NULL); while (*pnexttype) { attrib * next = *pnexttype; if (next->type==a->type) break; @@ -187,10 +188,11 @@ a_unlink(attrib ** pa, attrib * a) int a_remove(attrib ** pa, attrib * a) { - int ok; - ok = a_unlink(pa, a); - if (ok) a_free(a); - return ok; + int ok; + assert(a!=NULL); + ok = a_unlink(pa, a); + if (ok) a_free(a); + return ok; } void diff --git a/src/res/messages.xml b/src/res/messages.xml index 26120a349..39eed54ca 100644 --- a/src/res/messages.xml +++ b/src/res/messages.xml @@ -776,7 +776,7 @@ - "Die $region($ship) treibt nach $direction($dir)." + "Die $ship($ship) treibt nach $direction($dir)." "The ship $ship($ship) drifts to the $direction($dir)." "The ship $ship($ship) drifts to the $direction($dir)."