diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 949a0cf72..3a4fe6a11 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -641,7 +641,7 @@ give_control(unit * u, unit * u2) region * r = u->region; faction * f = region_get_owner(r); if (f==u->faction) { - building * b = largestbuilding(r, &is_owner_building, false); + building * b = largestbuilding(r, &cmp_current_owner, false); if (b==u->building) { int morale = region_get_morale(r); region_set_owner(r, u2->faction, turn); diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 793391d30..9f124d8cd 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -1554,7 +1554,7 @@ display_cmd(unit * u, struct order * ord) cmistake(u, ord, 148, MSG_EVENT); break; } - if (b != largestbuilding(r, &is_owner_building, false)) { + if (b != largestbuilding(r, &cmp_current_owner, false)) { cmistake(u, ord, 147, MSG_EVENT); break; } @@ -1797,7 +1797,7 @@ name_cmd(unit * u, struct order * ord) cmistake(u, ord, 148, MSG_EVENT); break; } - if (b != largestbuilding(r, &is_owner_building, false)) { + if (b != largestbuilding(r, &cmp_current_owner, false)) { cmistake(u, ord, 147, MSG_EVENT); break; } diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index f6e38f3af..b471b69d9 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -61,7 +61,7 @@ typedef struct building_type { void (*init)(struct building_type*); void (*age)(struct building *); int (*protection)(struct building *, struct unit *); - double (*taxes)(struct building *, int size); + double (*taxes)(const struct building *, int size); struct attrib * attribs; } building_type; diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index b4d2f3005..5c532781f 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -1689,21 +1689,17 @@ cstring(const char *s) } building * -largestbuilding(const region * r, boolean (*eval)(const struct building *), boolean imaginary) +largestbuilding(const region * r, int (*cmp_gt)(const struct building *, const struct building *), boolean imaginary) { building *b, *best = NULL; - /* durch die verw. von '>' statt '>=' werden die aelteren burgen - * bevorzugt. */ for (b = rbuildings(r); b; b = b->next) { - if (eval && !eval(b)) continue; + if (cmp_gt(b, best)<=0) continue; if (!imaginary) { const attrib * a = a_find(b->attribs, &at_icastle); if (a) continue; } - if (best==NULL || b->size > best->size) { - best = b; - } + best = b; } return best; } @@ -2614,12 +2610,17 @@ static const int wagetable[7][4] = { {15, 13, 16, 2} /* Zitadelle */ }; -boolean -is_castle(const struct building * b) +int +cmp_wage(const struct building * b, const building * a) { static const struct building_type * bt_castle; if (!bt_castle) bt_castle = bt_find("castle"); - return (b->type==bt_castle); + if (b->type==bt_castle) { + if (!a) return 1; + if (b->size>a->size) return 1; + if (b->size==a->size) return 0; + } + return -1; } boolean is_owner_building(const struct building * b) @@ -2632,13 +2633,57 @@ boolean is_owner_building(const struct building * b) return false; } -boolean is_tax_building(const building * b) +int +cmp_taxes(const building * b, const building * a) { + faction * f = region_get_owner(b->region); if (b->type->taxes) { - unit * u = buildingowner(b->region, b); - return u!=NULL; + if (a) { + int newsize = buildingeffsize(b, false); + double newtaxes = b->type->taxes(b, newsize); + int oldsize = buildingeffsize(a, false); + double oldtaxes = a->type->taxes(a, oldsize); + + if (newtaxesoldtaxes) return 1; + else if (b->sizesize) return -1; + else if (b->size>a->size) return 1; + else { + unit * u = buildingowner(b->region, b); + if (u && u->faction==f) { + u = buildingowner(a->region, a); + if (u && u->faction==f) return -1; + return 1; + } + } + } else { + return 1; + } } - return false; + return -1; +} + +int +cmp_current_owner(const building * b, const building * a) +{ + faction * f = region_get_owner(b->region); + if (f && b->type->taxes) { + unit * u = buildingowner(b->region, b); + if (!u || u->faction!=f) return -1; + if (a) { + int newsize = buildingeffsize(b, false); + double newtaxes = b->type->taxes(b, newsize); + int oldsize = buildingeffsize(a, false); + double oldtaxes = a->type->taxes(a, oldsize); + + if (newtaxesoldtaxes) return 1; + return 0; + } else { + return 1; + } + } + return -1; } int rule_auto_taxation(void) @@ -2651,7 +2696,7 @@ int rule_auto_taxation(void) static int default_wage(const region *r, const faction * f, const race * rc, int in_turn) { - building *b = largestbuilding(r, &is_castle, false); + building *b = largestbuilding(r, &cmp_wage, false); int esize = 0; curse * c; double wage; diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 85e5a0306..d8bd245af 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -244,10 +244,10 @@ extern char *cstring_i(char *s); extern const char *unitname(const struct unit * u); extern char * write_unitname(const struct unit * u, char * buffer, size_t size); -struct building *largestbuilding(const struct region * r, boolean (*eval)(const struct building *), boolean imaginary); -boolean is_castle(const struct building * b); -boolean is_tax_building(const struct building * b); -boolean is_owner_building(const struct building * b); +struct building *largestbuilding(const struct region * r, int (*eval_gt)(const struct building *,const struct building *), boolean imaginary); +int cmp_wage(const struct building * b, const struct building * bother); +int cmp_taxes(const struct building * b, const struct building * bother); +int cmp_current_owner(const struct building * b, const struct building * bother); #define TAX_ORDER 0x00 #define TAX_OWNER 0x01 diff --git a/src/common/kernel/move.c b/src/common/kernel/move.c index 736929538..da82eedc2 100644 --- a/src/common/kernel/move.c +++ b/src/common/kernel/move.c @@ -909,7 +909,7 @@ is_guardian_r(const unit * guard) if (guard->building && fval(guard, UFL_OWNER)) { faction * owner = region_get_owner(guard->region); if (owner==guard->faction) { - building * bowner = largestbuilding(guard->region, &is_owner_building, false); + building * bowner = largestbuilding(guard->region, &cmp_taxes, false); if (bowner==guard->building) { return true; } diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 313e0a3a2..ef2bdcc99 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -1476,8 +1476,8 @@ faction * update_owners(region * r) { faction * f = NULL; if (r->land) { - building * bowner = largestbuilding(r, &is_owner_building, false); - building * blargest = largestbuilding(r, &is_tax_building, false); + building * bowner = largestbuilding(r, &cmp_current_owner, false); + building * blargest = largestbuilding(r, &cmp_taxes, false); if (blargest) { if (!bowner || bowner->sizesize) { /* region owners update? */ diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index 3a1add737..6561696aa 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -320,7 +320,7 @@ parse_buildings(xmlDocPtr doc) } else if (strcmp((const char*)propValue, "protection")==0) { btype->protection = (int (*)(struct building*, struct unit *))fun; } else if (strcmp((const char*)propValue, "taxes")==0) { - btype->taxes = (double (*)(struct building*, int))fun; + btype->taxes = (double (*)(const struct building*, int))fun; } else if (strcmp((const char*)propValue, "age")==0) { btype->age = (void (*)(struct building*))fun; } else { diff --git a/src/scripts/tests.lua b/src/scripts/tests.lua index 249b7dd04..8a45f192a 100644 --- a/src/scripts/tests.lua +++ b/src/scripts/tests.lua @@ -268,8 +268,6 @@ local function test_recruit2() u:add_order("REKRUTIERE 1 mensch") u:add_order("REKRUTIERE 1") process_orders() - print(u:get_item("money")) - print(u.number) end local function test_owners() @@ -678,8 +676,9 @@ tests = { ["market"] = test_market } mytests = { --- ["blessed"] = test_blessed -- foiled by peasantgrowth - ["morale"] = test_morale + ["morale"] = test_morale, + ["taxes"] = test_taxes, + ["owners"] = test_owners } fail = 0 for k, v in pairs(tests) do