building and ownership fixed big time

http://bugs.eressea.de/view.php?id=1595
This commit is contained in:
Enno Rehling 2009-08-24 20:55:20 +00:00
parent e870de474e
commit 1b6dd9fe5a
9 changed files with 75 additions and 31 deletions

View File

@ -641,7 +641,7 @@ give_control(unit * u, unit * u2)
region * r = u->region; region * r = u->region;
faction * f = region_get_owner(r); faction * f = region_get_owner(r);
if (f==u->faction) { if (f==u->faction) {
building * b = largestbuilding(r, &is_owner_building, false); building * b = largestbuilding(r, &cmp_current_owner, false);
if (b==u->building) { if (b==u->building) {
int morale = region_get_morale(r); int morale = region_get_morale(r);
region_set_owner(r, u2->faction, turn); region_set_owner(r, u2->faction, turn);

View File

@ -1554,7 +1554,7 @@ display_cmd(unit * u, struct order * ord)
cmistake(u, ord, 148, MSG_EVENT); cmistake(u, ord, 148, MSG_EVENT);
break; break;
} }
if (b != largestbuilding(r, &is_owner_building, false)) { if (b != largestbuilding(r, &cmp_current_owner, false)) {
cmistake(u, ord, 147, MSG_EVENT); cmistake(u, ord, 147, MSG_EVENT);
break; break;
} }
@ -1797,7 +1797,7 @@ name_cmd(unit * u, struct order * ord)
cmistake(u, ord, 148, MSG_EVENT); cmistake(u, ord, 148, MSG_EVENT);
break; break;
} }
if (b != largestbuilding(r, &is_owner_building, false)) { if (b != largestbuilding(r, &cmp_current_owner, false)) {
cmistake(u, ord, 147, MSG_EVENT); cmistake(u, ord, 147, MSG_EVENT);
break; break;
} }

View File

@ -61,7 +61,7 @@ typedef struct building_type {
void (*init)(struct building_type*); void (*init)(struct building_type*);
void (*age)(struct building *); void (*age)(struct building *);
int (*protection)(struct building *, struct unit *); int (*protection)(struct building *, struct unit *);
double (*taxes)(struct building *, int size); double (*taxes)(const struct building *, int size);
struct attrib * attribs; struct attrib * attribs;
} building_type; } building_type;

View File

@ -1689,21 +1689,17 @@ cstring(const char *s)
} }
building * 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; building *b, *best = NULL;
/* durch die verw. von '>' statt '>=' werden die aelteren burgen
* bevorzugt. */
for (b = rbuildings(r); b; b = b->next) { for (b = rbuildings(r); b; b = b->next) {
if (eval && !eval(b)) continue; if (cmp_gt(b, best)<=0) continue;
if (!imaginary) { if (!imaginary) {
const attrib * a = a_find(b->attribs, &at_icastle); const attrib * a = a_find(b->attribs, &at_icastle);
if (a) continue; if (a) continue;
} }
if (best==NULL || b->size > best->size) { best = b;
best = b;
}
} }
return best; return best;
} }
@ -2614,12 +2610,17 @@ static const int wagetable[7][4] = {
{15, 13, 16, 2} /* Zitadelle */ {15, 13, 16, 2} /* Zitadelle */
}; };
boolean int
is_castle(const struct building * b) cmp_wage(const struct building * b, const building * a)
{ {
static const struct building_type * bt_castle; static const struct building_type * bt_castle;
if (!bt_castle) bt_castle = bt_find("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) boolean is_owner_building(const struct building * b)
@ -2632,13 +2633,57 @@ boolean is_owner_building(const struct building * b)
return false; 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) { if (b->type->taxes) {
unit * u = buildingowner(b->region, b); if (a) {
return u!=NULL; 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 (newtaxes<oldtaxes) return -1;
else if (newtaxes>oldtaxes) return 1;
else if (b->size<a->size) 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 (newtaxes<oldtaxes) return -1;
else if (newtaxes>oldtaxes) return 1;
return 0;
} else {
return 1;
}
}
return -1;
} }
int rule_auto_taxation(void) int rule_auto_taxation(void)
@ -2651,7 +2696,7 @@ int rule_auto_taxation(void)
static int static int
default_wage(const region *r, const faction * f, const race * rc, int in_turn) 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; int esize = 0;
curse * c; curse * c;
double wage; double wage;

View File

@ -244,10 +244,10 @@ extern char *cstring_i(char *s);
extern const char *unitname(const struct unit * u); extern const char *unitname(const struct unit * u);
extern char * write_unitname(const struct unit * u, char * buffer, size_t size); 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); struct building *largestbuilding(const struct region * r, int (*eval_gt)(const struct building *,const struct building *), boolean imaginary);
boolean is_castle(const struct building * b); int cmp_wage(const struct building * b, const struct building * bother);
boolean is_tax_building(const struct building * b); int cmp_taxes(const struct building * b, const struct building * bother);
boolean is_owner_building(const struct building * b); int cmp_current_owner(const struct building * b, const struct building * bother);
#define TAX_ORDER 0x00 #define TAX_ORDER 0x00
#define TAX_OWNER 0x01 #define TAX_OWNER 0x01

View File

@ -909,7 +909,7 @@ is_guardian_r(const unit * guard)
if (guard->building && fval(guard, UFL_OWNER)) { if (guard->building && fval(guard, UFL_OWNER)) {
faction * owner = region_get_owner(guard->region); faction * owner = region_get_owner(guard->region);
if (owner==guard->faction) { 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) { if (bowner==guard->building) {
return true; return true;
} }

View File

@ -1476,8 +1476,8 @@ faction * update_owners(region * r)
{ {
faction * f = NULL; faction * f = NULL;
if (r->land) { if (r->land) {
building * bowner = largestbuilding(r, &is_owner_building, false); building * bowner = largestbuilding(r, &cmp_current_owner, false);
building * blargest = largestbuilding(r, &is_tax_building, false); building * blargest = largestbuilding(r, &cmp_taxes, false);
if (blargest) { if (blargest) {
if (!bowner || bowner->size<blargest->size) { if (!bowner || bowner->size<blargest->size) {
/* region owners update? */ /* region owners update? */

View File

@ -320,7 +320,7 @@ parse_buildings(xmlDocPtr doc)
} else if (strcmp((const char*)propValue, "protection")==0) { } else if (strcmp((const char*)propValue, "protection")==0) {
btype->protection = (int (*)(struct building*, struct unit *))fun; btype->protection = (int (*)(struct building*, struct unit *))fun;
} else if (strcmp((const char*)propValue, "taxes")==0) { } 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) { } else if (strcmp((const char*)propValue, "age")==0) {
btype->age = (void (*)(struct building*))fun; btype->age = (void (*)(struct building*))fun;
} else { } else {

View File

@ -268,8 +268,6 @@ local function test_recruit2()
u:add_order("REKRUTIERE 1 mensch") u:add_order("REKRUTIERE 1 mensch")
u:add_order("REKRUTIERE 1") u:add_order("REKRUTIERE 1")
process_orders() process_orders()
print(u:get_item("money"))
print(u.number)
end end
local function test_owners() local function test_owners()
@ -678,8 +676,9 @@ tests = {
["market"] = test_market ["market"] = test_market
} }
mytests = { mytests = {
-- ["blessed"] = test_blessed -- foiled by peasantgrowth ["morale"] = test_morale,
["morale"] = test_morale ["taxes"] = test_taxes,
["owners"] = test_owners
} }
fail = 0 fail = 0
for k, v in pairs(tests) do for k, v in pairs(tests) do