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) { if (u->building == bld) { if (u->number > 0) { if (heir && last_owner && heir->faction != last_owner && u->faction == last_owner) { heir = u; break; /* we found someone from the same faction who is not dead. let's take this guy */ } else if (!heir) { heir = u; /* you'll do in an emergency */ } } } } if (!heir && config_token("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; }
faction *update_owners(region * r) { faction *f = NULL; assert(rule_region_owners()); if (r->land) { 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? */ unit *u = building_owner(blargest); f = region_get_owner(r); if (u == NULL) { if (f) { region_set_owner(r, NULL, turn); r->land->ownership->flags |= OWNER_MOURNING; f = NULL; } } else if (u->faction != f) { if (!r->land->ownership) { /* there has never been a prior owner */ region_set_morale(r, MORALE_DEFAULT, turn); } else { alliance *al = region_get_alliance(r); if (al && u->faction->alliance == al) { int morale = _max(0, r->land->morale - MORALE_TRANSFER); region_set_morale(r, morale, turn); } else { region_set_morale(r, MORALE_TAKEOVER, turn); if (f) { r->land->ownership->flags |= OWNER_MOURNING; } } } region_set_owner(r, u->faction, turn); f = u->faction; } } } else if (r->land->ownership && r->land->ownership->owner) { r->land->ownership->flags |= OWNER_MOURNING; region_set_owner(r, NULL, turn); f = NULL; } } return f; }
void morale_update(region *r) { int morale = region_get_morale(r); assert(r->land); if (r->land->ownership && r->land->ownership->owner) { int stability = turn - r->land->ownership->morale_turn; int maxmorale = MORALE_DEFAULT; building *b = largestbuilding(r, cmp_taxes, false); if (b) { int bsize = buildingeffsize(b, false); assert(b->type->taxes>0); maxmorale = (bsize + 1) * MORALE_TAX_FACTOR / b->type->taxes; } if (morale < maxmorale) { if (stability > MORALE_COOLDOWN && r->land->ownership->owner && morale < MORALE_MAX) { double ch = popularity(); if (is_cursed(r->attribs, &ct_generous)) { ch *= 1.2; /* 20% improvement */ } if (stability >= MORALE_AVERAGE * 2 || chance(ch)) { region_set_morale(r, morale + 1, turn); } } } else if (morale > maxmorale) { region_set_morale(r, morale - 1, turn); } } else if (morale > MORALE_DEFAULT) { region_set_morale(r, morale - 1, turn); } }
static void test_cmp_current_owner(CuTest *tc) { region *r; building *b1, *b2; building_type *btype; unit *u1, *u2; test_setup(); config_set("rules.region_owners", "1"); r = test_create_region(0, 0, NULL); btype = test_create_buildingtype("watch"); btype->stages->construction->maxsize = 1; btype->taxes = 200; b1 = test_create_building(r, btype); btype = test_create_buildingtype("castle"); btype->stages->construction->maxsize = 1; btype->taxes = 100; b2 = test_create_building(r, btype); b1->size = 1; CuAssertIntEquals(tc, 1, buildingeffsize(b1, false)); b2->size = 1; CuAssertIntEquals(tc, 1, buildingeffsize(b2, false)); u1 = test_create_unit(test_create_faction(NULL), r); u_set_building(u1, b1); u2 = test_create_unit(test_create_faction(NULL), r); u_set_building(u2, b2); region_set_owner(r, u1->faction, turn); CuAssertPtrEquals(tc, b1, largestbuilding(r, cmp_current_owner, false)); CuAssertTrue(tc, cmp_current_owner(b2, b1) < 0); CuAssertTrue(tc, cmp_current_owner(b1, b2) > 0); CuAssertTrue(tc, cmp_current_owner(b1, b1) == 0); test_teardown(); }
static void test_largestbuilding(CuTest *tc) { region *r; building *b1, *b2; test_setup(); r = test_create_region(0, 0, NULL); CuAssertPtrEquals(tc, NULL, largestbuilding(r, cmp_size, false)); b1 = test_create_building(r, NULL); b2 = test_create_building(r, NULL); b1->size = 1; b2->size = 1; CuAssertPtrEquals(tc, b1, largestbuilding(r, cmp_size, false)); b1->size = 2; CuAssertPtrEquals(tc, b1, largestbuilding(r, cmp_size, false)); b2->size = 3; CuAssertPtrEquals(tc, b2, largestbuilding(r, cmp_size, false)); test_teardown(); }
static void test_cmp_wage(CuTest *tc) { region *r; building *b1, *b2; building_type *btype; test_setup(); btype = test_create_buildingtype("castle"); btype->taxes = 100; r = test_create_region(0, 0, NULL); b1 = test_create_building(r, btype); b2 = test_create_building(r, btype); b1->size = 5; b2->size = 10; CuAssertPtrEquals(tc, b2, largestbuilding(r, cmp_wage, false)); CuAssertTrue(tc, cmp_wage(b1, b2) < 0); CuAssertTrue(tc, cmp_wage(b2, b1) > 0); CuAssertTrue(tc, cmp_wage(b1, b1) == 0); test_teardown(); }
static bool is_guardian_r(const unit * guard) { if (guard->number == 0) return false; if (besieged(guard)) return false; /* if region_owners exist then they may be guardians: */ if (guard->building && rule_region_owners() && guard == building_owner(guard->building)) { faction *owner = region_get_owner(guard->region); if (owner == guard->faction) { building *bowner = largestbuilding(guard->region, &cmp_taxes, false); if (bowner == guard->building) { return true; } } } if ((guard->flags & UFL_GUARD) == 0) return false; return fval(u_race(guard), RCF_UNARMEDGUARD) || is_monsters(guard->faction) || (armedmen(guard, true) > 0); }
static void test_cmp_taxes(CuTest *tc) { region *r; building *b1, *b2; building_type *btype; unit *u1, *u2; test_setup(); btype = test_create_buildingtype("castle"); btype->taxes = 100; r = test_create_region(0, 0, NULL); b1 = test_create_building(r, btype); b2 = test_create_building(r, btype); b1->size = 5; b2->size = 10; u1 = test_create_unit(test_create_faction(NULL), r); u_set_building(u1, b1); u2 = test_create_unit(test_create_faction(NULL), r); u_set_building(u2, b2); CuAssertPtrEquals(tc, b2, largestbuilding(r, cmp_taxes, false)); CuAssertTrue(tc, cmp_taxes(b1, b2) < 0); CuAssertTrue(tc, cmp_taxes(b2, b1) > 0); CuAssertTrue(tc, cmp_taxes(b1, b1) == 0); test_teardown(); }