diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index 4f5b016de..ecec5cd7c 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -613,11 +613,22 @@ cr_output_unit(FILE * F, const region * r, const item_type * lasttype; int pr; item *itm, *show; - boolean itemcloak = is_cursed(u->attribs, C_ITEMCLOAK, 0); building * b; const char * pzTmp; skill * sv; const attrib *a_fshidden = NULL; + boolean itemcloak = false; + static const curse_type * itemcloak_ct = 0; + static boolean init = false; + + if (!init) { + init = true; + itemcloak_ct = ct_find("itemcloak"); + } + + if (itemcloak_ct!=NULL) { + itemcloak = curse_active(get_curse(u->attribs, itemcloak_ct)); + } assert(u); @@ -637,7 +648,8 @@ cr_output_unit(FILE * F, const region * r, 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 *a = a_find(u->attribs, &at_group); + const attrib *a = NULL; + if (fval(u, UFL_GROUP)) a = a_find(u->attribs, &at_group); if (a!=NULL) { const group * g = (const group*)a->data.v; fprintf(F, "%d;gruppe\n", g->gid); @@ -731,12 +743,14 @@ cr_output_unit(FILE * F, const region * r, fprintf(F, "%d;alias\n", -i); i = get_money(u); fprintf(F, "%d;Kampfstatus\n", u->status); - if(fval(u, UFL_NOAID)) { + if (fval(u, UFL_NOAID)) { fputs("1;unaided\n", F); } - i = u_geteffstealth(u); - if (i >= 0) { - fprintf(F, "%d;Tarnung\n", i); + if (fval(u, UFL_STEALTH)) { + i = u_geteffstealth(u); + if (i >= 0) { + fprintf(F, "%d;Tarnung\n", i); + } } c = uprivate(u); if (c) { diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 5d1596971..73f9c86f3 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -1237,7 +1237,7 @@ ally_cmd(unit * u, struct order * ord) keyword = findparam(s, u->faction->locale); sfp = &u->faction->allies; - { + if (fval(u, UFL_GROUP)) { attrib * a = a_find(u->attribs, &at_group); if (a) sfp = &((group*)a->data.v)->allies; } @@ -1327,7 +1327,6 @@ static int prefix_cmd(unit * u, struct order * ord) { attrib **ap; - attrib *a; int i; const char *s; @@ -1336,9 +1335,13 @@ prefix_cmd(unit * u, struct order * ord) s = getstrtoken(); if (!*s) { - a = a_find(u->attribs, &at_group); + attrib *a = NULL; + if (fval(u, UFL_GROUP)) { + a = a_find(u->attribs, &at_group); + } if (a) { - a_removeall(&((group*)a->data.v)->attribs, &at_raceprefix); + group * g = (group*)a->data.v; + a_removeall(&g->attribs, &at_raceprefix); } else { a_removeall(&u->faction->attribs, &at_raceprefix); } @@ -1358,8 +1361,11 @@ prefix_cmd(unit * u, struct order * ord) } ap = &u->faction->attribs; - a = a_find(u->attribs, &at_group); - if (a) ap = &((group*)a->data.v)->attribs; + if (fval(u, UFL_GROUP)) { + attrib * a = a_find(u->attribs, &at_group); + group * g = (group*)a->data.v; + if (a) ap = &g->attribs; + } set_prefix(ap, race_prefixes[i]); return 0; @@ -1735,10 +1741,11 @@ name_cmd(unit * u, struct order * ord) case P_GROUP: { - attrib * a = a_find(u->attribs, &at_group); - if (a){ + attrib * a = NULL; + if (fval(u, UFL_GROUP)) a = a_find(u->attribs, &at_group); + if (a) { group * g = (group*)a->data.v; - s= &g->name; + s = &g->name; break; } else { cmistake(u, ord, 109, MSG_EVENT); diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 56f384a35..dd109f4de 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -2852,10 +2852,14 @@ make_fighter(battle * b, unit * u, side * s1, boolean attack) boolean pr_aid = false; boolean stealth = (boolean)((fval(u, UFL_PARTEITARNUNG)!=0)?true:false); int rest; - 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?get_otherfaction(a2):NULL; + const group * g = NULL; + const attrib *a = a_find(u->attribs, &at_otherfaction); + const faction *stealthfaction = a?get_otherfaction(a):NULL; + + if (fval(u, UFL_GROUP)) { + const attrib * agroup = a_find(u->attribs, &at_group); + if (agroup!=NULL) g = (const group*)agroup->data.v; + } /* 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 9b453e2dd..05931d7f0 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -851,27 +851,32 @@ effskill(const unit * u, skill_t sk) int effstealth(const unit * u) { - int e, es; + int e; /* Auf dem Ozean keine Tarnung! */ if (u->region->terrain == T_OCEAN) return 0; e = effskill(u, SK_STEALTH); - es = u_geteffstealth(u); - if (es >=0 && es < e) return es; + if (fval(u, UFL_STEALTH)) { + int es = u_geteffstealth(u); + if (es >=0 && es < e) return es; + } return e; } int eff_stealth (const unit * u, const region * r) { - int e, es; + int e; + if (r->terrain == T_OCEAN) return 0; e = eff_skill (u, SK_STEALTH, r); - es = u_geteffstealth(u); - if (es >=0 && es < e) return es; + if (fval(u, UFL_STEALTH)) { + int es = u_geteffstealth(u); + if (es >=0 && es < e) return es; + } return e; } @@ -1009,7 +1014,6 @@ int alliedunit(const unit * u, const faction * f2, int mode) { ally * sf; - const attrib * a; const plane * pl = getplane(u->region); int automode; @@ -1022,8 +1026,10 @@ alliedunit(const unit * u, const faction * f2, int mode) mode = (mode & automode) | (mode & HELP_GIVE); sf = u->faction->allies; - a = a_findc(u->attribs, &at_group); - if (a!=NULL) sf = ((group*)a->data.v)->allies; + if (fval(u, UFL_GROUP)) { + const attrib * a = a_findc(u->attribs, &at_group); + if (a!=NULL) sf = ((group*)a->data.v)->allies; + } return alliedgroup(pl, u->faction, f2, sf, mode); } @@ -1983,11 +1989,14 @@ create_unit(region * r, faction * f, int number, const struct race *urace, int i } /* Gruppen */ - a = a_find(creator->attribs, &at_group); - if (a) { - group * g = (group*)a->data.v; - a_add(&u->attribs, a_new(&at_group))->data.v = g; - } + if (fval(creator, UFL_GROUP)) { + a = a_find(creator->attribs, &at_group); + if (a) { + group * g = (group*)a->data.v; + a_add(&u->attribs, a_new(&at_group))->data.v = g; + fset(u, UFL_GROUP); + } + } a = a_find(creator->attribs, &at_otherfaction); if (a) { a_add(&u->attribs, make_otherfaction(get_otherfaction(a))); diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c index 70ca92f94..fdd85b743 100644 --- a/src/common/kernel/faction.c +++ b/src/common/kernel/faction.c @@ -305,7 +305,7 @@ destroyfaction(faction * f) /* units of other factions that were disguised as this faction * have their disguise replaced by ordinary faction hiding. */ - for(rc=regions; rc; rc=rc->next) { + for (rc=regions; rc; rc=rc->next) { for(u=rc->units; u; u=u->next) { attrib *a = a_find(u->attribs, &at_otherfaction); if(!a) continue; diff --git a/src/common/kernel/group.c b/src/common/kernel/group.c index 26bf83bd3..49125db94 100644 --- a/src/common/kernel/group.c +++ b/src/common/kernel/group.c @@ -131,12 +131,18 @@ free_group(group * g) boolean join_group(unit * u, const char * name) { - attrib * a = a_find(u->attribs, &at_group); + attrib * a = NULL; group * g; + if (fval(u, UFL_GROUP)) { + a = a_find(u->attribs, &at_group); + } if (a) ((group *)(a->data.v))->members--; if (!name || !strlen(name)) { - if (a) a_remove(&u->attribs, a); + if (a) { + a_remove(&u->attribs, a); + freset(u, UFL_GROUP); + } return true; } g = find_groupbyname(u->faction->groups, name); @@ -144,7 +150,10 @@ join_group(unit * u, const char * name) g = new_group(u->faction, name, ++maxgid); init_group(u->faction, g); } - if (!a) a = a_add(&u->attribs, a_new(&at_group)); + if (!a) { + a = a_add(&u->attribs, a_new(&at_group)); + fset(u, UFL_GROUP); + } a->data.v = g; g->members++; return true; diff --git a/src/common/kernel/karma.c b/src/common/kernel/karma.c index 80e6eb39e..173053332 100644 --- a/src/common/kernel/karma.c +++ b/src/common/kernel/karma.c @@ -559,7 +559,6 @@ jihad_attacks(void) faction *f; region *r; unit *u, *u2; - attrib *a; ally *sf, **sfp; for(f=factions; f; f=f->next) if(fspecial(f, FS_JIHAD)) { @@ -580,8 +579,10 @@ jihad_attacks(void) for(u=r->units; u; u=u->next) if(jihad(f, u->race)) { /* Allianz auflösen */ sfp = &u2->faction->allies; - a = a_find(u2->attribs, &at_group); - if (a) sfp = &((group*)a->data.v)->allies; + if (fval(u, UFL_GROUP)) { + attrib * a = a_find(u2->attribs, &at_group); + if (a) sfp = &((group*)a->data.v)->allies; + } for (sf=*sfp; sf; sf = sf->next) { if(sf->faction == u->faction) break; diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index 1ea716ce5..cbbbe7642 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -314,10 +314,12 @@ rc_name(const race * rc, int n) const char * raceprefix(const unit *u) { - const attrib * agroup = a_findc(u->attribs, &at_group); const attrib * asource = u->faction->attribs; - if (agroup!=NULL) asource = ((const group *)(agroup->data.v))->attribs; + if (fval(u, UFL_GROUP)) { + const attrib * agroup = agroup = a_findc(u->attribs, &at_group); + if (agroup!=NULL) asource = ((const group *)(agroup->data.v))->attribs; + } return get_prefix(asource); } diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index 024acfc61..e6cac9d86 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -207,11 +207,13 @@ bufunit(const faction * f, const unit * u, int indent, int mode) if (!isbattle) { attrib *a_otherfaction = a_find(u->attribs, &at_otherfaction); if (u->faction == f) { - attrib *a = a_find(u->attribs, &at_group); - if (a) { - group * g = (group*)a->data.v; - bufp += strlcpy(bufp, ", ", sizeof(buf)-(bufp-buf)); - bufp += strlcpy(bufp, groupid(g, f), sizeof(buf)-(bufp-buf)); + if (fval(u, UFL_GROUP)) { + attrib *a = a_find(u->attribs, &at_group); + if (a) { + group * g = (group*)a->data.v; + bufp += strlcpy(bufp, ", ", sizeof(buf)-(bufp-buf)); + bufp += strlcpy(bufp, groupid(g, f), sizeof(buf)-(bufp-buf)); + } } if (getarnt) { bufp += strlcpy(bufp, ", ", sizeof(buf)-(bufp-buf)); @@ -559,7 +561,7 @@ bufunit_ugroupleader(const faction * f, const unit * u, int indent, int mode) show = NULL; for(i = 0; i < ug->members; i++) { unit *uc = ug->unit_array[i]; - if(!itemcloak && mode >= see_unit && !(a_fshidden + if (!itemcloak && mode >= see_unit && !(a_fshidden && a_fshidden->data.ca[1] == 1 && effskill(u, SK_STEALTH) >= 3)) { for (itm=uc->items;itm;itm=itm->next) { item *ishow; @@ -656,7 +658,7 @@ spskill(char * buffer, size_t siz, const struct locale * lang, const struct unit } } - if (sk == SK_STEALTH) { + if (sk == SK_STEALTH && fval(u, UFL_STEALTH)) { i = u_geteffstealth(u); if(i>=0) { bufp += sprintf(bufp, "%d/", i); diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index 306a43162..4db9795e2 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -488,17 +488,32 @@ attrib_type at_stealth = { void u_seteffstealth(unit * u, int value) { - attrib * a = a_find(u->attribs, &at_stealth); - if (!a && value<0) return; - if (!a) a = a_add(&u->attribs, a_new(&at_stealth)); + attrib * a = NULL; + if (fval(u, UFL_STEALTH)) { + a = a_find(u->attribs, &at_stealth); + } + if (value<0) { + if (a!=NULL) { + freset(u, UFL_STEALTH); + a_remove(&u->attribs, a); + } + return; + } + if (a==NULL) { + a = a_add(&u->attribs, a_new(&at_stealth)); + fset(u, UFL_STEALTH); + } a->data.i = value; } int u_geteffstealth(const struct unit * u) { - attrib * a = a_find(u->attribs, &at_stealth); - return (a?a->data.i:-1); + if (fval(u, UFL_STEALTH)) { + attrib * a = a_find(u->attribs, &at_stealth); + if (a!=NULL) return a->data.i; + } + return -1; } int diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index 55b11a9f5..57a308a9b 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -58,13 +58,15 @@ struct skill; #define UFL_TAKEALL (1<<25) /* Einheit nimmt alle Gegenstände an */ /* flags that speed up attribute access: */ +#define UFL_STEALTH (1<<26) #define UFL_GUARD (1<<27) +#define UFL_GROUP (1<<28) /* Flags, die gespeichert werden sollen: */ #ifndef HEROES -# define UFL_SAVEMASK (UFL_MOVED | UFL_NOAID | UFL_OWNER | UFL_PARTEITARNUNG | UFL_LOCKED | UFL_HUNGER | UFL_TAKEALL | UFL_GUARD) +# define UFL_SAVEMASK (UFL_MOVED | UFL_NOAID | UFL_OWNER | UFL_PARTEITARNUNG | UFL_LOCKED | UFL_HUNGER | UFL_TAKEALL | UFL_GUARD | UFL_STEALTH) #else -# define UFL_SAVEMASK (UFL_MOVED | UFL_NOAID | UFL_OWNER | UFL_PARTEITARNUNG | UFL_LOCKED | UFL_HUNGER | UFL_TAKEALL | UFL_GUARD | UFL_HERO) +# define UFL_SAVEMASK (UFL_MOVED | UFL_NOAID | UFL_OWNER | UFL_PARTEITARNUNG | UFL_LOCKED | UFL_HUNGER | UFL_TAKEALL | UFL_GUARD | UFL_STEALTH | UFL_HERO) #endif #define UNIT_MAXSIZE 50000 diff --git a/src/eressea/korrektur.c b/src/eressea/korrektur.c index 3230e07c1..8c0a9c313 100644 --- a/src/eressea/korrektur.c +++ b/src/eressea/korrektur.c @@ -1023,7 +1023,12 @@ fix_attribflags(void) while (a) { if (a->type==&at_guard) { fset(u, UFL_GUARD); - break; + } + else if (a->type==&at_group) { + fset(u, UFL_GROUP); + } + else if (a->type==&at_stealth) { + fset(u, UFL_STEALTH); } a = a->next; } @@ -1071,7 +1076,7 @@ korrektur(void) } do_once("chgt", fix_chaosgates()); - do_once("attr", fix_attribflags()); + do_once("atri", fix_attribflags()); fix_astralplane(); fix_firewalls(); fix_gates();