diff --git a/src/economy.c b/src/economy.c index f218c766c..9108d7aa1 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1032,8 +1032,7 @@ static bool maintain(building * b, bool first) bool paid = true, work = first; unit *u; - if (fval(b, BLD_MAINTAINED) || b->type == NULL || b->type->maintenance == NULL - || is_cursed(b->attribs, C_NOCOST, 0)) { + if (fval(b, BLD_MAINTAINED) || b->type == NULL || b->type->maintenance == NULL || is_cursed(b->attribs, C_NOCOST, 0)) { fset(b, BLD_MAINTAINED); fset(b, BLD_WORKING); return true; @@ -1042,6 +1041,58 @@ static bool maintain(building * b, bool first) return false; } u = building_owner(b); + if (u == NULL) + return false; + /* If the owner is the region owner, check if biggest castle has the dontpay flag */ + if (check_param(global.parameters, "rules.region_owner_pay_building", b->type->_name)) { + if (u == building_owner(largestbuilding(r, &cmp_taxes, false))) { + if (fval(u->building, BLD_DONTPAY)) { + return false; + } + } + } + for (c = 0; b->type->maintenance[c].number; ++c) { + const maintenance *m = b->type->maintenance + c; + int need = m->number; + + if (fval(m, MTF_VARIABLE)) + need = need * b->size; + if (u) { + /* first ist im ersten versuch true, im zweiten aber false! Das + * bedeutet, das in der Runde in die Region geschafften Resourcen + * nicht genutzt werden können, weil die reserviert sind! */ + if (!first) + need -= get_pooled(u, m->rtype, GET_ALL, need); + else + need -= get_pooled(u, m->rtype, GET_DEFAULT, need); + if (!first && need > 0) { + unit *ua; + for (ua = r->units; ua; ua = ua->next) + freset(ua->faction, FFL_SELECT); + fset(u->faction, FFL_SELECT); /* hat schon */ + for (ua = r->units; ua; ua = ua->next) { + if (!fval(ua->faction, FFL_SELECT) && (ua->faction == u->faction + || alliedunit(ua, u->faction, HELP_MONEY))) { + need -= get_pooled(ua, m->rtype, GET_ALL, need); + fset(ua->faction, FFL_SELECT); + if (need <= 0) + break; + } + } + } + if (need > 0) { + if (!fval(m, MTF_VITAL)) + work = false; + else { + paid = false; + break; + } + } + } + if (fval(b, BLD_DONTPAY)) { + return false; + } + u = building_owner(b); if (u == NULL) return false; for (c = 0; b->type->maintenance[c].number; ++c) { diff --git a/src/kernel/building.c b/src/kernel/building.c index d638819e4..1fd0b5efa 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -586,7 +586,6 @@ void building_set_owner(struct unit * owner) static unit *building_owner_ex(const building * bld, const struct faction * last_owner) { unit *u, *heir = 0; - /* Eigentümer tot oder kein Eigentümer vorhanden. Erste lebende Einheit * nehmen. */ for (u = bld->region->units; u; u = u->next) { @@ -602,11 +601,25 @@ static unit *building_owner_ex(const building * bld, const struct faction * last } } } - return heir; + if (!heir && check_param(global.parameters, "rules.region_owner_pay_building", bld->type->_name)) { + if (rule_region_owners()) { + u = building_owner(largestbuilding(bld->region, &cmp_taxes, false)); + } + else { + u = building_owner(largestbuilding(bld->region, &cmp_wage, false)); + } + if (u) { + heir = u; + } + } + return heir; } unit *building_owner(const building * bld) { + if (!bld) { + return NULL; + } unit *owner = bld->_owner; if (!owner || (owner->building!=bld || owner->number<=0)) { unit * heir = building_owner_ex(bld, owner?owner->faction:0); diff --git a/src/kernel/config.c b/src/kernel/config.c index 4773faf96..c542bfa59 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -1538,8 +1538,10 @@ int lighthouse_range(const building * b, const faction * f) int c = 0; unit *u; for (u = r->units; u; u = u->next) { - if (u->building == b) { - c += u->number; + if (u->building == b || u == building_owner(b)) { + if (u->building == b) { + c += u->number; + } if (c > buildingcapacity(b)) break; if (f == NULL || u->faction == f) { @@ -1882,6 +1884,27 @@ int get_param_int(const struct param *p, const char *key, int def) return str ? atoi(str) : def; } +int check_param(const struct param *p, const char *key, const char *searchvalue) +{ + const char *value = get_param(p, key); + if (!value) { + return 0; + } + char *p_value = malloc(sizeof(char)* (strlen(value) + 1)); + strcpy(p_value, value); + const char *delimiter = " ,;"; + char *v = strtok(p_value, delimiter); + + while (v != NULL) { + if (strcmp(v, searchvalue) == 0) + { + return 1; + } + v = strtok(NULL, delimiter); + } + return 0; +} + static const char *g_datadir; const char *datapath(void) { diff --git a/src/kernel/config.h b/src/kernel/config.h index 352c9dcb6..4a1f23e25 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -389,10 +389,11 @@ extern "C" { const char *dbrace(const struct race *rc); - void set_param(struct param **p, const char *name, const char *data); - const char *get_param(const struct param *p, const char *name); - int get_param_int(const struct param *p, const char *name, int def); - float get_param_flt(const struct param *p, const char *name, float def); + void set_param(struct param **p, const char *key, const char *data); + const char *get_param(const struct param *p, const char *key); + int get_param_int(const struct param *p, const char *key, int def); + int check_param(const struct param *p, const char *key, const char *searchvalue); + float get_param_flt(const struct param *p, const char *key, float def); bool ExpensiveMigrants(void); int NMRTimeout(void); diff --git a/src/kernel/reports.c b/src/kernel/reports.c index d9a5d0a41..8758e9c97 100644 --- a/src/kernel/reports.c +++ b/src/kernel/reports.c @@ -1497,6 +1497,7 @@ static void prepare_reports(void) { region *r; faction *f; + building *b; const struct building_type *bt_lighthouse = bt_find("lighthouse"); for (f = factions; f; f = f->next) { @@ -1521,20 +1522,42 @@ static void prepare_reports(void) } } - for (u = r->units; u; u = u->next) { - if (u->building && u->building->type == bt_lighthouse) { - /* we are in a lighthouse. add the regions we can see from here! */ - prepare_lighthouse(u->building, u->faction); - } - - if (u_race(u) != get_race(RC_SPELL) || u->number == RS_FARVISION) { - if (fval(u, UFL_DISBELIEVES)) { - add_seen(u->faction->seen, r, see_unit, true); - } else { - add_seen(u->faction->seen, r, see_unit, false); + /* Region owner get always the Lighthouse report */ + if (check_param(global.parameters, "rules.region_owner_pay_building", bt_lighthouse->_name)) { + for (b = rbuildings(r); b; b = b->next) { + if (b && b->type == bt_lighthouse) { + u = building_owner(b); + if (u) { + prepare_lighthouse(b, u->faction); + if (u_race(u) != get_race(RC_SPELL) || u->number == RS_FARVISION) { + if (fval(u, UFL_DISBELIEVES)) { + add_seen(u->faction->seen, r, see_unit, true); + } + else { + add_seen(u->faction->seen, r, see_unit, false); + } + } + } + } + } } - } - } + + for (u = r->units; u; u = u->next) { + if (u->building && u->building->type == bt_lighthouse) { + /* we are in a lighthouse. add the regions we can see from here! */ + prepare_lighthouse(u->building, u->faction); + } + + if (u_race(u) != get_race(RC_SPELL) || u->number == RS_FARVISION) { + if (fval(u, UFL_DISBELIEVES)) { + add_seen(u->faction->seen, r, see_unit, true); + } + else { + add_seen(u->faction->seen, r, see_unit, false); + } + } + } + if (fval(r, RF_TRAVELUNIT)) { for (ru = a_find(r->attribs, &at_travelunit);