From bf8d75b7a3543fb45fffd4a76feeb1b16b7924d3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 24 Mar 2002 09:40:50 +0000 Subject: [PATCH] * otherfaction * crash in move_unit --- src/common/attributes/otherfaction.c | 26 ++++++++++++++++++++++---- src/common/attributes/otherfaction.h | 2 +- src/common/gamecode/creport.c | 5 +++-- src/common/gamecode/laws.c | 15 +-------------- src/common/gamecode/report.c | 2 +- src/common/gamecode/spy.c | 7 ++++--- src/common/kernel/battle.c | 2 +- src/common/kernel/eressea.c | 5 ++--- src/common/kernel/reports.c | 9 ++++++--- src/common/kernel/unit.c | 5 +++-- 10 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/common/attributes/otherfaction.c b/src/common/attributes/otherfaction.c index 920e1f0f9..7a9f9c45d 100644 --- a/src/common/attributes/otherfaction.c +++ b/src/common/attributes/otherfaction.c @@ -22,21 +22,39 @@ * simple attributes that do not yet have their own file */ + +void +write_of(const struct attrib * a, FILE* F) +{ + const faction * f = (faction*)a->data.v; + fprintf(F, "%d", f->no); +} + +int +read_of(struct attrib * a, FILE* F) /* return 1 on success, 0 if attrib needs removal */ +{ + int of; + fscanf(F, "%d", &of); + a->data.v = findfaction(of); + if (a->data.v) return 1; + return 0; +} + attrib_type at_otherfaction = { - "otherfaction", NULL, NULL, NULL, a_writedefault, a_readdefault, ATF_UNIQUE + "otherfaction", NULL, NULL, NULL, write_of, read_of, ATF_UNIQUE }; struct faction * get_otherfaction(const struct attrib * a) { - return findfaction(a->data.i); + return (faction*)(a->data.v); } struct attrib * -make_otherfaction(const struct faction * f) +make_otherfaction(struct faction * f) { attrib * a = a_new(&at_otherfaction); - a->data.i = f->no; + a->data.v = (void*)f; return a; } diff --git a/src/common/attributes/otherfaction.h b/src/common/attributes/otherfaction.h index d8a327638..4f0e30fbe 100644 --- a/src/common/attributes/otherfaction.h +++ b/src/common/attributes/otherfaction.h @@ -16,4 +16,4 @@ struct attrib; extern struct attrib_type at_otherfaction; extern void init_otherfaction(void); extern struct faction * get_otherfaction(const struct attrib * a); -extern struct attrib * make_otherfaction(const struct faction * f); +extern struct attrib * make_otherfaction(struct faction * f); diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index 22aec129f..021f16653 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -551,6 +551,7 @@ cr_output_unit(FILE * F, const region * r, } if (u->faction == f || omniscient(f)) { const attrib *a_otherfaction = a_find(u->attribs, &at_otherfaction); + const faction * otherfaction = a_otherfaction?get_otherfaction(a_otherfaction):NULL; /* my own faction, full info */ const attrib * ap = 0; if (a) { @@ -562,8 +563,8 @@ cr_output_unit(FILE * F, const region * r, if (sf!=u->faction) fprintf(F, "%d;Verkleidung\n", sf->no); if (fval(u, FL_PARTEITARNUNG)) fprintf(F, "%d;Parteitarnung\n", i2b(fval(u, FL_PARTEITARNUNG))); - if (a_otherfaction) - fprintf(F, "%d;Anderepartei\n", a_otherfaction->data.i); + if (otherfaction) + fprintf(F, "%d;Anderepartei\n", otherfaction->no); } else { if (fval(u, FL_PARTEITARNUNG)) { /* faction info is hidden */ diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 7dd0fb2b3..eb18de833 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -225,7 +225,7 @@ destroyfaction(faction * f) for(u=rc->units; u; u=u->next) { attrib *a = a_find(u->attribs, &at_otherfaction); if(!a) continue; - if(a->data.i == f->no) { + if (get_otherfaction(a) == f) { a_removeall(&u->attribs, &at_otherfaction); fset(u, FL_PARTEITARNUNG); } @@ -2719,20 +2719,7 @@ renumber_factions(void) } } for (rp=renum;rp;rp=rp->next) { - region *r; - unit *u; a_remove(&rp->faction->attribs, rp->attrib); - /* all units disguised as belonging to this faction have their - * attribute changed */ - for(r=regions; r; r=r->next) { - for(u=r->units; u; u=u->next) { - attrib *a = a_find(u->attribs, &at_otherfaction); - if(!a) continue; - if (a->data.i == rp->faction->no){ - a->data.i = rp->want; - } - } - } if (updatelog) fprintf(updatelog, "renum %s %s\n", itoa36(rp->faction->no), itoa36(rp->want)); fprintf(sqlstream, "UPDATE subscriptions set faction='%s' where " "faction='%s' and game=%d;", itoa36(rp->want), diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index 71a3158e3..45b4b09cb 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -754,7 +754,7 @@ rpunit(FILE * F, const faction * f, const unit * u, int indent, int mode) if(u->faction == f) { marker = '*'; } else { - if(a_otherfaction && f != u->faction && a_otherfaction->data.i == f->no + if(a_otherfaction && f != u->faction && get_otherfaction(a_otherfaction) == f && !fval(u, FL_PARTEITARNUNG)) { marker = '!'; } else { diff --git a/src/common/gamecode/spy.c b/src/common/gamecode/spy.c index e06074b9a..45fa9255f 100644 --- a/src/common/gamecode/spy.c +++ b/src/common/gamecode/spy.c @@ -180,14 +180,15 @@ setstealth(unit * u, strlist * S) if(!s2 || *s2 == 0 || nr == u->faction->no) { a_removeall(&u->attribs, &at_otherfaction); } else { + struct faction * f = findfaction(nr); /* TODO: Prüfung ob Partei sichtbar */ - if(!findfaction(nr)) { + if(f==NULL) { cmistake(u, S->s, 66, MSG_EVENT); } else { attrib *a; a = a_find(u->attribs, &at_otherfaction); - if(!a) a = a_add(&u->attribs, a_new(&at_otherfaction)); - a->data.i = nr; + if (!a) a = a_add(&u->attribs, make_otherfaction(f)); + else a->data.v = f; } } } else { diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 3b614abb2..eda63f5c7 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -2660,7 +2660,7 @@ make_fighter(battle * b, unit * u, boolean attack) const attrib * a = a_find(u->attribs, &at_group); const group * g = a?(const group*)a->data.v:NULL; const attrib *a2 = a_find(u->attribs, &at_otherfaction); - const faction *stealthfaction = a2?findfaction(a2->data.i):NULL; + const faction *stealthfaction = a2?get_otherfaction(a2):NULL; /* Illusionen und Zauber kaempfen nicht */ if (fval(u->race, RCF_ILLUSIONARY) || idle(u->faction)) diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index c677b4cba..e29923903 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -1678,9 +1678,8 @@ create_unit(region * r, faction * f, int number, const struct race *urace, int i a_add(&u->attribs, a_new(&at_group))->data.v = g; } a = a_find(creator->attribs, &at_otherfaction); - if (a){ - attrib *an = a_add(&u->attribs, a_new(&at_otherfaction)); - an->data.i = a->data.i; + if (a) { + a_add(&u->attribs, make_otherfaction(get_otherfaction(a))); } } /* Monster sind grundsätzlich parteigetarnt */ diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index 5476bfb46..0452caae8 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -196,9 +196,12 @@ bufunit(const faction * f, const unit * u, int indent, int mode) } if (getarnt) { scat(", "); scat(LOC(f->locale, "anonymous")); - } else if (a_otherfaction) { - scat(", "); - scat(factionname(findfaction(a_otherfaction->data.i))); + } else if (a_otherfaction) { + faction * otherfaction = get_otherfaction(a_otherfaction); + if (otherfaction) { + scat(", "); + scat(factionname(otherfaction)); + } } } else { if (getarnt) { diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index 7278e9097..33559fa70 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -644,10 +644,11 @@ can_survive(const unit *u, const region *r) void move_unit(unit * u, region * r, unit ** ulist) { - int maxhp = unit_max_hp(u); + int maxhp = 0; assert(u && r); if (u->region == r) return; + if (u->region!=NULL) maxhp = unit_max_hp(u); if (!ulist) ulist = (&r->units); if (u->region) { set_moved(&u->attribs); @@ -661,7 +662,7 @@ move_unit(unit * u, region * r, unit ** ulist) u->faction->first = 0; u->faction->last = 0; u->region = r; - u->hp = u->hp * unit_max_hp(u) / maxhp; + if (maxhp>0) u->hp = u->hp * unit_max_hp(u) / maxhp; } /* ist mist, aber wegen nicht skalierender attirbute notwendig: */