diff --git a/src/lighthouse.c b/src/lighthouse.c index 96b42b333..dd1183558 100644 --- a/src/lighthouse.c +++ b/src/lighthouse.c @@ -73,13 +73,11 @@ int lighthouse_range(const building * b, const faction * f) region *r = b->region; int c = 0; int cap = buildingcapacity(b); - unit *u; + unit *u, *uown = building_owner(b); for (u = r->units; u; u = u->next) { - if (u->building == b || u == building_owner(b)) { - if (u->building == b) { - c += u->number; - } + if (u->building == b || u == uown) { + c += u->number; if (c > cap) { break; } diff --git a/src/reports.c b/src/reports.c index dc0edf1b3..5a7f29a10 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1170,11 +1170,9 @@ static void add_seen_nb(faction *f, region *r, seen_mode mode) { /** mark all regions seen by the lighthouse. */ -static void prepare_lighthouse(building * b, report_context *ctx) +static void prepare_lighthouse(faction *f, region *r, int range) { - faction *f = ctx->f; - int range = lighthouse_range(b, f); - quicklist *ql, *rlist = get_regions_distance(b->region, range); + quicklist *ql, *rlist = get_regions_distance(r, range); int qi; for (ql = rlist, qi = 0; ql; ql_advance(&ql, &qi, 1)) { @@ -1316,7 +1314,6 @@ static void cb_add_seen(region *r, unit *u, void *cbdata) { void prepare_report(report_context *ctx, faction *f) { region *r; - building *b; static int config; static bool rule_region_owners; const struct building_type *bt_lighthouse = bt_find("lighthouse"); @@ -1334,34 +1331,36 @@ void prepare_report(report_context *ctx, faction *f) ctx->last = lastregion(f); for (r = ctx->first; r!=ctx->last; r = r->next) { + int range = 0; unit *u; + if (fval(r, RF_LIGHTHOUSE) && bt_lighthouse) { + if (rule_region_owners && f == region_get_owner(r)) { + /* region owners get the report from lighthouses */ + building *b; - if (fval(r, RF_LIGHTHOUSE)) { - /* region owners get the report from lighthouses */ - if (rule_region_owners && bt_lighthouse) { - for (b = rbuildings(r); b; b = b->next) { - if (b && b->type == bt_lighthouse) { - u = building_owner(b); - if (u && u->faction==f) { - prepare_lighthouse(b, ctx); - add_seen_nb(f, r, seen_unit); - } + for (b = r->buildings; b; b = b->next) { + if (b->type == bt_lighthouse) { + int br = lighthouse_range(b, NULL); + if (br > range) range = br; } } } - } for (u = r->units; u; u = u->next) { - if (u->faction==f) { + if (u->faction == f) { add_seen_nb(f, r, seen_unit); - if (fval(r, RF_LIGHTHOUSE)) { + if (fval(r, RF_LIGHTHOUSE) && bt_lighthouse) { if (u->building && u->building->type == bt_lighthouse && inside_building(u)) { - /* we are in a lighthouse. add the regions we can see from here! */ - prepare_lighthouse(u->building, ctx); + int br = lighthouse_range(u->building, f); + if (br > range) range = br; } } } } + if (range > 0) { + /* we are in at least one lighthouse. add the regions we can see from here! */ + prepare_lighthouse(f, r, range); + } if (fval(r, RF_TRAVELUNIT) && r->seen.mode #include #include #include @@ -344,6 +345,43 @@ static void test_prepare_lighthouse(CuTest *tc) { test_cleanup(); } +static void test_prepare_lighthouse_owners(CuTest *tc) { + report_context ctx; + faction *f; + region *r1, *r2, *r3; + unit *u; + building *b; + building_type *btype; + const struct terrain_type *t_ocean, *t_plain; + + test_setup(); + config_set("rules.region_owner_pay_building", "lighthouse"); + config_set("rules.region_owners", "1"); + t_ocean = test_create_terrain("ocean", SEA_REGION); + t_plain = test_create_terrain("plain", LAND_REGION); + f = test_create_faction(0); + r1 = test_create_region(0, 0, t_plain); + r2 = test_create_region(1, 0, t_ocean); + r3 = test_create_region(2, 0, t_ocean); + btype = test_create_buildingtype("lighthouse"); + b = test_create_building(r1, btype); + b->flags |= BLD_MAINTAINED; + b->size = 10; + update_lighthouse(b); + u = test_create_unit(f, r1); + u = test_create_unit(test_create_faction(0), r1); + u->building = b; + set_level(u, SK_PERCEPTION, 3); + region_set_owner(b->region, f, 0); + prepare_report(&ctx, f); + CuAssertPtrEquals(tc, r1, ctx.first); + CuAssertPtrEquals(tc, NULL, ctx.last); + CuAssertIntEquals(tc, seen_unit, r1->seen.mode); + CuAssertIntEquals(tc, seen_lighthouse, r2->seen.mode); + CuAssertIntEquals(tc, seen_neighbour, r3->seen.mode); + test_cleanup(); +} + static void test_prepare_report(CuTest *tc) { report_context ctx; faction *f; @@ -432,6 +470,7 @@ CuSuite *get_reports_suite(void) SUITE_ADD_TEST(suite, test_seen_neighbours); SUITE_ADD_TEST(suite, test_seen_travelthru); SUITE_ADD_TEST(suite, test_prepare_lighthouse); + SUITE_ADD_TEST(suite, test_prepare_lighthouse_owners); SUITE_ADD_TEST(suite, test_prepare_lighthouse_capacity); SUITE_ADD_TEST(suite, test_prepare_travelthru); SUITE_ADD_TEST(suite, test_reorder_units);