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;
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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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 (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)
@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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->size<blargest->size) {
/* region owners update? */

View File

@ -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 {

View File

@ -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