diff --git a/clibs b/clibs index 696505016..1854780fe 160000 --- a/clibs +++ b/clibs @@ -1 +1 @@ -Subproject commit 6965050165efdae89305a13bff06283229f143f4 +Subproject commit 1854780fe3073e491775836c22f709668b1fff62 diff --git a/iniparser b/iniparser index e3533ac0a..22741d9ce 160000 --- a/iniparser +++ b/iniparser @@ -1 +1 @@ -Subproject commit e3533ac0a45e43e9716c40f6a874bc6f41ddc96d +Subproject commit 22741d9ce9d19bf7b5f5a219b6ed0925259a4d1b diff --git a/res/translations/strings.de.po b/res/translations/strings.de.po index 5884eda83..8c90d6657 100644 --- a/res/translations/strings.de.po +++ b/res/translations/strings.de.po @@ -1708,7 +1708,7 @@ msgid "caravel_a" msgstr "eine Karavelle" msgid "galleon_a" -msgstr "eine Galleone" +msgstr "eine Galeone" msgctxt "keyword" msgid "describe" @@ -2068,7 +2068,7 @@ msgid "caravel" msgstr "Karavelle" msgid "galleon" -msgstr "Galleone" +msgstr "Galeone" msgid "dragon_postfix_10" msgstr "der Goldene" diff --git a/scripts/tests/report.lua b/scripts/tests/report.lua index b65bcc279..b02f4a908 100644 --- a/scripts/tests/report.lua +++ b/scripts/tests/report.lua @@ -94,7 +94,9 @@ function test_lighthouse() eressea.free_game() local r = region.create(0, 0, "mountain") local f = faction.create("human", "human@example.com") - region.create(1, 0, "mountain") + local f2 = faction.create("dwarf") + local r2 = region.create(1, 0, "mountain") + unit.create(f2, r2, 1).name = 'The Babadook' region.create(2, 0, "ocean") region.create(0, 1, "firewall") region.create(3, 0, "ocean") @@ -110,12 +112,13 @@ function test_lighthouse() init_reports() write_report(f) - assert_false(find_in_report(f, " %(1,0%) %(vom Turm erblickt%)")) + assert_false(find_in_report(f, "The Babadook")) + assert_true(find_in_report(f, " %(1,0%) %(vom Turm erblickt%)")) assert_true(find_in_report(f, " %(2,0%) %(vom Turm erblickt%)")) assert_true(find_in_report(f, " %(3,0%) %(vom Turm erblickt%)")) + assert_true(find_in_report(f, " %(0,1%) %(vom Turm erblickt%)")) assert_false(find_in_report(f, " %(0,0%) %(vom Turm erblickt%)")) - assert_false(find_in_report(f, " %(0,1%) %(vom Turm erblickt%)")) assert_false(find_in_report(f, " %(4,0%) %(vom Turm erblickt%)")) remove_report(f) end diff --git a/src/creport.c b/src/creport.c index fce3b8bff..1d3a32d48 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1503,33 +1503,34 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r) cr_output_messages(F, mlist, f); } } - /* buildings */ - for (b = rbuildings(r); b; b = b->next) { - int fno = -1; - u = building_owner(b); - if (u && !fval(u, UFL_ANON_FACTION)) { - const faction *sf = visible_faction(f, u); - fno = sf->no; - } - cr_output_building_compat(F, b, u, fno, f); - } - - /* ships */ - for (sh = r->ships; sh; sh = sh->next) { - int fno = -1; - u = ship_owner(sh); - if (u && !fval(u, UFL_ANON_FACTION)) { - const faction *sf = visible_faction(f, u); - fno = sf->no; + if (r->seen.mode >= seen_lighthouse) { + /* buildings */ + for (b = rbuildings(r); b; b = b->next) { + int fno = -1; + u = building_owner(b); + if (u && !fval(u, UFL_ANON_FACTION)) { + const faction *sf = visible_faction(f, u); + fno = sf->no; + } + cr_output_building_compat(F, b, u, fno, f); } - cr_output_ship_compat(F, sh, u, fno, f, r); - } + /* ships */ + for (sh = r->ships; sh; sh = sh->next) { + int fno = -1; + u = ship_owner(sh); + if (u && !fval(u, UFL_ANON_FACTION)) { + const faction *sf = visible_faction(f, u); + fno = sf->no; + } - /* visible units */ - for (u = r->units; u; u = u->next) { - if (visible_unit(u, f, stealthmod, r->seen.mode)) { - cr_output_unit_compat(F, f, u, r->seen.mode); + cr_output_ship_compat(F, sh, u, fno, f, r); + } + /* visible units */ + for (u = r->units; u; u = u->next) { + if (visible_unit(u, f, stealthmod, r->seen.mode)) { + cr_output_unit_compat(F, f, u, r->seen.mode); + } } } } diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 6ef070849..d25e0c911 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -318,7 +318,10 @@ int crew_skill(const ship *sh) { for (u = sh->region->units; u; u = u->next) { if (u->ship == sh) { - n += effskill(u, SK_SAILING, NULL) * u->number; + int es = effskill(u, SK_SAILING, NULL); + if (es >= sh->type->minskill) { + n += es * u->number; + } } } return n; diff --git a/src/kernel/ship.test.c b/src/kernel/ship.test.c index 71282cbd8..062e7cd20 100644 --- a/src/kernel/ship.test.c +++ b/src/kernel/ship.test.c @@ -384,27 +384,6 @@ static void test_stype_defaults(CuTest *tc) { test_teardown(); } -static void test_crew_skill(CuTest *tc) { - ship *sh; - region *r; - struct faction *f; - int i; - - test_setup(); - test_create_world(); - r = test_create_region(0, 0, NULL); - f = test_create_faction(NULL); - assert(r && f); - sh = test_create_ship(r, st_find("boat")); - for (i = 0; i != 4; ++i) { - unit * u = test_create_unit(f, r); - set_level(u, SK_SAILING, 5); - u->ship = sh; - } - CuAssertIntEquals(tc, 20, crew_skill(sh)); - test_teardown(); -} - static ship *setup_ship(void) { region *r; ship_type *stype; @@ -651,6 +630,35 @@ static void test_shipspeed_max_range(CuTest *tc) { test_teardown(); } +static void test_crew_skill(CuTest *tc) { + ship_type *stype; + ship * sh; + unit *u; + region *r; + + test_setup(); + stype = test_create_shiptype("kayak"); + CuAssertIntEquals(tc, 1, stype->minskill); + r = test_create_ocean(0, 0); + sh = test_create_ship(r, stype); + CuAssertIntEquals(tc, 0, crew_skill(sh)); + u = test_create_unit(test_create_faction(NULL), r); + set_level(u, SK_SAILING, 1); + CuAssertIntEquals(tc, 0, crew_skill(sh)); + u_set_ship(u, sh); + set_level(u, SK_SAILING, 1); + CuAssertIntEquals(tc, 1, crew_skill(sh)); + set_number(u, 10); + CuAssertIntEquals(tc, 10, crew_skill(sh)); + stype->minskill = 2; + CuAssertIntEquals(tc, 0, crew_skill(sh)); + set_level(u, SK_SAILING, 2); + CuAssertIntEquals(tc, 20, crew_skill(sh)); + set_level(u, SK_SAILING, 3); + CuAssertIntEquals(tc, 30, crew_skill(sh)); + test_teardown(); +} + CuSuite *get_ship_suite(void) { CuSuite *suite = CuSuiteNew(); diff --git a/src/kernel/types.h b/src/kernel/types.h index b67ee088a..82af31cdc 100644 --- a/src/kernel/types.h +++ b/src/kernel/types.h @@ -59,6 +59,7 @@ struct weapon_type; typedef enum { seen_none, seen_neighbour, + seen_lighthouse_land, seen_lighthouse, seen_travel, seen_unit, diff --git a/src/report.c b/src/report.c index e73760229..a6e55409d 100644 --- a/src/report.c +++ b/src/report.c @@ -750,7 +750,7 @@ static void append_message(sbstring *sbp, message *m, const faction * f) { sbp->end += size; } -static void prices(struct stream *out, const region * r, const faction * f) +static void report_prices(struct stream *out, const region * r, const faction * f) { const luxury_type *sale = NULL; struct demand *dmd; @@ -771,6 +771,7 @@ static void prices(struct stream *out, const region * r, const faction * f) m = msg_message("nr_market_sale", "product price", sale->itype->rtype, sale->price); + newline(out); nr_render(m, f->locale, buf, sizeof(buf), f); msg_release(m); sbs_adopt(&sbs, buf, sizeof(buf)); @@ -867,7 +868,8 @@ static void report_region_description(struct stream *out, const region * r, fact sbs_strcat(&sbs, LOC(f->locale, "see_neighbour")); sbs_strcat(&sbs, ")"); } - else if (r->seen.mode == seen_lighthouse) { + else if ((r->seen.mode == seen_lighthouse) + || (r->seen.mode == seen_lighthouse_land)) { sbs_strcat(&sbs, " ("); sbs_strcat(&sbs, LOC(f->locale, "see_lighthouse")); sbs_strcat(&sbs, ")"); @@ -1154,17 +1156,22 @@ void report_region(struct stream *out, const region * r, faction * f) } report_region_description(out, r, f, see); - report_region_schemes(out, r, f); - report_region_edges(out, r, f, edges, ne); + if (r->seen.mode >= seen_unit) { + report_region_schemes(out, r, f); + } + if (r->seen.mode >= seen_lighthouse) { + report_region_edges(out, r, f, edges, ne); + } } -static void statistics(struct stream *out, const region * r, const faction * f) +static void report_statistics(struct stream *out, const region * r, const faction * f) { int p = rpeasants(r); message *m; char buf[4096]; /* print */ + newline(out); m = msg_message("nr_stat_header", "region", r); nr_render(m, f->locale, buf, sizeof(buf), f); msg_release(m); @@ -1611,7 +1618,7 @@ static void allies(struct stream *out, const faction * f) } } -static void guards(struct stream *out, const region * r, const faction * see) +static void report_guards(struct stream *out, const region * r, const faction * see) { /* die Partei see sieht dies; wegen * "unbekannte Partei", wenn man es selbst ist... */ @@ -1810,12 +1817,10 @@ nr_building(struct stream *out, const region *r, const building *b, const factio } paragraph(out, buffer, 2, 0, 0); - if (r->seen.mode >= seen_lighthouse) { - nr_curses(out, 4, f, TYP_BUILDING, b); - } + nr_curses(out, 4, f, TYP_BUILDING, b); } -static void nr_paragraph(struct stream *out, message * m, faction * f) +static void nr_paragraph(struct stream *out, message * m, const faction * f) { char buf[4096]; @@ -1901,26 +1906,44 @@ static void cb_write_travelthru(region *r, unit *u, void *cbdata) { void report_travelthru(struct stream *out, region *r, const faction *f) { - int maxtravel; - assert(r); assert(f); - if (!fval(r, RF_TRAVELUNIT)) { - return; + if (fval(r, RF_TRAVELUNIT)) { + int maxtravel = count_travelthru(r, f); + + if (maxtravel > 0) { + cb_data cbdata; + char buf[8192]; + + newline(out); + init_cb(&cbdata, out, buf, sizeof(buf), f); + cbdata.maxtravel = maxtravel; + cbdata.writep += + str_strlcpy(buf, LOC(f->locale, "travelthru_header"), sizeof(buf)); + travelthru_map(r, cb_write_travelthru, &cbdata); + return; + } } +} - /* How many are we listing? For grammar. */ - maxtravel = count_travelthru(r, f); - if (maxtravel > 0) { - cb_data cbdata; - char buf[8192]; +static void report_market(stream * out, const region *r, const faction *f) { + const item_type *lux = r_luxury(r); + const item_type *herb = r->land->herbtype; + message * m = NULL; - init_cb(&cbdata, out, buf, sizeof(buf), f); - cbdata.maxtravel = maxtravel; - cbdata.writep += - str_strlcpy(buf, LOC(f->locale, "travelthru_header"), sizeof(buf)); - travelthru_map(r, cb_write_travelthru, &cbdata); - return; + if (herb && lux) { + m = msg_message("nr_market_info_p", "p1 p2", + lux->rtype, herb->rtype); + } + else if (lux) { + m = msg_message("nr_market_info_s", "p1", lux->rtype); + } + else if (herb) { + m = msg_message("nr_market_info_s", "p1", herb->rtype); + } + if (m) { + newline(out); + nr_paragraph(out, m, f); } } @@ -2124,121 +2147,92 @@ report_plaintext(const char *filename, report_context * ctx, for (r = ctx->first; r != ctx->last; r = r->next) { int stealthmod = stealth_modifier(r, f, r->seen.mode); - building *b = r->buildings; ship *sh = r->ships; - if (r->seen.mode < seen_lighthouse) - continue; - /* Beschreibung */ + if (r->seen.mode >= seen_lighthouse_land) { + rpline(out); + newline(out); + report_region(out, r, f); + } - rpline(out); - newline(out); if (r->seen.mode >= seen_unit) { anyunits = 1; - report_region(out, r, f); if (markets_module() && r->land) { - const item_type *lux = r_luxury(r); - const item_type *herb = r->land->herbtype; - - m = NULL; - if (herb && lux) { - m = msg_message("nr_market_info_p", "p1 p2", - lux->rtype, herb->rtype); - } - else if (lux) { - m = msg_message("nr_market_info_s", "p1",lux->rtype); - } - else if (herb) { - m = msg_message("nr_market_info_s", "p1", herb->rtype); - } - if (m) { - newline(out); - nr_paragraph(out, m, f); - } + report_market(out, r, f); } - else { - if (!fval(r->terrain, SEA_REGION) && rpeasants(r) / TRADE_FRACTION > 0) { - newline(out); - prices(out, r, f); - } + else if (!fval(r->terrain, SEA_REGION) && rpeasants(r) / TRADE_FRACTION > 0) { + report_prices(out, r, f); } - guards(out, r, f); - newline(out); + report_guards(out, r, f); report_travelthru(out, r, f); - } - else { - report_region(out, r, f); - newline(out); - report_travelthru(out, r, f); - } - - if (wants_stats && r->seen.mode >= seen_travel) { - if (r->land || r->seen.mode >= seen_unit) { - newline(out); - statistics(out, r, f); + if (wants_stats) { + report_statistics(out, r, f); } } + else if (r->seen.mode >= seen_lighthouse) { + report_travelthru(out, r, f); + } /* Nachrichten an REGION in der Region */ - if (r->seen.mode >= seen_travel) { + if (r->seen.mode >= seen_lighthouse) { message_list *mlist = r_getmessages(r, f); - newline(out); if (mlist) { struct mlist **split = merge_messages(mlist, r->msgs); newline(out); rp_messages(out, mlist, f, 0, false); split_messages(mlist, split); } - else { + else if (r->msgs) { + newline(out); rp_messages(out, r->msgs, f, 0, false); } - } - /* report all units. they are pre-sorted in an efficient manner */ - u = r->units; - while (b) { - while (b && (!u || u->building != b)) { - nr_building(out, r, b, f); - b = b->next; - } - if (b) { - nr_building(out, r, b, f); - while (u && u->building == b) { - if (visible_unit(u, f, stealthmod, r->seen.mode)) { - nr_unit(out, f, u, 6, r->seen.mode); + /* report all units. they are pre-sorted in an efficient manner */ + u = r->units; + if (r->seen.mode >= seen_travel) { + building *b = r->buildings; + while (b) { + while (b && (!u || u->building != b)) { + nr_building(out, r, b, f); + b = b->next; } - u = u->next; - } - b = b->next; - } - } - while (u && !u->ship) { - if (visible_unit(u, f, stealthmod, r->seen.mode)) { - nr_unit(out, f, u, 4, r->seen.mode); - } - assert(!u->building); - u = u->next; - } - while (sh) { - while (sh && (!u || u->ship != sh)) { - nr_ship(out, r, sh, f, NULL); - sh = sh->next; - } - if (sh) { - nr_ship(out, r, sh, f, u); - while (u && u->ship == sh) { - if (visible_unit(u, f, stealthmod, r->seen.mode)) { - nr_unit(out, f, u, 6, r->seen.mode); + if (b) { + nr_building(out, r, b, f); + while (u && u->building == b) { + if (visible_unit(u, f, stealthmod, r->seen.mode)) { + nr_unit(out, f, u, 6, r->seen.mode); + } + u = u->next; + } + b = b->next; } - u = u->next; } - sh = sh->next; } + while (u && !u->ship) { + if (visible_unit(u, f, stealthmod, r->seen.mode)) { + nr_unit(out, f, u, 4, r->seen.mode); + } + assert(!u->building); + u = u->next; + } + while (sh) { + while (sh && (!u || u->ship != sh)) { + nr_ship(out, r, sh, f, NULL); + sh = sh->next; + } + if (sh) { + nr_ship(out, r, sh, f, u); + while (u && u->ship == sh) { + if (visible_unit(u, f, stealthmod, r->seen.mode)) { + nr_unit(out, f, u, 6, r->seen.mode); + } + u = u->next; + } + sh = sh->next; + } + } + assert(!u); } - - assert(!u); - - newline(out); ERRNO_CHECK(); } if (!is_monsters(f)) { diff --git a/src/report.test.c b/src/report.test.c index b6696ea1b..030850906 100644 --- a/src/report.test.c +++ b/src/report.test.c @@ -260,7 +260,7 @@ static void test_report_travelthru(CuTest *tc) { out.api->rewind(out.handle); len = out.api->read(out.handle, buf, sizeof(buf)); buf[len] = '\0'; - CuAssertStrEquals_Msg(tc, "list one unit", "Durchreise: Hodor (1).\n", buf); + CuAssertStrEquals_Msg(tc, "list one unit", "\nDurchreise: Hodor (1).\n", buf); mstream_done(&out); mstream_init(&out); diff --git a/src/reports.c b/src/reports.c index 6e735223e..aa49c4653 100644 --- a/src/reports.c +++ b/src/reports.c @@ -102,6 +102,7 @@ const char *visibility[] = { "none", "neighbour", "lighthouse", + "lighthouse", "travel", "far", "unit", @@ -1115,38 +1116,40 @@ void get_addresses(report_context * ctx) } for (; r != NULL; r = r->next) { - int stealthmod = stealth_modifier(r, ctx->f, r->seen.mode); - if (r->seen.mode == seen_lighthouse) { - unit *u = r->units; - for (; u; u = u->next) { - faction *sf = visible_faction(ctx->f, u); - if (lastf != sf) { - if (u->building || u->ship || (stealthmod > INT_MIN - && cansee(ctx->f, r, u, stealthmod))) { - add_seen_faction_i(&flist, sf); - lastf = sf; + if (r->seen.mode >= seen_lighthouse) { + int stealthmod = stealth_modifier(r, ctx->f, r->seen.mode); + if (r->seen.mode == seen_lighthouse) { + unit *u = r->units; + for (; u; u = u->next) { + faction *sf = visible_faction(ctx->f, u); + if (lastf != sf) { + if (u->building || u->ship || (stealthmod > INT_MIN + && cansee(ctx->f, r, u, stealthmod))) { + add_seen_faction_i(&flist, sf); + lastf = sf; + } } } } - } - else if (r->seen.mode == seen_travel) { - /* when we travel through a region, then we must add - * the factions of any units we saw */ - add_travelthru_addresses(r, ctx->f, &flist, stealthmod); - } - else if (r->seen.mode > seen_travel) { - const unit *u = r->units; - while (u != NULL) { - if (u->faction != ctx->f) { - faction *sf = visible_faction(ctx->f, u); - bool ballied = sf && sf != ctx->f && sf != lastf - && !fval(u, UFL_ANON_FACTION) && cansee(ctx->f, r, u, stealthmod); - if (ballied || is_allied(ctx->f, sf)) { - add_seen_faction_i(&flist, sf); - lastf = sf; + else if (r->seen.mode == seen_travel) { + /* when we travel through a region, then we must add + * the factions of any units we saw */ + add_travelthru_addresses(r, ctx->f, &flist, stealthmod); + } + else if (r->seen.mode > seen_travel) { + const unit *u = r->units; + while (u != NULL) { + if (u->faction != ctx->f) { + faction *sf = visible_faction(ctx->f, u); + bool ballied = sf && sf != ctx->f && sf != lastf + && !fval(u, UFL_ANON_FACTION) && cansee(ctx->f, r, u, stealthmod); + if (ballied || is_allied(ctx->f, sf)) { + add_seen_faction_i(&flist, sf); + lastf = sf; + } } + u = u->next; } - u = u->next; } } } @@ -1294,7 +1297,7 @@ static void add_seen_lighthouse(region *r, faction *f) add_seen_nb(f, r, seen_lighthouse); } else { - add_seen_nb(f, r, seen_neighbour); + add_seen_nb(f, r, seen_lighthouse_land); } } diff --git a/src/reports.test.c b/src/reports.test.c index 7bea6c73c..0a85b75d2 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -573,7 +573,7 @@ static void test_prepare_lighthouse(CuTest *tc) { CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_lighthouse, r2->seen.mode); CuAssertIntEquals(tc, seen_neighbour, r3->seen.mode); - CuAssertIntEquals(tc, seen_neighbour, r4->seen.mode); + CuAssertIntEquals(tc, seen_lighthouse_land, r4->seen.mode); finish_reports(&ctx); test_teardown(); } @@ -868,6 +868,7 @@ static void test_visible_unit(CuTest *tc) { CuAssertTrue(tc, !visible_unit(u, f, 0, seen_travel)); CuAssertTrue(tc, !visible_unit(u, f, 0, seen_none)); CuAssertTrue(tc, !visible_unit(u, f, 0, seen_neighbour)); + CuAssertTrue(tc, !visible_unit(u, f, 0, seen_lighthouse_land)); CuAssertTrue(tc, visible_unit(u, f, 0, seen_lighthouse)); CuAssertTrue(tc, !visible_unit(u, f, -2, seen_lighthouse)); diff --git a/tests/run-turn.sh b/tests/run-turn.sh index 470cb6e2b..ad2e0e6b8 100755 --- a/tests/run-turn.sh +++ b/tests/run-turn.sh @@ -54,11 +54,11 @@ assert_grep_count reports/$CRFILE '^EINHEIT' 2 assert_grep_count reports/$CRFILE '^GEGENSTAENDE' 2 assert_grep_count reports/185-heg.cr '185;Runde' 1 -assert_grep_count reports/185-heg.cr ';Baeume' 2 -assert_grep_count reports/185-heg.cr '"B.ume";type' 2 -assert_grep_count reports/185-heg.cr '"Pferde";type' 2 -assert_grep_count reports/185-heg.nr 'erblickt' 2 -assert_grep_count reports/185-heg.cr '"lighthouse";visibility' 2 +assert_grep_count reports/185-heg.cr ';Baeume' 4 +assert_grep_count reports/185-heg.cr '"B.ume";type' 4 +assert_grep_count reports/185-heg.cr '"Pferde";type' 6 +assert_grep_count reports/185-heg.nr 'erblickt' 6 +assert_grep_count reports/185-heg.cr '"lighthouse";visibility' 6 assert_grep_count reports/185-heg.cr '"neighbour";visibility' 11 assert_grep_count reports/185-6rLo.cr '^EINHEIT' 2 assert_grep_count reports/185-6rLo.cr '^REGION' 13