diff --git a/src/common/attributes/follow.c b/src/common/attributes/follow.c index be11c0f0a..aa43f9f87 100644 --- a/src/common/attributes/follow.c +++ b/src/common/attributes/follow.c @@ -30,39 +30,21 @@ verify_follow(attrib * a) return 1; } -#define FOLLOW_PERSISTENT 0 - -#if FOLLOW_PERSISTENT -static void -write_follow(const attrib * a, FILE * F) -{ - write_unit_reference((unit*)a->data.v, F); -} -#else -#define write_follow NULL -#endif - static int read_follow(attrib * a, FILE * F) { if (global.data_version < BASE36IDS_VERSION) { int i; fscanf(F, "%d", &i); -#if FOLLOW_PERSISTENT ur_add((void*)i, (void**)&a->data.v, resolve_unit); -#endif } else { -#if FOLLOW_PERSISTENT - read_unit_reference((unit**)&a->data.v, F); -#else - read_unit_reference(NULL, F); -#endif + return read_unit_reference(NULL, F); } - return FOLLOW_PERSISTENT; + return AT_READ_OK; } attrib_type at_follow = { - "follow", NULL, NULL, verify_follow, write_follow, read_follow + "follow", NULL, NULL, verify_follow, NULL, read_follow }; attrib * diff --git a/src/common/attributes/giveitem.c b/src/common/attributes/giveitem.c index eac1bddd3..02f0ebe87 100644 --- a/src/common/attributes/giveitem.c +++ b/src/common/attributes/giveitem.c @@ -68,7 +68,7 @@ a_readgive(attrib * a, FILE * F) fscanf(F, "%d", &i); if (i==0) i_add(&gdata->items, i_new(it_find(zText), i)); } - return 1; + return AT_READ_OK; } static void diff --git a/src/common/attributes/gm.c b/src/common/attributes/gm.c index 4a4ea7b8b..c39739cdb 100644 --- a/src/common/attributes/gm.c +++ b/src/common/attributes/gm.c @@ -31,8 +31,7 @@ write_gm(const attrib * a, FILE * F) static int read_gm(attrib * a, FILE * F) { - read_plane_reference((plane**)&a->data.v, F); - return 1; + return read_plane_reference((plane**)&a->data.v, F); } diff --git a/src/common/attributes/hate.c b/src/common/attributes/hate.c index c20960b90..eccf503da 100644 --- a/src/common/attributes/hate.c +++ b/src/common/attributes/hate.c @@ -44,9 +44,9 @@ read_hate(attrib * a, FILE * F) fscanf(F, "%d", &i); ur_add((void*)i, (void**)&a->data.v, resolve_unit); } else { - read_unit_reference((unit**)&a->data.v, F); + return read_unit_reference((unit**)&a->data.v, F); } - return 1; + return AT_READ_OK; } attrib_type at_hate = { diff --git a/src/common/attributes/moved.c b/src/common/attributes/moved.c index e11eafbae..883fc1308 100644 --- a/src/common/attributes/moved.c +++ b/src/common/attributes/moved.c @@ -34,7 +34,8 @@ static int read_moved(attrib * a, FILE * F) { fscanf(F, "%d", &a->data.i); - return a->data.i!=0; + if (a->data.i!=0) return AT_READ_OK; + else return AT_READ_FAIL; } attrib_type at_moved = { diff --git a/src/common/attributes/otherfaction.c b/src/common/attributes/otherfaction.c index 7a9f9c45d..b0108b8f7 100644 --- a/src/common/attributes/otherfaction.c +++ b/src/common/attributes/otherfaction.c @@ -36,8 +36,8 @@ read_of(struct attrib * a, FILE* F) /* return 1 on success, 0 if attrib needs re int of; fscanf(F, "%d", &of); a->data.v = findfaction(of); - if (a->data.v) return 1; - return 0; + if (a->data.v) return AT_READ_OK; + return AT_READ_FAIL; } attrib_type at_otherfaction = { diff --git a/src/common/attributes/synonym.c b/src/common/attributes/synonym.c index 230a8a319..34c01c5d7 100644 --- a/src/common/attributes/synonym.c +++ b/src/common/attributes/synonym.c @@ -71,7 +71,7 @@ a_readsynonym(attrib * a, FILE * F) fscanf(F, "%s", lbuf); frs->synonyms[3] = strdup(lbuf); - return 1; + return AT_READ_OK; } attrib_type at_synonym = { diff --git a/src/common/attributes/targetregion.c b/src/common/attributes/targetregion.c index e234d0510..ea0797612 100644 --- a/src/common/attributes/targetregion.c +++ b/src/common/attributes/targetregion.c @@ -34,9 +34,9 @@ read_targetregion(attrib * a, FILE * F) a_readdefault(a, F); a->data.v = findregion(a->data.sa[0], a->data.sa[1]); } else { - read_region_reference((region**)&a->data.v, F); + return read_region_reference((region**)&a->data.v, F); } - return 1; + return AT_READ_OK; } attrib_type at_targetregion = { diff --git a/src/common/attributes/viewrange.c b/src/common/attributes/viewrange.c index 2fbe4f15f..f039d4199 100644 --- a/src/common/attributes/viewrange.c +++ b/src/common/attributes/viewrange.c @@ -35,7 +35,7 @@ a_readfunction(struct attrib *a, FILE *F) char buf[64]; fscanf(F, "%s ", buf); a->data.f = get_function(buf); - return 1; + return AT_READ_OK; } attrib_type at_viewrange = { diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index eebd64ffc..ec931df8e 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -834,6 +834,53 @@ report_resource(char * buf, const char * name, const locale * loc, int amount, i return buf; } +static void +cr_borders(const region * r, const faction * f, int seemode, FILE * F) +{ + direction_t d; + int g = 0; + for (d = 0; d != MAXDIRECTIONS; d++) + { /* Nachbarregionen, die gesehen werden, ermitteln */ + const region * r2 = rconnect(r, d); + const border * b; + if (!r2) continue; + if (seemode==see_neighbour) { + seen_region * sr = find_seen(r2); + if (sr==NULL || sr->mode<=see_neighbour) continue; + } + b = get_borders(r, r2); + while (b) { + boolean cs = b->type->fvisible(b, f, r); + + if (!cs) { + cs = b->type->rvisible(b, r); + if (!cs) { + unit * us = r->units; + while (us && !cs) { + if (us->faction==f) { + cs = b->type->uvisible(b, us); + if (cs) break; + } + us=us->next; + } + } + } + if (cs) { + fprintf(F, "GRENZE %d\n", ++g); + fprintf(F, "\"%s\";typ\n", b->type->name(b, r, f, GF_NONE)); + fprintf(F, "%d;richtung\n", d); + if (!b->type->transparent(b, f)) fputs("1;opaque\n", F); + /* pfusch: */ + if (b->type==&bt_road) { + int p = rroad(r, d)*100/terrain[rterrain(r)].roadreq; + fprintf(F, "%d;prozent\n", p); + } + } + b = b->next; + } + } +} + /* main function of the creport. creates the header and traverses all regions */ void report_computer(FILE * F, faction * f, const seen_region * seen, @@ -989,12 +1036,11 @@ report_computer(FILE * F, faction * f, const seen_region * seen, fputs("\"travel\";visibility\n", F); break; } - if (seemode != see_neighbour) - { + if (seemode == see_neighbour) { + cr_borders(r, f, seemode, F); + } else { #define RESOURCECOMPAT char cbuf[8192], *pos = cbuf; - int g = 0; - direction_t d; #ifdef RESOURCECOMPAT if (r->display && strlen(r->display)) fprintf(F, "\"%s\";Beschr\n", r->display); @@ -1120,42 +1166,7 @@ report_computer(FILE * F, faction * f, const seen_region * seen, } if (pos!=cbuf) fputs(cbuf, F); } - for (d = 0; d != MAXDIRECTIONS; d++) - { /* Nachbarregionen, die gesehen werden, ermitteln */ - region * r2 = rconnect(r, d); - border * b; - if (!r2) continue; - b = get_borders(r, r2); - while (b) { - boolean cs = b->type->fvisible(b, f, r); - - if (!cs) { - cs = b->type->rvisible(b, r); - if (!cs) { - unit * us = r->units; - while (us && !cs) { - if (us->faction==f) { - cs = b->type->uvisible(b, us); - if (cs) break; - } - us=us->next; - } - } - } - if (cs) { - fprintf(F, "GRENZE %d\n", ++g); - fprintf(F, "\"%s\";typ\n", b->type->name(b, r, f, GF_NONE)); - fprintf(F, "%d;richtung\n", d); - if (!b->type->transparent(b, f)) fputs("1;opaque\n", F); - /* pfusch: */ - if (b->type==&bt_road) { - int p = rroad(r, d)*100/terrain[rterrain(r)].roadreq; - fprintf(F, "%d;prozent\n", p); - } - } - b = b->next; - } - } + cr_borders(r, f, seemode, F); if (seemode==see_unit && r->planep && r->planep->id == 1 && !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) { /* Sonderbehandlung Teleport-Ebene */ diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index 74163a148..477db36a1 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -888,7 +888,7 @@ f_regionid(const region * r, const faction * f) } static void -prices(FILE * F, region * r, faction * f) +prices(FILE * F, const region * r, const faction * f) { const luxury_type *sale=NULL; struct demand * dmd; @@ -928,13 +928,13 @@ extern const direction_t back[MAXDIRECTIONS]; /* ------------------------------------------------------------- */ boolean -see_border(border * b, faction * f, region * r) +see_border(const border * b, const faction * f, const region * r) { boolean cs = b->type->fvisible(b, f, r); if (!cs) { cs = b->type->rvisible(b, r); if (!cs) { - unit * us = r->units; + const unit * us = r->units; while (us && !cs) { if (us->faction==f) { cs = b->type->uvisible(b, us); @@ -984,7 +984,7 @@ eval_trail(struct opstack ** stack, const void * userdata) /* (int, int) -> int } static void -describe(FILE * F, region * r, int partial, faction * f) +describe(FILE * F, const region * r, int partial, faction * f) { char dbuf[512]; int n; @@ -1321,9 +1321,9 @@ describe(FILE * F, region * r, int partial, faction * f) } void -statistics(FILE * F, region * r, faction * f) +statistics(FILE * F, const region * r, const faction * f) { - unit *u; + const unit *u; int number, p; item *itm, *items = NULL; p = rpeasants(r); @@ -1379,7 +1379,7 @@ statistics(FILE * F, region * r, faction * f) } static void -durchreisende(FILE * F, region * r, faction * f) +durchreisende(FILE * F, const region * r, const faction * f) { attrib *ru; int wieviele; @@ -1657,7 +1657,7 @@ allies(FILE * F, faction * f) } static void -guards(FILE * F, region * r, faction * see) +guards(FILE * F, const region * r, const faction * see) { /* die Partei see sieht dies; wegen * "unbekannte Partei", wenn man es selbst ist... */ @@ -1812,7 +1812,7 @@ report(FILE *F, faction * f, const faction_list * addresses, char ch; int dh; int anyunits; - region *r; + const struct region *r; building *b; ship *sh; unit *u; @@ -2536,45 +2536,46 @@ init_intervals() } #endif -static boolean -add_seen(region * r, unsigned char mode, boolean dis) +seen_region * +find_seen(const region * r) { - seen_region * find; - int index = abs((r->x & 0xffff) + ((r->y) << 16)) % MAXSEEHASH; - for (find=seehash[index];find;find=find->nextHash) { - if (find->r==r) { - if (find->mode < mode) { - if (find->mode<=see_neighbour && find->next) { - find->next->prev = find->prev; - if (find->prev) find->prev->next = find->next; - else seen = find->next; - last->next = find; - find->prev = last; - find->next = NULL; - last = find; - append = &last->next; - } - find->mode = mode; - find->disbelieves |= dis; - return true; - } - else return false; - } + seen_region * find=seehash[index]; + while (find) { + if (find->r==r) return find; + find=find->nextHash; } - if (!reuse) reuse = (seen_region*)calloc(1, sizeof(seen_region)); - *append = reuse; - reuse = reuse->next; - (*append)->next = NULL; - (*append)->prev = last; - if (last) last->next = *append; - last = *append; - (*append)->nextHash = seehash[index]; - seehash[index] = *append; - (*append)->r = r; - (*append)->mode = mode; - (*append)->disbelieves = dis; - append = &(*append)->next; + return NULL; +} + +static boolean +add_seen(const struct region * r, unsigned char mode, boolean dis) +{ + seen_region * find = find_seen(r); + if (find) { + if (find->mode >= mode) return false; + if (find->mode>see_neighbour || find->next==NULL) return true; + /* take it out the list, so it can get processed again */ + find->next->prev = find->prev; + if (find->prev) find->prev->next = find->next; + else seen = find->next; + } else { + int index = abs((r->x & 0xffff) + ((r->y) << 16)) % MAXSEEHASH; + if (!reuse) reuse = (seen_region*)calloc(1, sizeof(seen_region)); + *append = find = reuse; + reuse = reuse->next; + find->nextHash = seehash[index]; + seehash[index] = find; + find->r = r; + } + /* put it at the end of the list, where the unprocessed nodes are */ + if (last) last->next = find; + find->next = NULL; + find->prev = last; + last = find; + append = &last->next; + find->mode = mode; + find->disbelieves |= dis; return true; } @@ -2591,6 +2592,10 @@ view_default(region *r, faction *f) region * r2 = rconnect(r, dir); if (r2) { border * b = get_borders(r, r2); + while (b) { + if (!b->type->transparent(b, f)) break; + b = b->next; + } if (!b) add_seen(r2, see_neighbour, false); } } diff --git a/src/common/items/weapons.c b/src/common/items/weapons.c index 81058ab6d..efbf8dee1 100644 --- a/src/common/items/weapons.c +++ b/src/common/items/weapons.c @@ -158,7 +158,7 @@ attack_firesword(const troop * at, int *casualties, int row) int force = 1+rand()%10; if (row==FIGHT_ROW) { - enemies = count_enemies(fi->side, FS_ENEMY, + enemies = count_enemies(fi->side->battle, fi->side, FS_ENEMY, minrow, maxrow); } if (!enemies) { @@ -178,7 +178,7 @@ attack_firesword(const troop * at, int *casualties, int row) } do { - dt = select_enemy(fi, minrow, maxrow); + dt = select_enemy(fi->side->battle, fi, minrow, maxrow); assert(dt.fighter); --force; killed += terminate(dt, *at, AT_SPELL, damage, 1); @@ -215,11 +215,11 @@ attack_catapult(const troop * at, int * casualties, int row) } minrow = FIGHT_ROW; maxrow = FIGHT_ROW; - n = min(10, count_enemies(af->side, FS_ENEMY, minrow, maxrow)); + n = min(10, count_enemies(b, af->side, FS_ENEMY, minrow, maxrow)); while (--n >= 0) { /* Select defender */ - dt = select_enemy(af, minrow, maxrow); + dt = select_enemy(b, af, minrow, maxrow); if (!dt.fighter) break; diff --git a/src/common/kernel/alchemy.c b/src/common/kernel/alchemy.c index 174f04f47..34f384a34 100644 --- a/src/common/kernel/alchemy.c +++ b/src/common/kernel/alchemy.c @@ -197,7 +197,7 @@ a_readeffect(attrib *a, FILE *f) if (ptype==NULL || power==0) return 0; edata->type = ptype; edata->value = power; - return 1; + return AT_READ_OK; } attrib_type at_effect = { diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 2f61cf259..ebef64f22 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -1241,10 +1241,9 @@ lovar(int n) /* ------------------------------------------------------------- */ int -count_enemies(side * as, int mask, int minrow, int maxrow) +count_enemies(battle * b, side * as, int mask, int minrow, int maxrow) /* new implementation of count_enemies ignores mask, since it was never used */ { - battle *b = as->battle; int i = 0; void **si; @@ -1252,7 +1251,7 @@ count_enemies(side * as, int mask, int minrow, int maxrow) for (si = b->sides.begin; si != b->sides.end; ++si) { side *side = *si; - if (enemy(side, as)) + if (as==NULL || enemy(side, as)) { void **fi; @@ -1275,15 +1274,14 @@ count_enemies(side * as, int mask, int minrow, int maxrow) /* ------------------------------------------------------------- */ troop -select_enemy(fighter * af, int minrow, int maxrow) +select_enemy(battle * b, fighter * af, int minrow, int maxrow) { - side *as = af->side; - battle *b = as->battle; + side *as = af?af->side:NULL; troop dt = no_troop; void ** si; int enemies; - if(af->unit->race->flags & RCF_FLY) { + if (af && af->unit->race->flags & RCF_FLY) { /* flying races ignore min- and maxrow and can attack anyone fighting * them */ minrow = FIGHT_ROW; @@ -1291,7 +1289,7 @@ select_enemy(fighter * af, int minrow, int maxrow) } minrow = max(minrow, FIGHT_ROW); - enemies = count_enemies(af->side, FS_ENEMY, minrow, maxrow); + enemies = count_enemies(b, as, FS_ENEMY, minrow, maxrow); if (!enemies) return dt; /* Niemand ist in der angegebenen Entfernung */ @@ -1299,7 +1297,7 @@ select_enemy(fighter * af, int minrow, int maxrow) for (si=b->sides.begin;!dt.fighter && si!=b->sides.end;++si) { side *ds = *si; void ** fi; - if (!enemy(as, ds)) continue; + if (as!=NULL && !enemy(as, ds)) continue; for (fi=ds->fighters.begin;fi!=ds->fighters.end;++fi) { fighter * df = *fi; int dr = get_unitrow(df); @@ -1892,11 +1890,11 @@ attack(battle *b, troop ta, const att *a) boolean missile = false; if (wp && fval(wp->type, WTF_MISSILE)) missile=true; if (missile) { - if (row<=BEHIND_ROW) td = select_enemy(af, missile_range[0], missile_range[1]); + if (row<=BEHIND_ROW) td = select_enemy(b, af, missile_range[0], missile_range[1]); else return; } else { - if (row<=FIGHT_ROW) td = select_enemy(af, melee_range[0], melee_range[1]); + if (row<=FIGHT_ROW) td = select_enemy(b, af, melee_range[0], melee_range[1]); else return; } if (!td.fighter) return; @@ -1930,7 +1928,7 @@ attack(battle *b, troop ta, const att *a) do_extra_spell(ta, a); break; case AT_NATURAL: - td = select_enemy(af, melee_range[0]-offset, melee_range[1]-offset); + td = select_enemy(b, af, melee_range[0]-offset, melee_range[1]-offset); if (!td.fighter) return; if(td.fighter->person[td.index].last_action < b->turn) { td.fighter->person[td.index].last_action = b->turn; @@ -1945,7 +1943,7 @@ attack(battle *b, troop ta, const att *a) } break; case AT_DRAIN_ST: - td = select_enemy(af, melee_range[0]-offset, melee_range[1]-offset); + td = select_enemy(b, af, melee_range[0]-offset, melee_range[1]-offset); if (!td.fighter) return; if(td.fighter->person[td.index].last_action < b->turn) { td.fighter->person[td.index].last_action = b->turn; @@ -1968,7 +1966,7 @@ attack(battle *b, troop ta, const att *a) } break; case AT_DRAIN_EXP: - td = select_enemy(af, melee_range[0]-offset, melee_range[1]-offset); + td = select_enemy(b, af, melee_range[0]-offset, melee_range[1]-offset); if (!td.fighter) return; if(td.fighter->person[td.index].last_action < b->turn) { td.fighter->person[td.index].last_action = b->turn; @@ -1983,7 +1981,7 @@ attack(battle *b, troop ta, const att *a) } break; case AT_DAZZLE: - td = select_enemy(af, melee_range[0]-offset, melee_range[1]-offset); + td = select_enemy(b, af, melee_range[0]-offset, melee_range[1]-offset); if (!td.fighter) return; if(td.fighter->person[td.index].last_action < b->turn) { td.fighter->person[td.index].last_action = b->turn; @@ -1998,7 +1996,7 @@ attack(battle *b, troop ta, const att *a) } break; case AT_STRUCTURAL: - td = select_enemy(af, melee_range[0]-offset, melee_range[1]-offset); + td = select_enemy(b, af, melee_range[0]-offset, melee_range[1]-offset); if (!td.fighter) return; if(ta.fighter->person[ta.index].last_action < b->turn) { ta.fighter->person[ta.index].last_action = b->turn; @@ -2045,7 +2043,7 @@ do_attack(fighter * af) while (ta.index--) { /* Wir suchen eine beliebige Feind-Einheit aus. An der können * wir feststellen, ob noch jemand da ist. */ - int enemies = count_enemies(af->side, FS_ENEMY, FIGHT_ROW, LAST_ROW); + int enemies = count_enemies(b, af->side, FS_ENEMY, FIGHT_ROW, LAST_ROW); if (!enemies) break; for (apr=attacks_per_round(ta); apr > 0; apr--) { @@ -2144,6 +2142,7 @@ loot_items(fighter * corpse) { unit * u = corpse->unit; item * itm = u->items; + battle * b = corpse->side->battle; u->items = NULL; while (itm) { @@ -2160,7 +2159,7 @@ loot_items(fighter * corpse) */ if (loot>0 && (itm->type->flags & (ITF_CURSED|ITF_NOTLOST) || rand()%100 >= 50 - corpse->side->battle->keeploot)) { - fighter *fig = select_enemy(corpse, FIGHT_ROW, LAST_ROW).fighter; + fighter *fig = select_enemy(b, corpse, FIGHT_ROW, LAST_ROW).fighter; if (fig) { item * l = fig->loot; while (l && l->type!=itm->type) l=l->next; diff --git a/src/common/kernel/battle.h b/src/common/kernel/battle.h index f6d5e8183..9e9f87097 100644 --- a/src/common/kernel/battle.h +++ b/src/common/kernel/battle.h @@ -209,8 +209,8 @@ extern void do_battle(void); /* for combar spells and special attacks */ extern int damage_unit(struct unit *u, const char *dam, boolean armor, boolean magic); -extern troop select_enemy(struct fighter * af, int minrow, int maxrow); -extern int count_enemies(struct side * as, int mask, int minrow, int maxrow); +extern troop select_enemy(struct battle * b, struct fighter * af, int minrow, int maxrow); +extern int count_enemies(struct battle * b, struct side * as, int mask, int minrow, int maxrow); extern boolean terminate(troop dt, troop at, int type, const char *damage, boolean missile); extern void battlemsg(battle * b, struct unit * u, const char * s); extern void battlerecord(battle * b, const char *s); diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index 83e65ddd9..521bffc80 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -530,12 +530,12 @@ read_building_reference(struct building ** b, FILE * F) id = atoi36(zText); if (id==0) { *b = NULL; - return 0; + return AT_READ_FAIL; } else { *b = findbuilding(id); if (*b==NULL) ur_add((void*)id, (void**)b, resolve_building); - return 1; + return AT_READ_OK; } } diff --git a/src/common/kernel/combatspells.c b/src/common/kernel/combatspells.c index 70fd88aa7..fd019bde0 100644 --- a/src/common/kernel/combatspells.c +++ b/src/common/kernel/combatspells.c @@ -134,7 +134,7 @@ sp_kampfzauber(fighter * fi, int level, int power, spell * sp) force = lovar(get_force(power,10)); } - enemies = count_enemies(fi->side, FS_ENEMY, + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { scat(", aber niemand war in Reichweite."); @@ -145,7 +145,7 @@ sp_kampfzauber(fighter * fi, int level, int power, spell * sp) battlerecord(b, buf); do { - dt = select_enemy(fi, minrow, maxrow); + dt = select_enemy(b, fi, minrow, maxrow); assert(dt.fighter); --force; killed += terminate(dt, at, AT_COMBATSPELL, damage, false); @@ -175,7 +175,7 @@ sp_versteinern(fighter * fi, int level, int power, spell * sp) force = lovar(get_force(power,0)); - enemies = count_enemies(fi->side, FS_ENEMY, + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { scat(", aber niemand war in Reichweite."); @@ -186,7 +186,7 @@ sp_versteinern(fighter * fi, int level, int power, spell * sp) battlerecord(b, buf); do { - troop dt = select_enemy(fi, minrow, maxrow); + troop dt = select_enemy(b, fi, minrow, maxrow); fighter * df = dt.fighter; unit * du = df->unit; if (is_magic_resistant(mage, du, 0) == false) { @@ -234,7 +234,7 @@ sp_stun(fighter * fi, int level, int power, spell * sp) assert(0); } - enemies = count_enemies(fi->side, FS_ENEMY, minrow, maxrow); + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { scat(", aber niemand war in Reichweite."); battlerecord(b, buf); @@ -245,7 +245,7 @@ sp_stun(fighter * fi, int level, int power, spell * sp) stunned = 0; do { - troop dt = select_enemy(fi, minrow, maxrow); + troop dt = select_enemy(b, fi, minrow, maxrow); fighter * df = dt.fighter; unit * du = df->unit; @@ -290,7 +290,7 @@ sp_combatrosthauch(fighter * fi, int level, int power, spell * sp) force = lovar(power * 15); - enemies = count_enemies(fi->side, FS_ENEMY, minrow, maxrow); + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { battlemsg(b, fi->unit, msgt[0]); return 0; @@ -376,7 +376,7 @@ sp_sleep(fighter * fi, int level, int power, spell * sp) sprintf(buf, "%s zaubert %s", unitname(mage), sp->name); force = lovar(power * 25); - enemies = count_enemies(fi->side, FS_ENEMY, minrow, maxrow); + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { scat(", aber niemand war in Reichweite."); @@ -387,7 +387,7 @@ sp_sleep(fighter * fi, int level, int power, spell * sp) battlerecord(b, buf); do { - dt = select_enemy(fi, minrow, maxrow); + dt = select_enemy(b, fi, minrow, maxrow); assert(dt.fighter); du = dt.fighter->unit; if (is_magic_resistant(mage, du, 0) == false) { @@ -522,7 +522,7 @@ sp_mindblast(fighter * fi, int level, int power, spell * sp) sprintf(buf, "%s zaubert %s", unitname(mage), sp->name); force = lovar(power * 25); - enemies = count_enemies(fi->side, FS_ENEMY, minrow, maxrow); + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { scat(", aber niemand war in Reichweite."); battlerecord(b, buf); @@ -532,7 +532,7 @@ sp_mindblast(fighter * fi, int level, int power, spell * sp) battlerecord(b, buf); do { - dt = select_enemy(fi, minrow, maxrow); + dt = select_enemy(b, fi, minrow, maxrow); assert(dt.fighter); du = dt.fighter->unit; if (humanoidrace(du->race) && is_magic_resistant(mage, du, 0) == false) { @@ -606,7 +606,7 @@ sp_dragonodem(fighter * fi, int level, int power, spell * sp) /* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */ force = lovar(get_force(level,6)); - enemies = count_enemies(fi->side, FS_ENEMY, minrow, + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { @@ -621,7 +621,7 @@ sp_dragonodem(fighter * fi, int level, int power, spell * sp) at.index = 0; do { - dt = select_enemy(fi, minrow, maxrow); + dt = select_enemy(b, fi, minrow, maxrow); assert(dt.fighter); --force; killed += terminate(dt, at, AT_COMBATSPELL, damage, false); @@ -655,7 +655,7 @@ sp_drainodem(fighter * fi, int level, int power, spell * sp) /* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */ force = lovar(get_force(level,6)); - enemies = count_enemies(fi->side, FS_ENEMY, minrow, + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { @@ -670,7 +670,7 @@ sp_drainodem(fighter * fi, int level, int power, spell * sp) at.index = 0; do { - dt = select_enemy(fi, minrow, maxrow); + dt = select_enemy(b, fi, minrow, maxrow); assert(dt.fighter); if (hits(at, dt, NULL)) { drain_exp(dt.fighter->unit, 90); @@ -864,7 +864,7 @@ sp_chaosrow(fighter * fi, int level, int force, spell * sp) break; } - enemies = count_enemies(fi->side, FS_ENEMY, minrow, maxrow); + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { scat(", aber niemand war in Reichweite."); battlerecord(b, buf); @@ -964,7 +964,7 @@ sp_flee(fighter * fi, int level, int power, spell * sp) force = get_force(power,10); } - if (!count_enemies(fi->side, FS_ENEMY, minrow, maxrow)) { + if (!count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow)) { scat(", aber es gab niemanden mehr, der beeinflusst werden konnte."); battlerecord(b, buf); return 0; @@ -1140,7 +1140,7 @@ sp_frighten(fighter * fi, int level, int power, spell * sp) force = get_force(power, 2); sprintf(buf, "%s zaubert %s", unitname(mage), sp->name); - enemies = count_enemies(fi->side, FS_ENEMY, + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { scat(", aber niemand war in Reichweite."); @@ -1151,7 +1151,7 @@ sp_frighten(fighter * fi, int level, int power, spell * sp) battlerecord(b, buf); do { - troop dt = select_enemy(fi, minrow, maxrow); + troop dt = select_enemy(b, fi, minrow, maxrow); fighter *df = dt.fighter; --enemies; @@ -1190,7 +1190,7 @@ sp_tiredsoldiers(fighter * fi, int level, int force, spell * sp) force = force * force * 4; sprintf(buf, "%s zaubert %s", unitname(mage), sp->name); - if (!count_enemies(fi->side, FS_ENEMY, FIGHT_ROW, + if (!count_enemies(b, fi->side, FS_ENEMY, FIGHT_ROW, BEHIND_ROW)) { scat(", aber niemand war in Reichweite."); battlerecord(b, buf); @@ -1198,7 +1198,7 @@ sp_tiredsoldiers(fighter * fi, int level, int force, spell * sp) } while (force) { - troop t = select_enemy(fi, FIGHT_ROW, BEHIND_ROW); + troop t = select_enemy(b, fi, FIGHT_ROW, BEHIND_ROW); fighter *df = t.fighter; if (!df) @@ -1250,7 +1250,7 @@ sp_windshield(fighter * fi, int level, int power, spell * sp) force = power; at_malus = 2; } - enemies = count_enemies(fi->side, FS_ENEMY, + enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow); if (!enemies) { scat(", aber niemand war in Reichweite."); @@ -1259,7 +1259,7 @@ sp_windshield(fighter * fi, int level, int power, spell * sp) } do { - troop dt = select_enemy(fi, minrow, maxrow); + troop dt = select_enemy(b, fi, minrow, maxrow); fighter *df = dt.fighter; --enemies; diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 29a969ccc..a71c4de12 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -2366,9 +2366,12 @@ remove_empty_factions(void) } fprintf(sqlstream, "UPDATE subscriptions set status='DEAD' where " "faction='%s' and game=%d;", itoa36(f->no), GAME_ID); - stripfaction(f); + *fp = f->next; - free(f); +/* stripfaction(f); + * free(f); + * Wir können die nicht löschen, weil sie evtl. noch in attributen + * referenziert sind ! */ } else fp = &(*fp)->next; } diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index b43c28e4a..7c80c5c8e 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -855,7 +855,6 @@ extern int max_unique_id; #define FL_PARTEITARNUNG (1<<4) /* 16 */ #define FL_DISBELIEVES (1<<5) /* 32 */ #define FL_WARMTH (1<<6) /* 64 */ -#define FL_TRAVELTHRU (1<<7) /* 128 */ #define FL_MOVED (1<<8) #define FL_FOLLOWING (1<<9) diff --git a/src/common/kernel/group.c b/src/common/kernel/group.c index c7a988b45..784b9d168 100644 --- a/src/common/kernel/group.c +++ b/src/common/kernel/group.c @@ -99,9 +99,9 @@ read_group(attrib * a, FILE * f) a->data.v = g = find_group(gid); if (g!=0) { g->members++; - return 1; + return AT_READ_OK; } - return 0; + return AT_READ_FAIL; } static void diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index 5ec84ada8..ff8214f40 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -148,7 +148,7 @@ a_readicastle(attrib * a, FILE * f) fscanf(f, "%d", &t); data->time = 0; data->type = NULL; - return 0; /* no longer supported */ + return AT_READ_FAIL; } else { int bno; fscanf(f, "%s %d %d", buf, &bno, &data->time); @@ -158,7 +158,7 @@ a_readicastle(attrib * a, FILE * f) ur_add((void*)bno, (void**)&data->building, resolve_building); } data->type = bt_find(buf); - return 1; + return AT_READ_OK; } } @@ -246,7 +246,7 @@ read_mage(attrib * a, FILE * F) (*sp)->spellid = (spellid_t)i; sp = &(*sp)->next; } - return 1; + return AT_READ_OK; } static void @@ -2636,7 +2636,7 @@ read_familiar(attrib * a, FILE * F) fscanf(F, "%s", buf); i = atoi36(buf); ur_add((void*)i, &a->data.v, resolve_familiar); - return 1; + return AT_READ_OK; } /* clones */ @@ -2713,7 +2713,7 @@ read_clone(attrib * a, FILE * F) fscanf(F, "%s", buf); i = atoi36(buf); ur_add((void*)i, &a->data.v, resolve_clone); - return 1; + return AT_READ_OK; } /* mages */ @@ -2739,7 +2739,7 @@ read_magician(attrib * a, FILE * F) fscanf(F, "%s", buf); i = atoi36(buf); ur_add((void*)i, &a->data.v, resolve_mage); - return 1; + return AT_READ_OK; } static int diff --git a/src/common/kernel/movement.c b/src/common/kernel/movement.c index b70065e5c..ef59d4272 100644 --- a/src/common/kernel/movement.c +++ b/src/common/kernel/movement.c @@ -103,14 +103,14 @@ a_traveldir_new_age(attrib *a) int a_traveldir_new_read(attrib *a, FILE *f) { - traveldir *t = (traveldir *)(a->data.v); - int no, age, dir; + traveldir *t = (traveldir *)(a->data.v); + int no, age, dir; - fscanf(f, "%d %d %d", &no, &dir, &age); - t->no = no; - t->dir = (direction_t)dir; - t->age = age; - return 1; + fscanf(f, "%d %d %d", &no, &dir, &age); + t->no = no; + t->dir = (direction_t)dir; + t->age = age; + return AT_READ_OK; } void @@ -391,12 +391,12 @@ do_maelstrom(region *r, unit *u) damage_ship(u->ship, 0.01*damage); if (u->ship->damage >= u->ship->size * DAMAGE_SCALE) { - add_message(&u->faction->msgs, - new_message(u->faction, "entermaelstrom%r:region%h:ship%i:damage%i:sink", r, u->ship, damage, 1)); + ADDMSG(&u->faction->msgs, msg_message("entermaelstrom", + "region ship damage sink", r, u->ship, damage, 1)); destroy_ship(u->ship, r); } else { - add_message(&u->faction->msgs, - new_message(u->faction, "entermaelstrom%r:region%h:ship%i:damage%i:sink", r, u->ship, damage, 0)); + ADDMSG(&u->faction->msgs, msg_message("entermaelstrom", + "region ship damage sink", r, u->ship, damage, 0)); } } @@ -406,7 +406,6 @@ travelthru(unit * u, region * r) attrib *ru = a_add(&r->attribs, a_new(&at_travelunit)); ru->data.v = u; - fset(u, FL_TRAVELTHRU); u->faction->first = 0; u->faction->last = 0; } @@ -419,8 +418,10 @@ move_ship(ship * sh, region * from, region * to, region ** route) direction_t dir; attrib *a; - translist(&from->ships, &to->ships, sh); - sh->region = to; + if (from!=to) { + translist(&from->ships, &to->ships, sh); + sh->region = to; + } while (u) { unit *nu = u->next; @@ -457,14 +458,12 @@ move_ship(ship * sh, region * from, region * to, region ** route) travelthru(u, *ri++); } } - u->ship = NULL; /* damit move_unit() kein leave() macht */ - move_unit(u, to, ulist); -#if 0 - /* das braucht man (fast) sicher nicht. (Enno) */ - fset(u->faction, FL_DH); -#endif - ulist = &u->next; - u->ship = sh; + if (from!=to) { + u->ship = NULL; /* damit move_unit() kein leave() macht */ + move_unit(u, to, ulist); + ulist = &u->next; + u->ship = sh; + } if (route && eff_skill(u, SK_SAILING, from) >= 1) { produceexp(u, SK_SAILING, u->number); } @@ -1550,7 +1549,7 @@ sail(region * starting_point, unit * u, region * next_point, boolean move_on_lan } else { sh->coast = NODIRECTION; } - fset(sh, FL_MOVED); + sprintf(buf, "Die %s ", shipname(sh)); if( is_cursed(sh->attribs, C_SHIP_FLYING, 0) ) scat("fliegt"); @@ -1600,64 +1599,62 @@ sail(region * starting_point, unit * u, region * next_point, boolean move_on_lan /* Verfolgungen melden */ if (fval(u, FL_FOLLOWING)) caught_target(current_point, u); - if (starting_point != current_point) { - tt[step] = NULL; - sh = move_ship(sh, starting_point, current_point, tt); + tt[step] = NULL; + sh = move_ship(sh, starting_point, current_point, tt); - /* Hafengebühren ? */ + /* Hafengebühren ? */ - hafenmeister = owner_buildingtyp(current_point, bt_find("harbour")); - if (sh && hafenmeister != NULL) { - item * itm; - assert(trans==NULL); - for (u2 = current_point->units; u2; u2 = u2->next) { - if (u2->ship == u->ship && - !allied(hafenmeister, u->faction, HELP_GUARD)) { + hafenmeister = owner_buildingtyp(current_point, bt_find("harbour")); + if (sh && hafenmeister != NULL) { + item * itm; + assert(trans==NULL); + for (u2 = current_point->units; u2; u2 = u2->next) { + if (u2->ship == u->ship && + !allied(hafenmeister, u->faction, HELP_GUARD)) { - if (effskill(hafenmeister, SK_OBSERVATION) > effskill(u2, SK_STEALTH)) { - for (itm=u2->items; itm; itm=itm->next) { - const luxury_type * ltype = resource2luxury(itm->type->rtype); - if (ltype!=NULL && itm->number>0) { - st = itm->number * effskill(hafenmeister, SK_TRADE) / 50; - st = min(itm->number, st); + if (effskill(hafenmeister, SK_OBSERVATION) > effskill(u2, SK_STEALTH)) { + for (itm=u2->items; itm; itm=itm->next) { + const luxury_type * ltype = resource2luxury(itm->type->rtype); + if (ltype!=NULL && itm->number>0) { + st = itm->number * effskill(hafenmeister, SK_TRADE) / 50; + st = min(itm->number, st); - if (st > 0) { - i_change(&u2->items, itm->type, -st); - i_change(&hafenmeister->items, itm->type, st); - i_add(&trans, i_new(itm->type, st)); - } + if (st > 0) { + i_change(&u2->items, itm->type, -st); + i_change(&hafenmeister->items, itm->type, st); + i_add(&trans, i_new(itm->type, st)); } } } } } - if (trans) { - sprintf(buf, "%s erhielt ", hafenmeister->name); - for (itm = trans; itm; itm=itm->next) { - if (first != 1) { - if (itm->next!=NULL && itm->next->next==NULL) { - scat(" und "); - } else { - scat(", "); - } - } - first = 0; - icat(trans->number); - scat(" "); - if (itm->number == 1) { - scat(locale_string(default_locale, resourcename(itm->type->rtype, 0))); + } + if (trans) { + sprintf(buf, "%s erhielt ", hafenmeister->name); + for (itm = trans; itm; itm=itm->next) { + if (first != 1) { + if (itm->next!=NULL && itm->next->next==NULL) { + scat(" und "); } else { - scat(locale_string(default_locale, resourcename(itm->type->rtype, NMF_PLURAL))); + scat(", "); } } - scat(" von der "); - scat(shipname(u->ship)); - scat("."); - addmessage(0, u->faction, buf, MSG_COMMERCE, ML_INFO); - addmessage(0, hafenmeister->faction, buf, MSG_INCOME, ML_INFO); - while (trans) i_remove(&trans, trans); + first = 0; + icat(trans->number); + scat(" "); + if (itm->number == 1) { + scat(locale_string(default_locale, resourcename(itm->type->rtype, 0))); + } else { + scat(locale_string(default_locale, resourcename(itm->type->rtype, NMF_PLURAL))); + } } + scat(" von der "); + scat(shipname(u->ship)); + scat("."); + addmessage(0, u->faction, buf, MSG_COMMERCE, ML_INFO); + addmessage(0, hafenmeister->faction, buf, MSG_INCOME, ML_INFO); + while (trans) i_remove(&trans, trans); } } } diff --git a/src/common/kernel/plane.c b/src/common/kernel/plane.c index 9af550a4d..2d8702e79 100644 --- a/src/common/kernel/plane.c +++ b/src/common/kernel/plane.c @@ -242,14 +242,16 @@ write_plane_reference(const plane * u, FILE * F) fprintf(F, "%d ", u?(u->id):0); } -void +int read_plane_reference(plane ** pp, FILE * F) { int i; fscanf(F, "%d", &i); - if (i==0) *pp = NULL; - { - *pp = getplanebyid(i); - if (*pp==NULL) ur_add((void*)i, (void**)pp, resolve_plane); + if (i==0) { + *pp = NULL; + return AT_READ_FAIL; } + *pp = getplanebyid(i); + if (*pp==NULL) ur_add((void*)i, (void**)pp, resolve_plane); + return AT_READ_OK; } diff --git a/src/common/kernel/plane.h b/src/common/kernel/plane.h index 06ba0c527..ab8c18f97 100644 --- a/src/common/kernel/plane.h +++ b/src/common/kernel/plane.h @@ -74,6 +74,6 @@ extern int rel_to_abs(const struct plane *pl, const struct faction * f, int rel, extern void * resolve_plane(void * data); extern void write_plane_reference(const plane * p, FILE * F); -extern void read_plane_reference(plane ** pp, FILE * F); +extern int read_plane_reference(plane ** pp, FILE * F); #endif diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index 5427cc53a..342812f88 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -553,7 +553,7 @@ write_race_reference(const race * rc, FILE * F) fprintf(F, "%s ", rc?rc->_name[0]:"none"); } -void +int read_race_reference(const struct race ** rp, FILE * F) { char zName[20]; @@ -564,16 +564,18 @@ read_race_reference(const struct race ** rp, FILE * F) *rp = new_race[i]; } else { *rp = NULL; + return AT_READ_FAIL; } } else { fscanf(F, "%s", zName); if (strcmp(zName, "none")==0) { *rp = NULL; - } else { - *rp = rc_find(zName); - assert(*rp!=NULL); + return AT_READ_FAIL; } + *rp = rc_find(zName); + assert(*rp!=NULL); } + return AT_READ_OK; } #include diff --git a/src/common/kernel/race.h b/src/common/kernel/race.h index fb875907b..005f27847 100644 --- a/src/common/kernel/race.h +++ b/src/common/kernel/race.h @@ -156,6 +156,6 @@ extern const char *race_prefixes[]; extern const struct race_syn race_synonyms[]; extern void write_race_reference(const struct race * rc, FILE * F); -extern void read_race_reference(const struct race ** rp, FILE * F); +extern int read_race_reference(const struct race ** rp, FILE * F); #endif diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index eb71e3373..e0b8605fd 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -181,7 +181,7 @@ a_readdirection(attrib *a, FILE *f) d->desc = strdup(cstring(buf)); fscanf(f, "%s ", buf); d->keyword = strdup(cstring(buf)); - return 1; + return AT_READ_OK; } void @@ -224,7 +224,7 @@ a_readmoveblock(attrib *a, FILE *f) fscanf(f, "%d", &i); m->dir = (direction_t)i; - return 1; + return AT_READ_OK; } void @@ -1020,16 +1020,18 @@ production(const region *r) return p; } -void +int read_region_reference(region ** r, FILE * F) { int x[2]; fscanf(F, "%d %d", &x[0], &x[1]); - if (x[0]==INT_MAX) *r = NULL; - else { - *r = findregion(x[0], x[1]); - if (*r==NULL) ur_add(memcpy(malloc(sizeof(x)), x, sizeof(x)), (void**)r, resolve_region); + if (x[0]==INT_MAX) { + *r = NULL; + return AT_READ_FAIL; } + *r = findregion(x[0], x[1]); + if (*r==NULL) ur_add(memcpy(malloc(sizeof(x)), x, sizeof(x)), (void**)r, resolve_region); + return AT_READ_OK; } void diff --git a/src/common/kernel/region.h b/src/common/kernel/region.h index 6a2003fc8..e3860112c 100644 --- a/src/common/kernel/region.h +++ b/src/common/kernel/region.h @@ -216,7 +216,7 @@ extern const int delta_y[MAXDIRECTIONS]; extern const direction_t back[MAXDIRECTIONS]; extern int production(const struct region *r); -extern void read_region_reference(struct region ** r, FILE * F); +extern int read_region_reference(struct region ** r, FILE * F); extern void write_region_reference(const struct region * r, FILE * F); #endif /* _REGION_H */ diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index 77ce64431..4bad54c90 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -184,7 +184,7 @@ bufunit(const faction * f, const unit * u, int indent, int mode) strcpy(buf, unitname(u)); - fv = visible_faction(f,u); + fv = visible_faction(f, u); a_otherfaction = a_find(u->attribs, &at_otherfaction); if (u->faction == f) { diff --git a/src/common/kernel/reports.h b/src/common/kernel/reports.h index fd3145283..47370f520 100644 --- a/src/common/kernel/reports.h +++ b/src/common/kernel/reports.h @@ -82,12 +82,14 @@ typedef struct seen_region { struct seen_region * next; struct seen_region * prev; struct seen_region * nextHash; - struct region *r; + const struct region *r; unsigned char mode; boolean disbelieves; } seen_region; -extern seen_region * seen; +extern struct seen_region * seen; +extern struct seen_region * find_seen(const struct region * r); + extern const char* resname(resource_t res, int i); extern char **seasonnames; diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index 6ca86fb7c..1189c968b 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -89,7 +89,7 @@ int laen_read(attrib * a, FILE * F) int laen; fscanf(F, "%d", &laen); read_laen(current_region, laen); - return 0; + return AT_READ_FAIL; } #endif @@ -258,7 +258,6 @@ ri(FILE * F) return i * vz; } - static int ri36(FILE * F) { @@ -840,7 +839,7 @@ readgame(boolean backup) n = ri(F); if (maxregions<0) maxregions = n; - printf(" - Einzulesende Regionen: %d/%d ", maxregions, n); + printf(" - Einzulesende Regionen: %d/%d\r", maxregions, n); while (--n >= 0) { unit **up; @@ -862,8 +861,8 @@ readgame(boolean backup) skip = true; } if ((n%1024)==0) { /* das spart extrem Zeit */ + printf(" - Einzulesende Regionen: %d/%d ", maxregions, n); printf("* %d,%d \r", x, y); - printf(" - Einzulesende Regionen: %d/%d ", maxregions, n); } if (skip) { char * r; @@ -966,6 +965,7 @@ readgame(boolean backup) addlist2(up,u); } } + printf("\n"); if (!dirtyload) { if (global.data_version >= BORDER_VERSION) read_borders(F); #ifdef USE_UGROUPS @@ -1040,6 +1040,9 @@ readgame(boolean backup) if(findfaction(0)) { findfaction(0)->alive = 1; } + if (maxregions>=0) { + remove_empty_factions(); + } /* Regionen */ for (r=regions;r;r=r->next) { @@ -1449,7 +1452,7 @@ curse_read(attrib * a, FILE * f) { } chash(c); - return 1; + return AT_READ_OK; } /* ------------------------------------------------------------- */ @@ -1499,13 +1502,13 @@ read_faction_reference(faction ** f, FILE * F) } else { fscanf(F, "%d ", &id); } - if (id==0) { + if (id<0) { *f = NULL; - return 0; + return AT_READ_FAIL; } *f = findfaction(id); if (*f==NULL) ur_add((void*)id, (void**)f, resolve_faction); - return 1; + return AT_READ_OK; } void diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c index 85b576b25..3ffa95f30 100644 --- a/src/common/kernel/spell.c +++ b/src/common/kernel/spell.c @@ -2939,7 +2939,7 @@ cw_read(attrib * a, FILE * f) fscanf(f, "%d ", &br->id); ur_add((void *)br->id, (void**)&wc->wall, resolve_borderid); ur_add((void *)br, (void**)&wc->buddy, resolve_buddy); - return 1; + return AT_READ_OK; } attrib_type at_cursewall = diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index 98bd21212..a006c87ff 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -459,20 +459,23 @@ write_unit_reference(const unit * u, FILE * F) fprintf(F, "%s ", u?itoa36(u->no):"0"); } -void +int read_unit_reference(unit ** up, FILE * F) { char zId[10]; int i; fscanf(F, "%s", zId); - i = atoi36(zId); - if (up) { - if (i==0) *up = NULL; - else { - *up = findunit(i); - if (*up==NULL) ur_add((void*)i, (void**)up, resolve_unit); - } + if (up==NULL) { + return AT_READ_FAIL; } + i = atoi36(zId); + if (i==0) { + *up = NULL; + return AT_READ_FAIL; + } + *up = findunit(i); + if (*up==NULL) ur_add((void*)i, (void**)up, resolve_unit); + return AT_READ_OK; } attrib_type at_stealth = { diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index 729681a1b..2dd02bbf2 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -130,7 +130,7 @@ extern void destroy_unit(struct unit * u); /* see resolve.h */ extern void * resolve_unit(void * data); extern void write_unit_reference(const unit * u, FILE * F); -extern void read_unit_reference(unit ** up, FILE * F); +extern int read_unit_reference(unit ** up, FILE * F); extern void leave(struct region * r, struct unit * u); extern void leave_ship(unit * u); diff --git a/src/common/modules/arena.c b/src/common/modules/arena.c index f3355ce9c..d6ed152e9 100644 --- a/src/common/modules/arena.c +++ b/src/common/modules/arena.c @@ -267,9 +267,9 @@ read_hurting(attrib * a, FILE * F) { a->data.v = (void*)findbuilding(i); if (a->data.v==NULL) { log_error(("temple of pain is broken\n")); - return 0; + return AT_READ_FAIL; } - return 1; + return AT_READ_OK; } static attrib_type at_hurting = { @@ -446,7 +446,7 @@ caldera_read(trigger * t, FILE * F) t->data.v = findbuilding(i); if (t->data.v==NULL) ur_add((void*)i, &t->data.v, resolve_building); - return 1; + return AT_READ_OK; } struct trigger_type tt_caldera = { diff --git a/src/common/modules/gmcmd.c b/src/common/modules/gmcmd.c index 7fc90cca5..00eed9ae2 100644 --- a/src/common/modules/gmcmd.c +++ b/src/common/modules/gmcmd.c @@ -57,7 +57,7 @@ read_permissions(attrib * a, FILE * F) { attrib ** p_a = (attrib**)&a->data.v; a_read(F, p_a); - return 1; + return AT_READ_OK; } struct attrib_type at_permissions = { @@ -93,7 +93,7 @@ read_gmcreate(attrib * a, FILE * F) fscanf(F, "%s", zText); *p_itype = it_find(zText); assert(*p_itype); - return 1; + return AT_READ_OK; } /* at_gmcreate specifies that the owner can create items of a particular type */ diff --git a/src/common/modules/museum.c b/src/common/modules/museum.c index 8cb4cefa5..d006f4b4d 100644 --- a/src/common/modules/museum.c +++ b/src/common/modules/museum.c @@ -98,7 +98,7 @@ a_readmuseumgivebackcookie(attrib *a, FILE *f) { museumgivebackcookie *gbc = (museumgivebackcookie *)a->data.v; fscanf(f, "%d %d", &gbc->warden_no, &gbc->cookie); - return 1; + return AT_READ_OK; } attrib_type at_museumgivebackcookie = { @@ -141,7 +141,7 @@ a_readmuseumgiveback(attrib *a, FILE *f) museumgiveback *gb = (museumgiveback *)a->data.v; fscanf(f, "%d", &gb->cookie); read_items(f, &gb->items); - return 1; + return AT_READ_OK; } attrib_type at_museumgiveback = { diff --git a/src/common/modules/xmas.c b/src/common/modules/xmas.c index 48186e872..24432912a 100644 --- a/src/common/modules/xmas.c +++ b/src/common/modules/xmas.c @@ -32,7 +32,6 @@ santa_comes_to_town(region * r, unit * santa, void (*action)(unit*)) const item_type * roi = it_find("roi"); assert(roi); - fset(santa, FL_TRAVELTHRU); for (f = factions;f;f=f->next) { unit * u; unit * senior = f->units; diff --git a/src/common/modules/xmas2000.c b/src/common/modules/xmas2000.c index 9f0e3a5b3..689bd71ee 100644 --- a/src/common/modules/xmas2000.c +++ b/src/common/modules/xmas2000.c @@ -89,15 +89,7 @@ xmasgate_write(const trigger * t, FILE * F) static int xmasgate_read(trigger * t, FILE * F) { - char zText[128]; - int i; - - fscanf(F, "%s", zText); - i = atoi36(zText); - t->data.v = findbuilding(i); - if (t->data.v==NULL) ur_add((void*)i, &t->data.v, resolve_building); - - return 1; + return read_building_reference((building**)&t->data.v, F); } struct trigger_type tt_xmasgate = { diff --git a/src/common/spells/alp.c b/src/common/spells/alp.c index 253eb1a7d..ffd3c4288 100644 --- a/src/common/spells/alp.c +++ b/src/common/spells/alp.c @@ -70,9 +70,10 @@ static int alp_read(attrib * a, FILE * F) { alp_data * ad = (alp_data*)a->data.v; - read_unit_reference(&ad->mage, F); - read_unit_reference(&ad->target, F); - return 1; + int m = read_unit_reference(&ad->mage, F); + int t = read_unit_reference(&ad->target, F); + if (m!=AT_READ_OK || t!=AT_READ_OK) return AT_READ_FAIL; + return AT_READ_OK; } static attrib_type at_alp = { diff --git a/src/common/triggers/changefaction.c b/src/common/triggers/changefaction.c index c5db7436c..b24b3a28a 100644 --- a/src/common/triggers/changefaction.c +++ b/src/common/triggers/changefaction.c @@ -83,10 +83,11 @@ changefaction_read(trigger * t, FILE * F) { changefaction_data * td = (changefaction_data*)t->data.v; - read_unit_reference(&td->unit, F); - read_faction_reference(&td->faction, F); + int u = read_unit_reference(&td->unit, F); + int f = read_faction_reference(&td->faction, F); - return 1; + if (u!=AT_READ_OK || f!=AT_READ_OK) return AT_READ_FAIL; + return AT_READ_OK; } trigger_type tt_changefaction = { diff --git a/src/common/triggers/changerace.c b/src/common/triggers/changerace.c index 18bcc490a..905d85f0e 100644 --- a/src/common/triggers/changerace.c +++ b/src/common/triggers/changerace.c @@ -84,10 +84,11 @@ static int changerace_read(trigger * t, FILE * F) { changerace_data * td = (changerace_data*)t->data.v; - read_unit_reference(&td->u, F); - read_race_reference(&td->race, F); - read_race_reference(&td->irace, F); - return 1; + int uc = read_unit_reference(&td->u, F); + int rc = read_race_reference(&td->race, F); + int ic = read_race_reference(&td->irace, F); + if (uc!=AT_READ_OK || rc!=AT_READ_OK || ic!=AT_READ_OK) return AT_READ_FAIL; + return AT_READ_OK; } trigger_type tt_changerace = { diff --git a/src/common/triggers/clonedied.c b/src/common/triggers/clonedied.c index 62d2ba20e..ce0f59984 100644 --- a/src/common/triggers/clonedied.c +++ b/src/common/triggers/clonedied.c @@ -62,8 +62,7 @@ clonedied_write(const trigger * t, FILE * F) static int clonedied_read(trigger * t, FILE * F) { - read_unit_reference((unit**)&t->data.v, F); - return 1; + return read_unit_reference((unit**)&t->data.v, F); } trigger_type tt_clonedied = { diff --git a/src/common/triggers/createcurse.c b/src/common/triggers/createcurse.c index 9dafca644..72c61f059 100644 --- a/src/common/triggers/createcurse.c +++ b/src/common/triggers/createcurse.c @@ -103,7 +103,7 @@ createcurse_read(trigger * t, FILE * F) if (td->target==NULL) ur_add((void*)i, (void**)&td->target, resolve_unit); fscanf(F, "%d %d %d %d %d %d ", &td->id, &td->id2, &td->vigour, &td->duration, &td->effect, &td->men); - return 1; + return AT_READ_OK; } trigger_type tt_createcurse = { diff --git a/src/common/triggers/createunit.c b/src/common/triggers/createunit.c index 3a1acbb28..52a264a08 100644 --- a/src/common/triggers/createunit.c +++ b/src/common/triggers/createunit.c @@ -88,12 +88,14 @@ createunit_read(trigger * t, FILE * F) { createunit_data * td = (createunit_data*)t->data.v; - read_unit_reference(&td->u, F); - read_region_reference(&td->r, F); - read_race_reference(&td->race, F); + int uc = read_unit_reference(&td->u, F); + int rc = read_region_reference(&td->r, F); + int ic = read_race_reference(&td->race, F); fscanf(F, "%d ", &td->number); - return 1; + + if (uc!=AT_READ_OK || rc!=AT_READ_OK || ic!=AT_READ_OK) return AT_READ_FAIL; + return AT_READ_OK; } trigger_type tt_createunit = { diff --git a/src/common/triggers/gate.c b/src/common/triggers/gate.c index 0e2b759ad..951485602 100644 --- a/src/common/triggers/gate.c +++ b/src/common/triggers/gate.c @@ -71,10 +71,11 @@ gate_read(trigger * t, FILE * F) { gate_data * gd = (gate_data*)t->data.v; - read_building_reference(&gd->gate, F); - read_region_reference(&gd->target, F); + int bc = read_building_reference(&gd->gate, F); + int rc = read_region_reference(&gd->target, F); - return 1; + if (rc!=AT_READ_OK || bc!=AT_READ_OK) return AT_READ_FAIL; + return AT_READ_OK; } static void diff --git a/src/common/triggers/giveitem.c b/src/common/triggers/giveitem.c index 2bf46a678..f661c2a87 100644 --- a/src/common/triggers/giveitem.c +++ b/src/common/triggers/giveitem.c @@ -91,7 +91,7 @@ giveitem_read(trigger * t, FILE * F) td->itype = it_find(zText); assert(td->itype); - return 1; + return AT_READ_OK; } trigger_type tt_giveitem = { diff --git a/src/common/triggers/killunit.c b/src/common/triggers/killunit.c index 2672e0997..1eb2828a5 100644 --- a/src/common/triggers/killunit.c +++ b/src/common/triggers/killunit.c @@ -54,8 +54,7 @@ killunit_write(const trigger * t, FILE * F) static int killunit_read(trigger * t, FILE * F) { - read_unit_reference((unit**)&t->data.v, F); - return 1; + return read_unit_reference((unit**)&t->data.v, F); } trigger_type tt_killunit = { diff --git a/src/common/triggers/removecurse.c b/src/common/triggers/removecurse.c index 22be2253b..210b7b1c0 100644 --- a/src/common/triggers/removecurse.c +++ b/src/common/triggers/removecurse.c @@ -94,7 +94,7 @@ removecurse_read(trigger * t, FILE * F) td->curse = cfindhash(i); if (td->curse==NULL) ur_add((void*)i, (void**)&td->curse, resolve_curse); - return 1; + return AT_READ_OK; } trigger_type tt_removecurse = { diff --git a/src/common/triggers/shock.c b/src/common/triggers/shock.c index 6ae7c1521..a6a142ddd 100644 --- a/src/common/triggers/shock.c +++ b/src/common/triggers/shock.c @@ -49,14 +49,25 @@ static void shock_write(const trigger * t, FILE * F) { unit * u = (unit*)t->data.v; - write_unit_reference(u, F); + trigger * next = t->next; + while (next) { + /* make sure it is unique! */ + if (next->type==t->type && next->data.v==t->data.v) break; + next=next->next; + } + if (next && u) { + log_error(("more than one shock-attribut for %s on a unit. FIXED.\n", + unitid(u))); + write_unit_reference(NULL, F); + } else { + write_unit_reference(u, F); + } } static int shock_read(trigger * t, FILE * F) { - read_unit_reference((unit**)&t->data.v, F); - return 1; + return read_unit_reference((unit**)&t->data.v, F); } trigger_type tt_shock = { diff --git a/src/common/triggers/timeout.c b/src/common/triggers/timeout.c index c991ea4ca..dfc0418d3 100644 --- a/src/common/triggers/timeout.c +++ b/src/common/triggers/timeout.c @@ -83,7 +83,8 @@ timeout_read(trigger * t, FILE * F) tr = tr->next; } } - return (td->triggers!=NULL && td->timer>0); + if (td->triggers!=NULL && td->timer>0) return AT_READ_OK; + return AT_READ_FAIL; } trigger_type tt_timeout = { diff --git a/src/common/triggers/unguard.c b/src/common/triggers/unguard.c index 493301cb8..5ae14a5d5 100644 --- a/src/common/triggers/unguard.c +++ b/src/common/triggers/unguard.c @@ -49,9 +49,7 @@ unguard_write(const trigger * t, FILE * F) static int unguard_read(trigger * t, FILE * F) { - read_building_reference((building**)&t->data.v, F); - - return 1; + return read_building_reference((building**)&t->data.v, F); } struct trigger_type tt_unguard = { diff --git a/src/common/triggers/unitmessage.c b/src/common/triggers/unitmessage.c index f11dc89f5..0a1eed103 100644 --- a/src/common/triggers/unitmessage.c +++ b/src/common/triggers/unitmessage.c @@ -93,7 +93,7 @@ unitmessage_read(trigger * t, FILE * F) fscanf(F, "%s %d %d ", zText, &td->type, &td->level); td->string = strdup(zText); - return 1; + return AT_READ_OK; } trigger_type tt_unitmessage = { diff --git a/src/common/util/attrib.c b/src/common/util/attrib.c index dce894a5e..aee7bc57e 100644 --- a/src/common/util/attrib.c +++ b/src/common/util/attrib.c @@ -174,7 +174,7 @@ a_readdefault(attrib * a, FILE * f) { assert(sizeof(int)==sizeof(a->data)); fscanf(f, "%d", &a->data.i); - return 1; + return AT_READ_OK; } void @@ -206,7 +206,7 @@ a_readstring(attrib * a, FILE * f) char zText[4096]; read_quoted(f, zText, sizeof(zText)); a->data.v = strdup(zText); - return 1; + return AT_READ_OK; } void @@ -258,10 +258,18 @@ a_read(FILE * f, attrib ** attribs) } if (at->read) { attrib * na = a_new(at); - if (at->read(na, f)) + int i = at->read(na, f); + switch (i) { + case AT_READ_OK: a_add(attribs, na); - else + break; + case AT_READ_FAIL: a_free(na); + break; + default: + assert(!"invalid return value"); + break; + } } else { assert(!"fehler: keine laderoutine für attribut"); } diff --git a/src/common/util/attrib.h b/src/common/util/attrib.h index b98de9ca1..6b8576127 100644 --- a/src/common/util/attrib.h +++ b/src/common/util/attrib.h @@ -83,4 +83,7 @@ extern void a_write(FILE * f, const attrib * attribs); #define NO_WRITE NULL #define NO_READ NULL +#define AT_READ_OK 4711 +#define AT_READ_FAIL -4711 + #endif diff --git a/src/common/util/base36.c b/src/common/util/base36.c index 549454dc0..87bd1b28e 100644 --- a/src/common/util/base36.c +++ b/src/common/util/base36.c @@ -25,13 +25,16 @@ #include #include -#ifdef HAVE_STRTOL int atoi36(const char * s) { - return (int)(strtol(s, NULL, 36)); + char * p = NULL; + int i = (int)(strtol(s, &p, 36)); + if (*p || i<0) return -1; + return i; } -#else + +#if 0 #include int atoi36(const char * s) @@ -40,14 +43,15 @@ atoi36(const char * s) assert(s); if(!(*s)) return 0; - while(!isalnum((int)*s)) ++s; + while(isspace((int)*s)) ++s; while(isalnum((int)*s)) { if (isupper((int)*s)) i = i*36 + (*s)-'A' + 10; else if (islower((int)*s)) i=i*36 + (*s)-'a' + 10; else if (isdigit((int)*s)) i=i*36 + (*s)-'0'; + else return -1; ++s; } - if (i<0) return 0; + if (i<0 || !isspace(*s) && *s!='0') return -1; return i; } #endif diff --git a/src/common/util/event.c b/src/common/util/event.c index fc2d5abcf..b3d9ac2fc 100644 --- a/src/common/util/event.c +++ b/src/common/util/event.c @@ -47,8 +47,20 @@ read_triggers(FILE * F, trigger ** tp) ttype = tt_find(zText); assert(ttype || !"unknown trigger-type"); *tp = t_new(ttype); - if (ttype->read) ttype->read(*tp, F); - tp = &(*tp)->next; + if (ttype->read) { + int i = ttype->read(*tp, F); + switch (i) { + case AT_READ_OK: + tp = &(*tp)->next; + break; + case AT_READ_FAIL: + t_free(*tp); + break; + default: + assert(!"invalid return value"); + break; + } + } } } @@ -130,7 +142,10 @@ read_handler(attrib * a, FILE * F) fscanf(F, "%s ", zText); hi->event = strdup(zText); read_triggers(F, &hi->triggers); - return (hi->triggers!=NULL); + if (hi->triggers!=NULL) { + return AT_READ_OK; + } + return AT_READ_FAIL; } attrib_type at_eventhandler = { diff --git a/src/eressea/eressea.dsp b/src/eressea/eressea.dsp index 8ec190344..8c2310f76 100644 --- a/src/eressea/eressea.dsp +++ b/src/eressea/eressea.dsp @@ -108,6 +108,22 @@ LINK32=link.exe # Name "eressea - Win32 Release" # Name "eressea - Win32 Debug" # Name "eressea - Win32 Profile" +# Begin Group "Text Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\commit.txt +# End Source File +# Begin Source File + +SOURCE=..\header.txt +# End Source File +# Begin Source File + +SOURCE=..\todo.txt +# End Source File +# End Group # Begin Source File SOURCE=.\korrektur.c diff --git a/src/eressea/korrektur.c b/src/eressea/korrektur.c index 7e24d1583..494b136a7 100644 --- a/src/eressea/korrektur.c +++ b/src/eressea/korrektur.c @@ -126,9 +126,8 @@ verify_owners(boolean bOnce) #define do_once(magic, fun) \ { \ attrib * a = find_key(global.attribs, atoi36(magic)); \ - if (a) { \ - log_warning(("[do_once] a unique fix %d=\"%s\" was called a second time\n", atoi36(magic), magic)); \ - } else { \ + if (!a) { \ + log_warning(("[do_once] a unique fix %d=\"%s\" was applied.\n", atoi36(magic), magic)); \ if (fun == 0) a_add(&global.attribs, make_key(atoi36(magic))); \ } \ } @@ -138,12 +137,13 @@ warn_items(void) { boolean found = 0; region * r; + const item_type * it_money = it_find("money"); for (r=regions;r;r=r->next) { unit * u; for (u=r->units;u;u=u->next) { item * itm; for (itm=u->items;itm;itm=itm->next) { - if (itm->number>1000000) { + if (itm->number>100000 && itm->type!=it_money) { found = 1; log_error(("Einheit %s hat %u %s\n", unitid(u), itm->number, @@ -187,7 +187,6 @@ santa_comes_to_town(void) santa->irace = new_race[RC_DAEMON]; set_string(&santa->name, "Ein dicker Gnom mit einem Rentierschlitten"); set_string(&santa->display, "hat: 6 Rentiere, Schlitten, Sack mit Geschenken, Kekse für Khorne"); - fset(santa, FL_TRAVELTHRU); for (f=factions;f;f=f->next) { unit * u; @@ -1337,7 +1336,7 @@ fix_herbtypes(void) static int fix_plainherbs(void) { - region *r, *lastr; + region *r, *lastr = regions; for (r=regions;r;r=r->next) { int i; const char * name; diff --git a/src/todo.txt b/src/todo.txt index 6c2ff66a3..50b1ae3ed 100644 --- a/src/todo.txt +++ b/src/todo.txt @@ -1,44 +1,53 @@ +Status: + *=default + !=critical, muss diese Runde gemacht werden. + +=fixed, muss überprüft werden + V=verified, ist getestet + -=war kein Bug + Announcen: -* Freigewordene Vinyambar-Parteien -* Bugfix Kräuterverteilung -* Schattendämonen, Gewicht +! Schattendämonen, Gewicht Nächste Woche beachten: -* bei der auswertung auf die resourcenanzeige achten. -* Kräuterneuverteilung -* Bauern in Bofintedlat aussetzen, bitte ++ bei der auswertung auf die resourcenanzeige achten. ++ Kräuterneuverteilung +! Bauern in Bofintedlat aussetzen, bitte Bugfixes/Debugging: +! TARNE PARTEI NICHT immer noch defekt? * Tragkraft von monstern unbegrenzt? * Unterhaltungsmaximum kann nicht ausgeschoepft werden (H. Bruns) * Schiff nicht abgelegt (Marc Albrecht) -* Antimagiekristall (Stefan Schwarz) -* NR und CR Diskrepanz: Strassen -* shock-Attribut (u. wahrscheinlich andere) mehrfach im Datenfile -* Kampf und Bergung (W. Edel) -* Lernkosten (W. Edel) -* Schattendaemonen kann man mit RESERVIERE Gegenstaende abnehmen, aber sie ++ Antimagiekristall (Stefan Schwarz) ++ NR und CR Diskrepanz: Strassen ++ shock-Attribut (u. wahrscheinlich andere) mehrfach im Datenfile +v Kampf und Bergung (W. Edel) +- Lernkosten (W. Edel) +! Schattendaemonen kann man mit RESERVIERE Gegenstaende abnehmen, aber sie koennen kein GIB. was ist richtig? * Monsterroutinen nochmal anschauen, Clustering von Wyrmen -* trigger anschauen. killunit::handle -* Durchreiseregionen werden nicht angezeigt -* Gewicht von Schattendämonen +v trigger anschauen. killunit::handle +v Durchreiseregionen werden nicht angezeigt +v Regionen nach Straßen werden nicht angezeigt +! Gewicht von Schattendämonen +v remove_empty_factions darf kein free machen, weil noch attribute + auf die partei zeigen. Attribute mit faction 0 wurden nie eingelesen. +* Parteien in Durchreise- und Leuchtturmregionen tauchen nicht als PARTEI Block auf Features: * Bauernblut-Effekt an der Einheit speichern, wie bei anderen Traenken auch -* Passworte fuer Vinyambar, cancelling von Parteien aus DB an Server - weiterreichen +* cancelling von Parteien aus DB an Server weiterreichen * Automatisches Einsetzen im allgemeinen * buildings.xml hat keinen support fuer gebaeude mit mehreren ausbaustufen (castle). nachtragen, und bt_castle aus dem source werfen -* eigener messagetype für regions-/einheitenbotschaften (nicht string) +- eigener messagetype für regions-/einheitenbotschaften (nicht string) Webseiten, Mailinglisten: * mehr logging, vinyambar-accounts * mailman gate_news konfiguration * mailgate schickt postings von Arsenius nicht an die mailingliste. -* Option fuer Start in alten Regionen im Webformular -* Regel mit mindestens 0 NMR aus der partieboerse (standin.py) nehmen. +! Option fuer Start in alten Regionen im Webformular +V Regel mit mindestens 0 NMR aus der parteiboerse (standin.py) nehmen. Designideen zur Diskussion: * neue Waffen