diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index 2b2cf624c..7a78a9e10 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -470,6 +470,27 @@ read_building_reference(struct building ** b, FILE * F) } } +void +free_buildinglist(building_list *blist) +{ + while (blist) { + building_list * rl2 = blist->next; + free(blist); + blist = rl2; + } +} + +void +add_buildinglist(building_list **blist, building *b) +{ + building_list *rl2 = (building_list*)malloc(sizeof(building_list)); + + rl2->data = b; + rl2->next = *blist; + + *blist = rl2; +} + building * new_building(const struct building_type * btype, region * r, const struct locale * lang) { diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index 1789d2c75..c08bf3fdb 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -98,6 +98,14 @@ typedef struct building { unsigned int flags; } building; +typedef struct building_list { + struct building_list * next; + building * data; +} building_list; + +extern void free_buildinglist(building_list *bl); +extern void add_buildinglist(building_list **bl, struct building *b); + extern attrib_type at_building_generic_type; extern const char * buildingtype(const struct building * b, int bsize); extern const char * buildingname(const struct building * b); diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 7f99b4d5a..3ae6abf61 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -1828,6 +1828,40 @@ maxworkingpeasants(const struct region * r) return max(i, 0); } +unit_list * +get_lighthouses(const region * r) +{ + attrib * a; + unit_list * ulist = NULL; + + if (rterrain(r) != T_OCEAN) return NULL; + + for (a = a_find(r->attribs, &at_lighthouse);a;a=a->nexttype) { + building *b = (building *)a->data.v; + region *r2 = b->region; + + if (fval(b, BLD_WORKING) && b->size >= 10) { + boolean c = false; + unit *u; + int d = distance(r, r2); + int maxd = (int)log10(b->size) + 1; + + if (maxd < d) break; + + for (u = r2->units; u; u = u->next) { + if (u->building == b) { + c = true; + if (c > buildingcapacity(b)) break; + if (eff_skill(u, SK_OBSERVATION, r) >= d * 3) { + unitlist_insert(&ulist, u); + } + } else if (c) break; /* first unit that's no longer in the house ends the search */ + } + } + } + return ulist; +} + boolean check_leuchtturm(region * r, faction * f) { @@ -1899,6 +1933,48 @@ lastregion (faction * f) return f->last; } +void +update_intervals(void) +{ + region *r; + + for (r = regions; r; r = r->next) { + plane * p = rplane(r); + attrib *ru; + unit *u; + unit_list * ulist, *uptr; + + for (u = r->units; u; u = u->next) { + faction * f = u->faction; + if (f->first==NULL) f->first = r; + } + + for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) { + faction * f = ((unit*)ru->data.v)->faction; + if (f->first==NULL) f->first = r; + } + + ulist = get_lighthouses(r); + for (uptr=ulist;uptr!=NULL;uptr=uptr->next) { + /* check lighthouse warden's faction */ + unit * u = uptr->data; + if (u->faction->first==NULL) { + u->faction->first = r; + } + } + unitlist_clear(&ulist); + + if (p!=NULL) { + struct watcher * w = p->watchers; + while (w) { + faction * f = w->faction; + if (f->first==NULL) f->first = r; + w = w->next; + } + } + } +} + region * firstregion (faction * f) { diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 4cfc8bbbf..b7dfb01b5 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -910,6 +910,7 @@ extern boolean faction_id_is_unused(int); /* leuchtturm */ extern boolean check_leuchtturm(struct region * r, struct faction * f); extern void update_lighthouse(struct building * lh); +extern struct unit_list * get_lighthouses(const struct region * r); /* skills */ extern int max_skill(struct faction * f, skill_t sk); diff --git a/src/common/kernel/pathfinder.c b/src/common/kernel/pathfinder.c index da2d13841..d73608871 100644 --- a/src/common/kernel/pathfinder.c +++ b/src/common/kernel/pathfinder.c @@ -109,7 +109,6 @@ regions_in_range(struct region * start, int maxdist, boolean (*allowed)(const st if (n->distance >= maxdist) break; for (d=0;d!=MAXDIRECTIONS; ++d) { region * rn = rconnect(r, d); - region_list * rnew; if (rn==NULL) continue; if (fval(rn, FL_MARK)) continue; /* already been there */ if (!allowed(r, rn)) continue; /* can't go there */ diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c index d2a296c49..6298d390f 100644 --- a/src/common/kernel/spell.c +++ b/src/common/kernel/spell.c @@ -7255,8 +7255,8 @@ sp_wdwpyramid(castorder *co) for(r2 = regions; r2; r2 = r2->next) { if(a_find(r->attribs, &at_wdwpyramid) != NULL) { - short dist = distance(mage->region, r2); - if(dist < mindist) { + int dist = distance(mage->region, r2); + if (dist < mindist) { mindist = dist; } } @@ -9131,7 +9131,7 @@ spell spelldaten[] = (spell_f)sp_transferaura, patzer }, - {SPL_UNIT_ANALYSESONG, "Gesang des Lebens analysieren", NULL, NULL, + {SPL_UNIT_ANALYSESONG, "analysesong_unit", NULL, NULL, "u", M_BARDE, (UNITSPELL | ONSHIPCAST | ONETARGET | TESTCANSEE), diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index ac43e5c15..bd49f8b5e 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -51,7 +51,6 @@ #define FIND_FOREIGN_TEMP - int demonfix = 0; /* ------------------------------------------------------------- */ @@ -1092,3 +1091,24 @@ is_monstrous(const unit * u) return (boolean) (u->faction->no == MONSTER_FACTION || !playerrace(u->race)); } +void +unitlist_clear(struct unit_list **ul) +{ + while (*ul) { + unit_list * rl2 = (*ul)->next; + free(*ul); + *ul = rl2; + } +} + +void +unitlist_insert(struct unit_list **ul, struct unit *u) +{ + unit_list *rl2 = (unit_list*)malloc(sizeof(unit_list)); + + rl2->data = u; + rl2->next = *ul; + + *ul = rl2; +} + diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index f52ce2f44..7914a112e 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -94,6 +94,14 @@ typedef struct unit { int wants; /* enno: attribut? */ } unit; +typedef struct unit_list { + struct unit_list * next; + struct unit * data; +} unit_list; + +extern void unitlist_clear(struct unit_list **ul); +extern void unitlist_insert(struct unit_list **ul, struct unit *u); + extern attrib_type at_alias; extern attrib_type at_siege; extern attrib_type at_target;