* otherfaction

* crash in move_unit
This commit is contained in:
Enno Rehling 2002-03-24 09:40:50 +00:00
parent c0c71cbfb1
commit bf8d75b7a3
10 changed files with 44 additions and 34 deletions

View File

@ -22,21 +22,39 @@
* simple attributes that do not yet have their own file * 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 = { 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 * struct faction *
get_otherfaction(const struct attrib * a) get_otherfaction(const struct attrib * a)
{ {
return findfaction(a->data.i); return (faction*)(a->data.v);
} }
struct attrib * struct attrib *
make_otherfaction(const struct faction * f) make_otherfaction(struct faction * f)
{ {
attrib * a = a_new(&at_otherfaction); attrib * a = a_new(&at_otherfaction);
a->data.i = f->no; a->data.v = (void*)f;
return a; return a;
} }

View File

@ -16,4 +16,4 @@ struct attrib;
extern struct attrib_type at_otherfaction; extern struct attrib_type at_otherfaction;
extern void init_otherfaction(void); extern void init_otherfaction(void);
extern struct faction * get_otherfaction(const struct attrib * a); 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);

View File

@ -551,6 +551,7 @@ cr_output_unit(FILE * F, const region * r,
} }
if (u->faction == f || omniscient(f)) { if (u->faction == f || omniscient(f)) {
const attrib *a_otherfaction = a_find(u->attribs, &at_otherfaction); 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 */ /* my own faction, full info */
const attrib * ap = 0; const attrib * ap = 0;
if (a) { 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 (sf!=u->faction) fprintf(F, "%d;Verkleidung\n", sf->no);
if (fval(u, FL_PARTEITARNUNG)) if (fval(u, FL_PARTEITARNUNG))
fprintf(F, "%d;Parteitarnung\n", i2b(fval(u, FL_PARTEITARNUNG))); fprintf(F, "%d;Parteitarnung\n", i2b(fval(u, FL_PARTEITARNUNG)));
if (a_otherfaction) if (otherfaction)
fprintf(F, "%d;Anderepartei\n", a_otherfaction->data.i); fprintf(F, "%d;Anderepartei\n", otherfaction->no);
} else { } else {
if (fval(u, FL_PARTEITARNUNG)) { if (fval(u, FL_PARTEITARNUNG)) {
/* faction info is hidden */ /* faction info is hidden */

View File

@ -225,7 +225,7 @@ destroyfaction(faction * f)
for(u=rc->units; u; u=u->next) { for(u=rc->units; u; u=u->next) {
attrib *a = a_find(u->attribs, &at_otherfaction); attrib *a = a_find(u->attribs, &at_otherfaction);
if(!a) continue; if(!a) continue;
if(a->data.i == f->no) { if (get_otherfaction(a) == f) {
a_removeall(&u->attribs, &at_otherfaction); a_removeall(&u->attribs, &at_otherfaction);
fset(u, FL_PARTEITARNUNG); fset(u, FL_PARTEITARNUNG);
} }
@ -2719,20 +2719,7 @@ renumber_factions(void)
} }
} }
for (rp=renum;rp;rp=rp->next) { for (rp=renum;rp;rp=rp->next) {
region *r;
unit *u;
a_remove(&rp->faction->attribs, rp->attrib); 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)); if (updatelog) fprintf(updatelog, "renum %s %s\n", itoa36(rp->faction->no), itoa36(rp->want));
fprintf(sqlstream, "UPDATE subscriptions set faction='%s' where " fprintf(sqlstream, "UPDATE subscriptions set faction='%s' where "
"faction='%s' and game=%d;", itoa36(rp->want), "faction='%s' and game=%d;", itoa36(rp->want),

View File

@ -754,7 +754,7 @@ rpunit(FILE * F, const faction * f, const unit * u, int indent, int mode)
if(u->faction == f) { if(u->faction == f) {
marker = '*'; marker = '*';
} else { } 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)) { && !fval(u, FL_PARTEITARNUNG)) {
marker = '!'; marker = '!';
} else { } else {

View File

@ -180,14 +180,15 @@ setstealth(unit * u, strlist * S)
if(!s2 || *s2 == 0 || nr == u->faction->no) { if(!s2 || *s2 == 0 || nr == u->faction->no) {
a_removeall(&u->attribs, &at_otherfaction); a_removeall(&u->attribs, &at_otherfaction);
} else { } else {
struct faction * f = findfaction(nr);
/* TODO: Prüfung ob Partei sichtbar */ /* TODO: Prüfung ob Partei sichtbar */
if(!findfaction(nr)) { if(f==NULL) {
cmistake(u, S->s, 66, MSG_EVENT); cmistake(u, S->s, 66, MSG_EVENT);
} else { } else {
attrib *a; attrib *a;
a = a_find(u->attribs, &at_otherfaction); a = a_find(u->attribs, &at_otherfaction);
if(!a) a = a_add(&u->attribs, a_new(&at_otherfaction)); if (!a) a = a_add(&u->attribs, make_otherfaction(f));
a->data.i = nr; else a->data.v = f;
} }
} }
} else { } else {

View File

@ -2660,7 +2660,7 @@ make_fighter(battle * b, unit * u, boolean attack)
const attrib * a = a_find(u->attribs, &at_group); const attrib * a = a_find(u->attribs, &at_group);
const group * g = a?(const group*)a->data.v:NULL; const group * g = a?(const group*)a->data.v:NULL;
const attrib *a2 = a_find(u->attribs, &at_otherfaction); 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 */ /* Illusionen und Zauber kaempfen nicht */
if (fval(u->race, RCF_ILLUSIONARY) || idle(u->faction)) if (fval(u->race, RCF_ILLUSIONARY) || idle(u->faction))

View File

@ -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_add(&u->attribs, a_new(&at_group))->data.v = g;
} }
a = a_find(creator->attribs, &at_otherfaction); a = a_find(creator->attribs, &at_otherfaction);
if (a){ if (a) {
attrib *an = a_add(&u->attribs, a_new(&at_otherfaction)); a_add(&u->attribs, make_otherfaction(get_otherfaction(a)));
an->data.i = a->data.i;
} }
} }
/* Monster sind grundsätzlich parteigetarnt */ /* Monster sind grundsätzlich parteigetarnt */

View File

@ -196,9 +196,12 @@ bufunit(const faction * f, const unit * u, int indent, int mode)
} }
if (getarnt) { if (getarnt) {
scat(", "); scat(LOC(f->locale, "anonymous")); scat(", "); scat(LOC(f->locale, "anonymous"));
} else if (a_otherfaction) { } else if (a_otherfaction) {
scat(", "); faction * otherfaction = get_otherfaction(a_otherfaction);
scat(factionname(findfaction(a_otherfaction->data.i))); if (otherfaction) {
scat(", ");
scat(factionname(otherfaction));
}
} }
} else { } else {
if (getarnt) { if (getarnt) {

View File

@ -644,10 +644,11 @@ can_survive(const unit *u, const region *r)
void void
move_unit(unit * u, region * r, unit ** ulist) move_unit(unit * u, region * r, unit ** ulist)
{ {
int maxhp = unit_max_hp(u); int maxhp = 0;
assert(u && r); assert(u && r);
if (u->region == r) return; if (u->region == r) return;
if (u->region!=NULL) maxhp = unit_max_hp(u);
if (!ulist) ulist = (&r->units); if (!ulist) ulist = (&r->units);
if (u->region) { if (u->region) {
set_moved(&u->attribs); set_moved(&u->attribs);
@ -661,7 +662,7 @@ move_unit(unit * u, region * r, unit ** ulist)
u->faction->first = 0; u->faction->first = 0;
u->faction->last = 0; u->faction->last = 0;
u->region = r; 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: */ /* ist mist, aber wegen nicht skalierender attirbute notwendig: */