From de7248fb5a6ecc1fefa11a396394cfa6ac48dedb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 13 Jul 2018 22:45:17 +0200 Subject: [PATCH 01/17] BUG 2457: Einheiten werden bei Durchreise nicht angezeigt. --- clibs | 2 +- src/reports.c | 6 ++- src/reports.test.c | 112 +++++++++++++++++++++++++++------------------ storage | 2 +- 4 files changed, 74 insertions(+), 48 deletions(-) diff --git a/clibs b/clibs index f9842e07a..d86c85254 160000 --- a/clibs +++ b/clibs @@ -1 +1 @@ -Subproject commit f9842e07a442c5453c270badf25ab72633b4edf5 +Subproject commit d86c8525489d7f11b7ba13e101bb59ecf160b871 diff --git a/src/reports.c b/src/reports.c index 06f6b0084..c30587534 100644 --- a/src/reports.c +++ b/src/reports.c @@ -2446,8 +2446,10 @@ bool visible_unit(const unit *u, const faction *f, int stealthmod, seen_mode mod return true; } else { - if (stealthmod > INT_MIN && (mode == seen_lighthouse || mode >= seen_unit)) { - return cansee(f, u->region, u, stealthmod); + if (stealthmod > INT_MIN && mode >= seen_lighthouse) { + if (mode != seen_travel || u->building || u->ship || is_guard(u)) { + return cansee(f, u->region, u, stealthmod); + } } } return false; diff --git a/src/reports.test.c b/src/reports.test.c index 2b22782ae..120af4118 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -1,7 +1,7 @@ #include #include "reports.h" -#include "kernel/calendar.h" +#include "guard.h" #include "keyword.h" #include "lighthouse.h" #include "laws.h" @@ -10,28 +10,29 @@ #include "spy.h" #include "travelthru.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "kernel/ally.h" +#include "kernel/calendar.h" +#include "kernel/config.h" +#include "kernel/building.h" +#include "kernel/faction.h" +#include "kernel/item.h" +#include "kernel/race.h" +#include "kernel/region.h" +#include "kernel/ship.h" +#include "kernel/terrain.h" +#include "kernel/unit.h" +#include "kernel/spell.h" +#include "kernel/spellbook.h" +#include "kernel/terrain.h" -#include -#include -#include -#include +#include "util/attrib.h" +#include "util/language.h" +#include "util/lists.h" +#include "util/message.h" -#include -#include -#include +#include "attributes/attributes.h" +#include "attributes/key.h" +#include "attributes/otherfaction.h" #include #include @@ -824,38 +825,61 @@ static void test_newbie_warning(CuTest *tc) { } static void test_visible_unit(CuTest *tc) { - unit *u2; + unit *u; faction *f; ship *sh; + building *b; + race *rc; test_setup(); f = test_create_faction(NULL); - u2 = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); - sh = test_create_ship(u2->region, NULL); + rc = test_create_race("smurf"); + rc->flags |= RCF_UNARMEDGUARD; + u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); - CuAssertTrue(tc, cansee(f, u2->region, u2, 0)); - CuAssertTrue(tc, visible_unit(u2, f, 0, seen_unit)); - CuAssertTrue(tc, visible_unit(u2, f, 0, seen_spell)); - CuAssertTrue(tc, visible_unit(u2, f, 0, seen_battle)); - CuAssertTrue(tc, !visible_unit(u2, f, 0, seen_travel)); - CuAssertTrue(tc, !visible_unit(u2, f, 0, seen_none)); - CuAssertTrue(tc, !visible_unit(u2, f, 0, seen_neighbour)); + CuAssertTrue(tc, cansee(f, u->region, u, 0)); + CuAssertTrue(tc, visible_unit(u, f, 0, seen_unit)); + CuAssertTrue(tc, visible_unit(u, f, 0, seen_spell)); + CuAssertTrue(tc, visible_unit(u, f, 0, seen_battle)); + 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(u2, f, 0, seen_lighthouse)); - CuAssertTrue(tc, !visible_unit(u2, f, -2, seen_lighthouse)); - u2->ship = sh; - CuAssertTrue(tc, visible_unit(u2, f, -2, seen_lighthouse)); - u2->ship = NULL; + CuAssertTrue(tc, visible_unit(u, f, 0, seen_lighthouse)); + CuAssertTrue(tc, !visible_unit(u, f, -2, seen_lighthouse)); - set_level(u2, SK_STEALTH, 1); - CuAssertTrue(tc, !cansee(f, u2->region, u2, 0)); - CuAssertTrue(tc, cansee(f, u2->region, u2, 1)); + u->ship = sh = test_create_ship(u->region, NULL); + CuAssertTrue(tc, visible_unit(u, f, -2, seen_travel)); + CuAssertTrue(tc, visible_unit(u, f, -2, seen_lighthouse)); + u->ship = NULL; - u2->ship = sh; - CuAssertTrue(tc, visible_unit(u2, f, -2, seen_lighthouse)); - u2->ship = NULL; - CuAssertTrue(tc, visible_unit(u2, f, 1, seen_spell)); - CuAssertTrue(tc, visible_unit(u2, f, 1, seen_battle)); + setguard(u, true); + CuAssertTrue(tc, is_guard(u)); + CuAssertTrue(tc, visible_unit(u, f, -2, seen_travel)); + CuAssertTrue(tc, visible_unit(u, f, -2, seen_lighthouse)); + setguard(u, false); + + u->building = b = test_create_building(u->region, NULL); + CuAssertTrue(tc, visible_unit(u, f, -2, seen_travel)); + CuAssertTrue(tc, visible_unit(u, f, -2, seen_lighthouse)); + u->building = NULL; + + set_level(u, SK_STEALTH, 1); + CuAssertTrue(tc, !cansee(f, u->region, u, 0)); + CuAssertTrue(tc, cansee(f, u->region, u, 1)); + + u->ship = sh; + CuAssertTrue(tc, visible_unit(u, f, -2, seen_lighthouse)); + CuAssertTrue(tc, visible_unit(u, f, -2, seen_travel)); + u->ship = NULL; + + u->building = b; + CuAssertTrue(tc, visible_unit(u, f, -2, seen_lighthouse)); + CuAssertTrue(tc, visible_unit(u, f, -2, seen_travel)); + u->building = NULL; + + CuAssertTrue(tc, visible_unit(u, f, 1, seen_spell)); + CuAssertTrue(tc, visible_unit(u, f, 1, seen_battle)); test_teardown(); } diff --git a/storage b/storage index 5623ee652..0ef4b39e3 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit 5623ee6527e97af20c7d8efc03800b6fe1579744 +Subproject commit 0ef4b39e39d8146d6ca323500a285c53843db988 From ced21cc336971286f72bce5d047624b52768ecce Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 13 Jul 2018 23:37:45 +0200 Subject: [PATCH 02/17] BUG 2459 Regionen recycling macht ein Reset der Rohstoffe. --- src/gmtool.c | 29 +++++++++++++----- src/kernel/region.c | 73 ++++++++++++++++++++++++--------------------- src/kernel/region.h | 1 + 3 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/gmtool.c b/src/gmtool.c index e13701f6f..ce4c0129e 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -531,17 +531,32 @@ static void statusline(WINDOW * win, const char *str) } static void reset_region(region *r) { + unit **up = &r->units; + bool players = false; + set_chaoscount(r, 0); r->flags = 0; a_removeall(&r->attribs, NULL); - while (r->units) { - remove_unit(&r->units, r->units); + while (*up) { + unit *u = *up; + if (is_monsters(u->faction)) { + remove_unit(up, u); + } + else { + players = true; + up = &u->next; + } } - while (r->ships) { - remove_ship(&r->ships, r->ships); - } - while (r->buildings) { - remove_building(&r->buildings, r->buildings); + if (!players) { + while (r->ships) { + remove_ship(&r->ships, r->ships); + } + while (r->buildings) { + remove_building(&r->buildings, r->buildings); + } + if (r->land) { + init_region(r); + } } } diff --git a/src/kernel/region.c b/src/kernel/region.c index 68b47d7a2..7cb52c201 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -1048,6 +1048,43 @@ int fix_demand(region * rd) { return -1; } +void init_region(region *r) +{ + static int changed; + static const terrain_type *t_plain; + const terrain_type * terrain = r->terrain; + int horses = 0, trees = 0; + if (terrain_changed(&changed)) { + t_plain = get_terrain(terrainnames[T_PLAIN]); + } + if (terrain->size>0) { + horses = rng_int() % (terrain->size / 50); + trees = terrain->size * (30 + rng_int() % 40) / 1000; + } + if (t_plain && terrain == t_plain) { + rsethorses(r, horses); + if (chance(0.4)) { + rsettrees(r, 2, trees); + } + } + else if (trees>0 && chance(0.2)) { + rsettrees(r, 2, trees); + } + else { + rsettrees(r, 2, 0); + } + rsettrees(r, 1, rtrees(r, 2) / 4); + rsettrees(r, 0, rtrees(r, 2) / 8); + + if (!fval(r, RF_CHAOTIC)) { + int peasants; + peasants = (region_maxworkers(r) * (20 + dice(6, 10))) / 100; + rsetpeasants(r, MAX(100, peasants)); + rsetmoney(r, rpeasants(r) * ((wage(r, NULL, NULL, + INT_MAX) + 1) + rng_int() % 5)); + } +} + void terraform_region(region * r, const terrain_type * terrain) { /* Resourcen, die nicht mehr vorkommen können, löschen */ @@ -1195,40 +1232,8 @@ void terraform_region(region * r, const terrain_type * terrain) else freset(r, RF_MALLORN); } - } - - if (oldterrain == NULL || terrain->size != oldterrain->size) { - static int changed; - static const terrain_type *t_plain; - int horses = 0, trees = 0; - if (terrain_changed(&changed)) { - t_plain = get_terrain(terrainnames[T_PLAIN]); - } - if (terrain->size>0) { - horses = rng_int() % (terrain->size / 50); - trees = terrain->size * (30 + rng_int() % 40) / 1000; - } - if (t_plain && terrain == t_plain) { - rsethorses(r, horses); - if (chance(0.4)) { - rsettrees(r, 2, trees); - } - } - else if (trees>0 && chance(0.2)) { - rsettrees(r, 2, trees); - } - else { - rsettrees(r, 2, 0); - } - rsettrees(r, 1, rtrees(r, 2) / 4); - rsettrees(r, 0, rtrees(r, 2) / 8); - - if (!fval(r, RF_CHAOTIC)) { - int peasants; - peasants = (region_maxworkers(r) * (20 + dice(6, 10))) / 100; - rsetpeasants(r, MAX(100, peasants)); - rsetmoney(r, rpeasants(r) * ((wage(r, NULL, NULL, - INT_MAX) + 1) + rng_int() % 5)); + if (oldterrain == NULL || terrain->size != oldterrain->size) { + init_region(r); } } } diff --git a/src/kernel/region.h b/src/kernel/region.h index 9543658d9..bf932e9c3 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -228,6 +228,7 @@ extern "C" { struct region *new_region(int x, int y, struct plane *pl, int uid); void remove_region(region ** rlist, region * r); void terraform_region(struct region *r, const struct terrain_type *terrain); + void init_region(struct region *r); bool pnormalize(int *x, int *y, const struct plane *pl); extern const int delta_x[MAXDIRECTIONS]; From fc80e4b83eb4015de12546240667836ac4f7fc43 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 17 Jul 2018 20:53:34 +0200 Subject: [PATCH 03/17] =?UTF-8?q?BUG=202462:=20Leuchtturm=20meldet=20keine?= =?UTF-8?q?=20Landregionen,=20besch=C3=BCtzt=20Schiffe=20erst=20ab=20Gr?= =?UTF-8?q?=C3=B6=C3=9Fe=2010.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/tests/report.lua | 6 +-- src/kernel/build.c | 4 +- src/kernel/building.c | 12 +++-- src/lighthouse.c | 114 ++++++++++++++++++--------------------- src/lighthouse.h | 5 +- src/lighthouse.test.c | 43 +++++++++++++-- src/move.c | 4 +- src/reports.c | 19 ++++--- src/reports.test.c | 4 +- 9 files changed, 125 insertions(+), 86 deletions(-) diff --git a/scripts/tests/report.lua b/scripts/tests/report.lua index 12d1538c3..b65bcc279 100644 --- a/scripts/tests/report.lua +++ b/scripts/tests/report.lua @@ -93,11 +93,11 @@ end function test_lighthouse() eressea.free_game() local r = region.create(0, 0, "mountain") - local f = faction.create("human", "noreply@eressea.de", "de") + local f = faction.create("human", "human@example.com") region.create(1, 0, "mountain") region.create(2, 0, "ocean") region.create(0, 1, "firewall") - region.create(3, 0, "mountain") + region.create(3, 0, "ocean") region.create(4, 0, "plain") local u = unit.create(f, r, 1) local b = building.create(r, "lighthouse") @@ -110,7 +110,7 @@ function test_lighthouse() init_reports() write_report(f) - assert_true(find_in_report(f, " %(1,0%) %(vom Turm erblickt%)")) + assert_false(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%)")) diff --git a/src/kernel/build.c b/src/kernel/build.c index 310e4bd43..11324f752 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -895,7 +895,9 @@ build_building(unit * u, const building_type * btype, int id, int want, order * } fset(b, BLD_EXPANDED); - update_lighthouse(b); + if (is_lighthouse(btype)) { + update_lighthouse(b); + } return built; } diff --git a/src/kernel/building.c b/src/kernel/building.c index f3f01905f..75cad30f7 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -377,7 +377,9 @@ building *new_building(const struct building_type * btype, region * r, bptr = &(*bptr)->next; *bptr = b; - update_lighthouse(b); + if (is_lighthouse(b->type)) { + update_lighthouse(b); + } bname = LOC(lang, btype->_name); if (!bname) { bname = LOC(lang, parameters[P_GEBAEUDE]); @@ -399,6 +401,7 @@ static building *deleted_buildings; void remove_building(building ** blist, building * b) { unit *u; + region *r = b->region; static const struct building_type *bt_caravan, *bt_dam, *bt_tunnel; static int btypes; @@ -410,18 +413,19 @@ void remove_building(building ** blist, building * b) bt_tunnel = bt_find("tunnel"); } handle_event(b->attribs, "destroy", b); - for (u = b->region->units; u; u = u->next) { + for (u = r->units; u; u = u->next) { if (u->building == b) leave(u, true); } + if (is_lighthouse(b->type)) { + remove_lighthouse(b); + } b->size = 0; - update_lighthouse(b); bunhash(b); /* Falls Karawanserei, Damm oder Tunnel einst�rzen, wird die schon * gebaute Strasse zur Haelfte vernichtet */ if (b->type == bt_caravan || b->type == bt_dam || b->type == bt_tunnel) { - region *r = b->region; int d; for (d = 0; d != MAXDIRECTIONS; ++d) { direction_t dir = (direction_t)d; diff --git a/src/lighthouse.c b/src/lighthouse.c index fbf950fb1..2ff1c6191 100644 --- a/src/lighthouse.c +++ b/src/lighthouse.c @@ -19,6 +19,11 @@ attrib_type at_lighthouse = { /* Rest ist NULL; tempor�res, nicht alterndes Attribut */ }; +bool is_lighthouse(const building_type *btype) +{ + return is_building_type(btype, "lighthouse"); +} + /* update_lighthouse: call this function whenever the size of a lighthouse changes * it adds temporary markers to the surrounding regions. * The existence of markers says nothing about the quality of the observer in @@ -26,46 +31,57 @@ attrib_type at_lighthouse = { */ void update_lighthouse(building * lh) { - if (is_building_type(lh->type, "lighthouse")) { - region *r = lh->region; + region *r = lh->region; + assert(is_lighthouse(lh->type)); - r->flags |= RF_LIGHTHOUSE; - if (lh->size > 0) { - int d = (int)log10(lh->size) + 1; - int x; - for (x = -d; x <= d; ++x) { - int y; - for (y = -d; y <= d; ++y) { - attrib *a; - region *r2; - int px = r->x + x, py = r->y + y; + r->flags |= RF_LIGHTHOUSE; + if (lh->size >= 10) { + int d = lighthouse_range(lh, NULL, NULL); + int x; + for (x = -d; x <= d; ++x) { + int y; + for (y = -d; y <= d; ++y) { + attrib *a; + region *r2; + int px = r->x + x, py = r->y + y; - pnormalize(&px, &py, rplane(r)); - r2 = findregion(px, py); - if (!r2 || !fval(r2->terrain, SEA_REGION)) - continue; - if (distance(r, r2) > d) - continue; - a = a_find(r2->attribs, &at_lighthouse); - while (a && a->type == &at_lighthouse) { - building *b = (building *)a->data.v; - if (b == lh) - break; - a = a->next; - } - if (!a) { - a = a_add(&r2->attribs, a_new(&at_lighthouse)); - a->data.v = (void *)lh; - } + pnormalize(&px, &py, rplane(r)); + r2 = findregion(px, py); + if (!r2 || !fval(r2->terrain, SEA_REGION)) + continue; + if (distance(r, r2) > d) + continue; + a = a_find(r2->attribs, &at_lighthouse); + while (a && a->type == &at_lighthouse) { + building *b = (building *)a->data.v; + if (b == lh) + break; + a = a->next; + } + if (!a) { + a = a_add(&r2->attribs, a_new(&at_lighthouse)); + a->data.v = (void *)lh; } } } } } +void remove_lighthouse(const building *lh) { + building *b; + region * r = lh->region; + + r->flags &= ~RF_LIGHTHOUSE; + for (b = r->buildings; b; b = b->next) { + if (b != lh && is_lighthouse(b->type)) { + update_lighthouse(b); + } + } +} + int lighthouse_range(const building * b, const faction * f, const unit *u) { - if (fval(b, BLD_MAINTAINED) && b->size >= 10) { + if (b->size >= 10 && (b->flags & BLD_MAINTAINED)) { int maxd = (int)log10(b->size) + 1; if (u && skill_enabled(SK_PERCEPTION)) { @@ -80,11 +96,11 @@ int lighthouse_range(const building * b, const faction * f, const unit *u) return 0; } -bool check_leuchtturm(region * r, faction * f) +bool lighthouse_guarded(const region * r) { attrib *a; - if (!fval(r->terrain, SEA_REGION)) { + if (!r->attribs || !(r->terrain->flags & SEA_REGION)) { return false; } for (a = a_find(r->attribs, &at_lighthouse); a && a->type == &at_lighthouse; @@ -92,37 +108,11 @@ bool check_leuchtturm(region * r, faction * f) building *b = (building *)a->data.v; assert(is_building_type(b->type, "lighthouse")); - if (fval(b, BLD_MAINTAINED) && b->size >= 10) { + if ((b->flags & BLD_MAINTAINED) && b->size >= 10) { int maxd = (int)log10(b->size) + 1; - - if (skill_enabled(SK_PERCEPTION) && f) { - region *r2 = b->region; - unit *u; - int c = 0; - int d = 0; - - for (u = r2->units; u; u = u->next) { - if (u->building == b) { - c += u->number; - if (c > buildingcapacity(b)) - break; - if (u->faction == f) { - if (!d) - d = distance(r, r2); - if (maxd < d) - break; - if (effskill(u, SK_PERCEPTION, 0) >= d * 3) - return true; - } - } - else if (c) - break; /* first unit that's no longer in the house ends the search */ - } - } - else { - /* E3A rule: no perception req'd */ - return true; - } + int d = distance(r, b->region); + assert(maxd >= d); + return true; } } diff --git a/src/lighthouse.h b/src/lighthouse.h index 2eacfb7d8..cd5a02d04 100644 --- a/src/lighthouse.h +++ b/src/lighthouse.h @@ -29,13 +29,16 @@ extern "C" { struct faction; struct region; struct building; + struct building_type; struct unit; struct attrib; extern struct attrib_type at_lighthouse; /* leuchtturm */ - bool check_leuchtturm(struct region *r, struct faction *f); + bool is_lighthouse(const struct building_type *btype); + bool lighthouse_guarded(const struct region *r); void update_lighthouse(struct building *b); + void remove_lighthouse(const struct building *lh); int lighthouse_range(const struct building *b, const struct faction *f, const struct unit *u); diff --git a/src/lighthouse.test.c b/src/lighthouse.test.c index e0c57ec1a..bcc7c0ab7 100644 --- a/src/lighthouse.test.c +++ b/src/lighthouse.test.c @@ -36,6 +36,7 @@ static void test_lighthouse_range(CuTest * tc) set_level(u1, SK_PERCEPTION, 3); set_level(u2, SK_PERCEPTION, 3); CuAssertIntEquals(tc, 0, lighthouse_range(b, NULL, NULL)); + b->flags |= BLD_MAINTAINED; CuAssertIntEquals(tc, 1, lighthouse_range(b, u1->faction, u1)); set_level(u1, SK_PERCEPTION, 6); @@ -54,7 +55,7 @@ static void test_lighthouse_range(CuTest * tc) static void test_lighthouse_update(CuTest * tc) { - region *r1, *r2, *r3; + region *r1, *r2, *r3, *r4; building *b; const struct terrain_type *t_ocean, *t_plain; @@ -64,20 +65,23 @@ static void test_lighthouse_update(CuTest * tc) r1 = test_create_region(0, 0, t_plain); r2 = test_create_region(1, 0, t_ocean); r3 = test_create_region(2, 0, t_ocean); + r4 = test_create_region(0, 1, t_plain); b = test_create_building(r1, test_create_buildingtype("lighthouse")); + b->flags |= BLD_MAINTAINED; CuAssertIntEquals(tc, RF_LIGHTHOUSE, r1->flags&RF_LIGHTHOUSE); CuAssertPtrEquals(tc, NULL, r1->attribs); CuAssertPtrEquals(tc, NULL, r2->attribs); CuAssertPtrEquals(tc, NULL, r3->attribs); + CuAssertPtrEquals(tc, NULL, r4->attribs); r1->flags = 0; - b->size = 1; + b->size = 9; /* minimum size for any effect is 10 */ update_lighthouse(b); CuAssertIntEquals(tc, RF_LIGHTHOUSE, r1->flags&RF_LIGHTHOUSE); - CuAssertPtrNotNull(tc, r2->attribs); - CuAssertPtrEquals(tc, (void *)&at_lighthouse, (void *)r2->attribs->type); CuAssertPtrEquals(tc, NULL, r1->attribs); + CuAssertPtrEquals(tc, NULL, r2->attribs); CuAssertPtrEquals(tc, NULL, r3->attribs); + CuAssertPtrEquals(tc, NULL, r4->attribs); a_removeall(&r2->attribs, NULL); r1->flags = 0; @@ -88,6 +92,36 @@ static void test_lighthouse_update(CuTest * tc) CuAssertPtrEquals(tc, (void *)&at_lighthouse, (void *)r2->attribs->type); CuAssertPtrNotNull(tc, r3->attribs); CuAssertPtrEquals(tc, (void *)&at_lighthouse, (void *)r3->attribs->type); + CuAssertPtrEquals(tc, NULL, r4->attribs); + test_teardown(); +} + +static void test_lighthouse_guard(CuTest * tc) { + region *r1, *r2, *r3, *r4; + building *b; + const struct terrain_type *t_ocean, *t_plain; + + test_setup(); + t_ocean = test_create_terrain("ocean", SEA_REGION); + t_plain = test_create_terrain("plain", LAND_REGION); + r1 = test_create_region(0, 0, t_plain); + r2 = test_create_region(1, 0, t_ocean); + r3 = test_create_region(2, 0, t_ocean); + r4 = test_create_region(0, 1, t_plain); + b = test_create_building(r1, test_create_buildingtype("lighthouse")); + b->flags |= BLD_MAINTAINED; + b->size = 10; + CuAssertIntEquals(tc, 2, lighthouse_range(b, NULL, NULL)); + update_lighthouse(b); + CuAssertIntEquals(tc, RF_LIGHTHOUSE, r1->flags&RF_LIGHTHOUSE); + CuAssertPtrEquals(tc, NULL, r1->attribs); + CuAssertPtrEquals(tc, (void *)&at_lighthouse, (void *)r2->attribs->type); + CuAssertPtrEquals(tc, (void *)&at_lighthouse, (void *)r3->attribs->type); + CuAssertPtrEquals(tc, NULL, r4->attribs); + CuAssertIntEquals(tc, false, lighthouse_guarded(r1)); + CuAssertIntEquals(tc, true, lighthouse_guarded(r2)); + CuAssertIntEquals(tc, true, lighthouse_guarded(r3)); + CuAssertIntEquals(tc, false, lighthouse_guarded(r4)); test_teardown(); } @@ -96,5 +130,6 @@ CuSuite *get_lighthouse_suite(void) CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_lighthouse_range); SUITE_ADD_TEST(suite, test_lighthouse_update); + SUITE_ADD_TEST(suite, test_lighthouse_guard); return suite; } diff --git a/src/move.c b/src/move.c index 990d6fc14..205b52416 100644 --- a/src/move.c +++ b/src/move.c @@ -1779,7 +1779,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting) /* storms should be the first thing we do. */ stormchance = stormyness / shipspeed(sh, u); - if (check_leuchtturm(next_point, NULL)) { + if (lighthouse_guarded(next_point)) { if (lighthouse_div > 0) { stormchance /= lighthouse_div; } @@ -1867,7 +1867,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting) if (reason == SA_NO_INSECT) { ADDMSG(&f->msgs, msg_message("detectforbidden", "unit region", u, sh->region)); } - else if (check_leuchtturm(current_point, NULL)) { + else if (lighthouse_guarded(current_point)) { ADDMSG(&f->msgs, msg_message("sailnolandingstorm", "ship region", sh, next_point)); } else { diff --git a/src/reports.c b/src/reports.c index 5355a1db9..5d22636e8 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1353,6 +1353,13 @@ static void add_seen_nb(faction *f, region *r, seen_mode mode) { update_interval(f, last); } +static void add_seen_lighthouse(region *r, faction *f) +{ + if (r->terrain->flags & SEA_REGION) { + add_seen_nb(f, r, seen_lighthouse); + } +} + /** mark all regions seen by the lighthouse. */ static void prepare_lighthouse_ql(faction *f, selist *rlist) { @@ -1361,9 +1368,7 @@ static void prepare_lighthouse_ql(faction *f, selist *rlist) { for (ql = rlist, qi = 0; ql; selist_advance(&ql, &qi, 1)) { region *rl = (region *)selist_get(ql, qi); - if (!fval(rl->terrain, FORBIDDEN_REGION)) { - add_seen_nb(f, rl, seen_lighthouse); - } + add_seen_lighthouse(rl, f); } } @@ -1382,9 +1387,7 @@ static void prepare_lighthouse(faction *f, region *r, int range) assert(n > 0 && n <= 64); for (i = 0; i != n; ++i) { region *rl = result[i]; - if (!fval(rl->terrain, FORBIDDEN_REGION)) { - add_seen_nb(f, rl, seen_lighthouse); - } + add_seen_lighthouse(rl, f); } } } @@ -1592,7 +1595,7 @@ void prepare_report(report_context *ctx, faction *f) if (rule_region_owners && f == region_get_owner(r)) { for (b = rbuildings(r); b; b = b->next) { if (b && b->type == bt_lighthouse) { - /* region owners get maximm range */ + /* region owners get maximum range */ int lhr = lighthouse_range(b, NULL, NULL); if (lhr > range) range = lhr; } @@ -1630,7 +1633,7 @@ void prepare_report(report_context *ctx, faction *f) /* unit is one of ours, and inside the current lighthouse */ if (br == 0) { /* lazy-calculate the range */ - br = lighthouse_range(u->building, f, u); + br = lighthouse_range(b, f, u); } if (br > range) { range = br; diff --git a/src/reports.test.c b/src/reports.test.c index 2b22782ae..6d7a7961f 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -530,7 +530,7 @@ void test_prepare_lighthouse_capacity(CuTest *tc) { static void test_prepare_lighthouse(CuTest *tc) { report_context ctx; faction *f; - region *r1, *r2, *r3; + region *r1, *r2, *r3, *r4; unit *u; building *b; building_type *btype; @@ -543,6 +543,7 @@ static void test_prepare_lighthouse(CuTest *tc) { r1 = test_create_region(0, 0, t_plain); r2 = test_create_region(1, 0, t_ocean); r3 = test_create_region(2, 0, t_ocean); + r4 = test_create_region(0, 1, t_plain); btype = test_create_buildingtype("lighthouse"); b = test_create_building(r1, btype); b->flags |= BLD_MAINTAINED; @@ -557,6 +558,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); finish_reports(&ctx); test_teardown(); } From 7b7d3cb7597440d19722c56ac631e7392a414f26 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 17 Jul 2018 21:34:22 +0200 Subject: [PATCH 04/17] test: lighhouse size reduction reduces effectiveness --- src/lighthouse.c | 8 ++++---- src/lighthouse.test.c | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lighthouse.c b/src/lighthouse.c index 2ff1c6191..ff1cc5b84 100644 --- a/src/lighthouse.c +++ b/src/lighthouse.c @@ -25,10 +25,10 @@ bool is_lighthouse(const building_type *btype) } /* update_lighthouse: call this function whenever the size of a lighthouse changes -* it adds temporary markers to the surrounding regions. -* The existence of markers says nothing about the quality of the observer in -* the lighthouse, for this may change more frequently. -*/ + * it adds temporary markers to the surrounding regions. + * The existence of markers says nothing about the quality of the observer in + * the lighthouse, since this may change more frequently. + */ void update_lighthouse(building * lh) { region *r = lh->region; diff --git a/src/lighthouse.test.c b/src/lighthouse.test.c index bcc7c0ab7..f85b5ce99 100644 --- a/src/lighthouse.test.c +++ b/src/lighthouse.test.c @@ -122,6 +122,9 @@ static void test_lighthouse_guard(CuTest * tc) { CuAssertIntEquals(tc, true, lighthouse_guarded(r2)); CuAssertIntEquals(tc, true, lighthouse_guarded(r3)); CuAssertIntEquals(tc, false, lighthouse_guarded(r4)); + b->size = 1; /* size can go down in destroy_cmd */ + CuAssertIntEquals(tc, false, lighthouse_guarded(r2)); + CuAssertIntEquals(tc, false, lighthouse_guarded(r3)); test_teardown(); } From 228216091619a9837fe3a0e6b25291a60419ca71 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 18 Jul 2018 20:49:17 +0200 Subject: [PATCH 05/17] separate lighthouse_view_distance from lighthouse_range. --- src/lighthouse.c | 18 ++++++++++++------ src/lighthouse.h | 4 ++-- src/lighthouse.test.c | 31 +++++++++++++++++-------------- src/reports.c | 12 ++++++------ src/reports.test.c | 4 ++-- 5 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/lighthouse.c b/src/lighthouse.c index ff1cc5b84..4ef830cfc 100644 --- a/src/lighthouse.c +++ b/src/lighthouse.c @@ -36,7 +36,7 @@ void update_lighthouse(building * lh) r->flags |= RF_LIGHTHOUSE; if (lh->size >= 10) { - int d = lighthouse_range(lh, NULL, NULL); + int d = lighthouse_range(lh); int x; for (x = -d; x <= d; ++x) { int y; @@ -79,18 +79,24 @@ void remove_lighthouse(const building *lh) { } } -int lighthouse_range(const building * b, const faction * f, const unit *u) +int lighthouse_range(const building * b) { if (b->size >= 10 && (b->flags & BLD_MAINTAINED)) { - int maxd = (int)log10(b->size) + 1; + return (int)log10(b->size) + 1; + } + return 0; +} - if (u && skill_enabled(SK_PERCEPTION)) { +int lighthouse_view_distance(const building * b, const unit *u) +{ + if (b->size >= 10 && (b->flags & BLD_MAINTAINED)) { + int maxd = lighthouse_range(b); + + if (maxd > 0 && u && skill_enabled(SK_PERCEPTION)) { int sk = effskill(u, SK_PERCEPTION, 0) / 3; assert(u->building == b); - assert(u->faction == f); if (maxd > sk) maxd = sk; } - /* E3A rule: no perception req'd */ return maxd; } return 0; diff --git a/src/lighthouse.h b/src/lighthouse.h index cd5a02d04..cd0e055fd 100644 --- a/src/lighthouse.h +++ b/src/lighthouse.h @@ -39,8 +39,8 @@ extern "C" { bool lighthouse_guarded(const struct region *r); void update_lighthouse(struct building *b); void remove_lighthouse(const struct building *lh); - int lighthouse_range(const struct building *b, const struct faction *f, - const struct unit *u); + int lighthouse_range(const struct building *b); + int lighthouse_view_distance(const struct building *b, const struct unit *u); #ifdef __cplusplus diff --git a/src/lighthouse.test.c b/src/lighthouse.test.c index f85b5ce99..d9accd49e 100644 --- a/src/lighthouse.test.c +++ b/src/lighthouse.test.c @@ -26,30 +26,33 @@ static void test_lighthouse_range(CuTest * tc) u1 = test_create_unit(test_create_faction(NULL), r); u2 = test_create_unit(test_create_faction(NULL), r); b = test_create_building(r, test_create_buildingtype("lighthouse")); - CuAssertIntEquals(tc, 0, lighthouse_range(b, NULL, NULL)); - CuAssertIntEquals(tc, 0, lighthouse_range(b, u1->faction, NULL)); + CuAssertIntEquals(tc, 0, lighthouse_range(b)); + b->size = 9; + CuAssertIntEquals(tc, 0, lighthouse_range(b)); b->size = 10; - CuAssertIntEquals(tc, 0, lighthouse_range(b, NULL, NULL)); + CuAssertIntEquals(tc, 0, lighthouse_range(b)); + b->flags |= BLD_MAINTAINED; + CuAssertIntEquals(tc, 2, lighthouse_range(b)); u1->building = b; u2->building = b; u1->number = 10; set_level(u1, SK_PERCEPTION, 3); set_level(u2, SK_PERCEPTION, 3); - CuAssertIntEquals(tc, 0, lighthouse_range(b, NULL, NULL)); - b->flags |= BLD_MAINTAINED; - CuAssertIntEquals(tc, 1, lighthouse_range(b, u1->faction, u1)); + CuAssertIntEquals(tc, 1, lighthouse_view_distance(b, u1)); set_level(u1, SK_PERCEPTION, 6); - CuAssertIntEquals(tc, 2, lighthouse_range(b, u1->faction, u1)); - /* lighthouse_range does not check inside_building */ - CuAssertIntEquals(tc, 1, lighthouse_range(b, u2->faction, u2)); + CuAssertIntEquals(tc, 1, lighthouse_view_distance(b, u2)); + CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, u1)); b->size = 100; update_lighthouse(b); - CuAssertIntEquals(tc, 3, lighthouse_range(b, NULL, NULL)); - CuAssertIntEquals(tc, 2, lighthouse_range(b, u1->faction, u1)); + CuAssertIntEquals(tc, 3, lighthouse_range(b)); + CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, u1)); set_level(u1, SK_PERCEPTION, 9); - CuAssertIntEquals(tc, 3, lighthouse_range(b, u1->faction, u1)); - CuAssertIntEquals(tc, 1, lighthouse_range(b, u2->faction, u2)); + CuAssertIntEquals(tc, 3, lighthouse_view_distance(b, u1)); + CuAssertIntEquals(tc, 1, lighthouse_view_distance(b, u2)); + b->size = 99; + CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, u1)); + test_teardown(); } @@ -111,7 +114,7 @@ static void test_lighthouse_guard(CuTest * tc) { b = test_create_building(r1, test_create_buildingtype("lighthouse")); b->flags |= BLD_MAINTAINED; b->size = 10; - CuAssertIntEquals(tc, 2, lighthouse_range(b, NULL, NULL)); + CuAssertIntEquals(tc, 2, lighthouse_range(b)); update_lighthouse(b); CuAssertIntEquals(tc, RF_LIGHTHOUSE, r1->flags&RF_LIGHTHOUSE); CuAssertPtrEquals(tc, NULL, r1->attribs); diff --git a/src/reports.c b/src/reports.c index 5d22636e8..711d09874 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1596,7 +1596,7 @@ void prepare_report(report_context *ctx, faction *f) for (b = rbuildings(r); b; b = b->next) { if (b && b->type == bt_lighthouse) { /* region owners get maximum range */ - int lhr = lighthouse_range(b, NULL, NULL); + int lhr = lighthouse_view_distance(b, NULL); if (lhr > range) range = lhr; } } @@ -1613,7 +1613,7 @@ void prepare_report(report_context *ctx, faction *f) */ if (!fval(r, RF_LIGHTHOUSE)) { /* it's enough to add the region once, and if there are - * no lighthouses, there is no need to look at more units */ + * no lighthouses here, there is no need to look at more units */ break; } } @@ -1633,10 +1633,10 @@ void prepare_report(report_context *ctx, faction *f) /* unit is one of ours, and inside the current lighthouse */ if (br == 0) { /* lazy-calculate the range */ - br = lighthouse_range(b, f, u); - } - if (br > range) { - range = br; + br = lighthouse_view_distance(b, u); + if (br > range) { + range = br; + } } } } diff --git a/src/reports.test.c b/src/reports.test.c index 6d7a7961f..5a6e1fd9e 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -495,7 +495,7 @@ void test_prepare_lighthouse_capacity(CuTest *tc) { u1->number = 4; u1->building = b; set_level(u1, SK_PERCEPTION, 3); - CuAssertIntEquals(tc, 1, lighthouse_range(b, u1->faction, u1)); + CuAssertIntEquals(tc, 1, lighthouse_view_distance(b, u1)); CuAssertPtrEquals(tc, b, inside_building(u1)); u2 = test_create_unit(f, r1); u2->building = b; @@ -597,7 +597,7 @@ static void test_prepare_lighthouse_owners(CuTest *tc) u = test_create_unit(test_create_faction(NULL), r1); u->building = b; region_set_owner(b->region, f, 0); - CuAssertIntEquals(tc, 2, lighthouse_range(b, NULL, NULL)); + CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, NULL)); prepare_report(&ctx, f); CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, NULL, ctx.last); From e62b5c580dd283f2533f9049b316c2ee59a9e934 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 19 Jul 2018 04:57:33 +0200 Subject: [PATCH 06/17] update tests to reflect new lighthouse rules --- tests/run-turn.sh | 10 +++++----- tests/write-reports.sh | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/run-turn.sh b/tests/run-turn.sh index ad2e0e6b8..470cb6e2b 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' 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 ';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 '"neighbour";visibility' 11 assert_grep_count reports/185-6rLo.cr '^EINHEIT' 2 assert_grep_count reports/185-6rLo.cr '^REGION' 13 diff --git a/tests/write-reports.sh b/tests/write-reports.sh index 5621e84a9..c3d1066e3 100755 --- a/tests/write-reports.sh +++ b/tests/write-reports.sh @@ -19,7 +19,7 @@ done #set -e cd $ROOT/tests setup -#cleanup +cleanup VALGRIND=`which valgrind` TESTS=../Debug/eressea/test_eressea SERVER=../Debug/eressea/eressea From cd6154cae64acd5eaf996d653798daa413e7a915 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 22 Jul 2018 10:55:09 +0200 Subject: [PATCH 07/17] fix the lighthouse crash in preview. --- scripts/eressea/xmasitems.lua | 2 -- src/kernel/save.c | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/eressea/xmasitems.lua b/scripts/eressea/xmasitems.lua index 9e22dea52..a0f2e48f8 100644 --- a/scripts/eressea/xmasitems.lua +++ b/scripts/eressea/xmasitems.lua @@ -99,8 +99,6 @@ function self.update() r:set_resource("tree", trees * 1.1) msg:send_region(r) end - if clear then - end end end else diff --git a/src/kernel/save.c b/src/kernel/save.c index b43d9bd5d..b51e82734 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1493,7 +1493,9 @@ int read_game(gamedata *data) if (r->flags & RF_LIGHTHOUSE) { building *b; for (b = r->buildings; b; b = b->next) { - update_lighthouse(b); + if (is_lighthouse(b->type)) { + update_lighthouse(b); + } } } } From 5309c84224f892728d7af645a040cb53c9664d8d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 25 Jul 2018 19:42:48 +0200 Subject: [PATCH 08/17] BUG 2465 Kein Item-Teleport bei Lied der Verfuehrung. --- res/translations/messages.de.po | 2 +- src/spells.c | 40 +++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/res/translations/messages.de.po b/res/translations/messages.de.po index 3413ffc2c..b87fe241a 100644 --- a/res/translations/messages.de.po +++ b/res/translations/messages.de.po @@ -2121,7 +2121,7 @@ msgid "missing_components" msgstr "\"$unit($unit) hat nicht genügend Komponenten um $spell($spell) auf Stufe $int($level) zu zaubern.\"" msgid "seduce_effect_1" -msgstr "\"$unit($unit) verfiel dem Glücksspiel und hat fast sein ganzes Hab und gut verspielt.\"" +msgstr "\"$unit($unit) verfiel dem Glücksspiel und hat fast sein ganzes Hab und Gut verspielt.\"" msgid "xmastree_effect" msgstr "\"In der Region erstrahlen des Nachts bunte Lichter, Gloeckchen klingeln und frohes Kindergelaechter klingt durch den Wald.\"" diff --git a/src/spells.c b/src/spells.c index 4e98b1a2a..8caf29039 100644 --- a/src/spells.c +++ b/src/spells.c @@ -4072,7 +4072,7 @@ static int sp_pump(castorder * co) * Betoert eine Einheit, so das sie ihm den groe�ten Teil ihres Bargelds * und 50% ihres Besitzes schenkt. Sie behaelt jedoch immer soviel, wie * sie zum ueberleben braucht. Wirkt gegen Magieresistenz. - * MIN(Stufe*1000$, u->money - maintenace) + * MIN(Stufe*1000$, u->money - maintenance) * Von jedem Item wird 50% abgerundet ermittelt und uebergeben. Dazu * kommt Itemzahl%2 mit 50% chance * @@ -4083,15 +4083,16 @@ static int sp_seduce(castorder * co) { const resource_type *rsilver = get_resourcetype(R_SILVER); unit *target; - item **itmp, *items = 0; - unit *mage = co->magician.u; + item **itmp, *items = NULL; + unit *u, *mage = co->magician.u; spellparameter *pa = co->par; int cast_level = co->level; double force = co->force; /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) + if (pa->param[0]->flag == TARGET_NOTFOUND) { return 0; + } target = pa->param[0]->data.u; /* Zieleinheit */ @@ -4101,6 +4102,15 @@ static int sp_seduce(castorder * co) return 0; } + u = mage; + if (mage->region != target->region) { + for (u = target->region->units; u; u = u->next) { + if (u->faction == mage->faction) { + break; + } + } + } + /* Erfolgsmeldung */ itmp = &target->items; @@ -4113,28 +4123,30 @@ static int sp_seduce(castorder * co) if (loot < 0) loot = 0; } else { - loot = itm->number / 2; - if (itm->number % 2) { - loot += rng_int() % 2; - } + loot = (itm->number + 1) / 2; if (loot > 0) { int floot = (int)(5 * force); if (loot > floot) loot = floot; } } if (loot > 0) { - i_change(&mage->items, itm->type, loot); - i_change(&items, itm->type, loot); + if (u) { + i_change(&u->items, itm->type, loot); + i_change(&items, itm->type, loot); + } i_change(itmp, itm->type, -loot); } - if (*itmp == itm) + if (*itmp == itm) { itmp = &itm->next; + } } if (items) { - ADDMSG(&mage->faction->msgs, msg_message("seduce_effect_0", "mage unit items", - mage, target, items)); - i_freeall(&items); + if (u) { + ADDMSG(&mage->faction->msgs, msg_message("seduce_effect_0", "mage unit items", + u, target, items)); + i_freeall(&items); + } ADDMSG(&target->faction->msgs, msg_message("seduce_effect_1", "unit", target)); } From 7eb951544a1d0b9c1fbdb66cd1eccf259f0fc1ed Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 30 Jul 2018 22:19:40 +0200 Subject: [PATCH 09/17] equip_newunits got called twice. --- scripts/eressea/equipment.lua | 1 - scripts/tests/config.lua | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/scripts/eressea/equipment.lua b/scripts/eressea/equipment.lua index 8852dfb27..c7bfe7dad 100644 --- a/scripts/eressea/equipment.lua +++ b/scripts/eressea/equipment.lua @@ -2,7 +2,6 @@ local self = {} local function equip_first(u) - equip_newunits(u) name = 'seed_' .. u.race equip_unit(u, name, 255) end diff --git a/scripts/tests/config.lua b/scripts/tests/config.lua index 316a8ccca..733a8ee07 100644 --- a/scripts/tests/config.lua +++ b/scripts/tests/config.lua @@ -30,6 +30,26 @@ function test_first_troll() assert_equal(2, u:eff_skill('perception')) end +function test_first_human() + local f = faction.create('human') + local r = region.create(0, 0, "plain") + local u = unit.create(f, r, 1) + u:equip('first_unit') + assert_not_nil(u.building) + assert_equal('castle', u.building.type) + assert_equal(10, u.building.size) +end + +function test_first_aquarian() + local f = faction.create('aquarian') + local r = region.create(0, 0, "plain") + local u = unit.create(f, r, 1) + u:equip('first_unit') + assert_not_nil(u.ship) + assert_equal('boat', u.ship.type) + assert_equal(1, u:get_skill('sailing')) +end + function test_seed_unit() local r = region.create(0, 0, "plain") local f = faction.create('human') @@ -53,3 +73,4 @@ function test_seed_elf() assert_equal('castle', u.building.type) assert_equal(10, u.building.size) end + From e9bded4a87a0b83ea5e4d2ba284470e55ea7fee0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 31 Jul 2018 10:12:54 +0200 Subject: [PATCH 10/17] BUG 2469 wrong default quantity for construction reqs --- src/creport.c | 1 + src/economy.c | 1 - src/exparse.c | 1 + src/report.c | 1 + 4 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/creport.c b/src/creport.c index eeaa563bb..91d56ca3b 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1529,6 +1529,7 @@ static void report_itemtype(FILE *F, faction *f, const item_type *itype) { fprintf(F, "\"%s\"\n", translate(ch, LOC(f->locale, ch))); m++; } + assert(!m->rtype); } } diff --git a/src/economy.c b/src/economy.c index 5fbb0111c..3bb7b1066 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1252,7 +1252,6 @@ static void create_potion(unit * u, const item_type * itype, int want) /* something missing from the list of materials */ ADDMSG(&u->faction->msgs, msg_materials_required(u, u->thisorder, itype->construction, want)); - return; break; default: i_change(&u->items, itype, built); diff --git a/src/exparse.c b/src/exparse.c index 07acb090e..9f49459a9 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -625,6 +625,7 @@ static void handle_requirement(parseinfo *pi, const XML_Char *el, const XML_Char assert(nreqs < MAX_REQUIREMENTS); req = reqs + nreqs; + req->number = 1; for (i = 0; attr[i]; i += 2) { if (xml_strcmp(attr[i], "type") == 0) { req->rtype = rt_get_or_create(attr[i + 1]); diff --git a/src/report.c b/src/report.c index 2a0e9eb3a..407c0c767 100644 --- a/src/report.c +++ b/src/report.c @@ -2212,6 +2212,7 @@ report_plaintext(const char *filename, report_context * ctx, if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER(); } + assert(!rm->rtype); } *bufp = 0; centre(out, buf, true); From ad0464ab50d1615b71a7acd857e68252939196cd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 1 Aug 2018 10:04:12 +0200 Subject: [PATCH 11/17] BUG 2168: call sink_ship for ships that take too much damage. --- clibs | 2 +- scripts/tests/e2/e2features.lua | 13 +++++++++++++ src/battle.c | 5 ++++- src/bind_unit.c | 2 +- src/chaos.c | 20 +++++++++++--------- src/chaos.h | 2 -- src/kernel/ship.h | 6 +++--- src/laws.c | 1 + src/move.c | 9 +++++++-- src/randenc.c | 3 +++ src/spy.c | 25 +++++++++++++++---------- src/spy.h | 6 ++---- 12 files changed, 61 insertions(+), 33 deletions(-) diff --git a/clibs b/clibs index 9b6e34959..d86c85254 160000 --- a/clibs +++ b/clibs @@ -1 +1 @@ -Subproject commit 9b6e34959f77d7ca3a4ce3826cb487487f557441 +Subproject commit d86c8525489d7f11b7ba13e101bb59ecf160b871 diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index be09ec448..721ad7a1c 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -517,3 +517,16 @@ function test_buy_sell() assert_equal(4, u:get_item(item)) assert_not_equal(0, u:get_item('money')) end + +function test_seaserpent_attack() + local r = region.create(0, 0, 'ocean') + local sh = ship.create(r, 'boat') + local us = unit.create(get_monsters(), r, 1, 'seaserpent') + local u = unit.create(faction.create('human'), r, 20, 'human') + u.ship = sh + us:clear_orders() + us:add_order('ATTACKIERE ' .. itoa36(u.id)) + us:set_skill('unarmed', 10) + process_orders() + write_reports() +end diff --git a/src/battle.c b/src/battle.c index 38590b8a6..9e2f841c0 100644 --- a/src/battle.c +++ b/src/battle.c @@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "move.h" #include "skill.h" #include "study.h" +#include "spy.h" #include #include @@ -2787,10 +2788,12 @@ static void aftermath(battle * b) ship *sh = *sp; freset(sh, SF_DAMAGED); if (sh->damage >= sh->size * DAMAGE_SCALE) { + sink_ship(sh); remove_ship(sp, sh); } - if (*sp == sh) + else { sp = &sh->next; + } } } diff --git a/src/bind_unit.c b/src/bind_unit.c index e0fa9f86b..7858aadf2 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -909,8 +909,8 @@ static int tolua_unit_create(lua_State * L) faction *f = (faction *)tolua_tousertype(L, 1, 0); region *r = (region *)tolua_tousertype(L, 2, 0); unit *u; - const char *rcname = tolua_tostring(L, 4, NULL); int num = (int)tolua_tonumber(L, 3, 1); + const char *rcname = tolua_tostring(L, 4, NULL); const race *rc; assert(f && r); diff --git a/src/chaos.c b/src/chaos.c index 21a5a8624..1ec431b7e 100644 --- a/src/chaos.c +++ b/src/chaos.c @@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "chaos.h" #include "monsters.h" #include "move.h" +#include "spy.h" #include #include @@ -144,19 +145,20 @@ static void chaos(region * r) break; } if (dir != MAXDIRECTIONS) { - ship *sh = r->ships; + ship **slist = &r->ships; unit **up; - while (sh) { - ship *nsh = sh->next; - double dmg = - config_get_flt("rules.ship.damage.atlantis", - 0.50); - damage_ship(sh, dmg); + while (*slist) { + ship *sh = *slist; + + damage_ship(sh, 0.5); if (sh->damage >= sh->size * DAMAGE_SCALE) { - remove_ship(&sh->region->ships, sh); + sink_ship(sh); + remove_ship(slist, sh); + } + else { + slist = &sh->next; } - sh = nsh; } for (up = &r->units; *up;) { diff --git a/src/chaos.h b/src/chaos.h index 550aa3efb..cb913d1a0 100644 --- a/src/chaos.h +++ b/src/chaos.h @@ -22,8 +22,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif - struct region; - void chaos_update(void); #ifdef __cplusplus diff --git a/src/kernel/ship.h b/src/kernel/ship.h index c726b4839..ce3283a6f 100644 --- a/src/kernel/ship.h +++ b/src/kernel/ship.h @@ -124,9 +124,9 @@ extern "C" { extern void write_ship_reference(const struct ship *sh, struct storage *store); - extern void remove_ship(struct ship **slist, struct ship *s); - extern void free_ship(struct ship *s); - extern void free_ships(void); + void remove_ship(struct ship **slist, struct ship *s); + void free_ship(struct ship *s); + void free_ships(void); const char *ship_getname(const struct ship *sh); void ship_setname(struct ship *self, const char *name); diff --git a/src/laws.c b/src/laws.c index aa6e237e2..35e4732f1 100644 --- a/src/laws.c +++ b/src/laws.c @@ -2590,6 +2590,7 @@ void sinkships(struct region * r) } } if (sh->damage >= sh->size * DAMAGE_SCALE) { + sink_ship(sh); remove_ship(shp, sh); } if (*shp == sh) diff --git a/src/move.c b/src/move.c index 205b52416..b815f5ea5 100644 --- a/src/move.c +++ b/src/move.c @@ -47,6 +47,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "laws.h" #include "reports.h" #include "study.h" +#include "spy.h" #include "alchemy.h" #include "travelthru.h" #include "vortex.h" @@ -541,6 +542,7 @@ static ship *do_maelstrom(region * r, unit * u) if (sh->damage >= sh->size * DAMAGE_SCALE) { ADDMSG(&u->faction->msgs, msg_message("entermaelstrom", "region ship damage sink", r, sh, damage, 1)); + sink_ship(sh); remove_ship(&sh->region->ships, sh); return NULL; } @@ -882,12 +884,14 @@ static void drifting_ships(region * r) } if (sh->damage >= sh->size * DAMAGE_SCALE) { msg_to_ship_inmates(sh, &firstu, &lastu, msg_message("shipsink", "ship", sh)); - remove_ship(&sh->region->ships, sh); + sink_ship(sh); + remove_ship(shp, sh); } } - if (*shp == sh) + if (*shp == sh) { shp = &sh->next; + } } } } @@ -1926,6 +1930,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting) if (sh->damage >= sh->size * DAMAGE_SCALE) { if (sh->region) { ADDMSG(&f->msgs, msg_message("shipsink", "ship", sh)); + sink_ship(sh); remove_ship(&sh->region->ships, sh); } sh = NULL; diff --git a/src/randenc.c b/src/randenc.c index 7de49b9e2..820d3760f 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "economy.h" #include "monsters.h" #include "move.h" +#include "spy.h" #include "study.h" #include "volcano.h" @@ -295,6 +296,7 @@ static void move_iceberg(region * r) ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg_des", "ship", sh)); } + sink_ship(sh); remove_ship(&sh->region->ships, sh); } else if (u != NULL) { @@ -421,6 +423,7 @@ static void godcurse(void) ADDMSG(&uo->faction->msgs, msg_message("godcurse_destroy_ship", "ship", sh)); } + sink_ship(sh); remove_ship(&sh->region->ships, sh); } sh = shn; diff --git a/src/spy.c b/src/spy.c index 94d6c4e7d..c0afbe43c 100644 --- a/src/spy.c +++ b/src/spy.c @@ -392,19 +392,22 @@ static int try_destruction(unit * u, unit * u2, const ship * sh, int skilldiff) return 1; /* success */ } -static void sink_ship(region * r, ship * sh, unit * saboteur) +#define OCEAN_SWIMMER_CHANCE 0.1 +#define COAST_SWIMMER_CHANCE 0.9 + +void sink_ship(ship * sh) { unit **ui, *u; - region *safety = r; + region *r, *safety; int i; direction_t d; double probability = 0.0; message *sink_msg = NULL; faction *f; - assert(r); - assert(sh); - assert(saboteur); + assert(sh && sh->region); + r = sh->region; + for (f = NULL, u = r->units; u; u = u->next) { /* slight optimization to avoid dereferencing u->faction each time */ if (f != u->faction) { @@ -414,8 +417,9 @@ static void sink_ship(region * r, ship * sh, unit * saboteur) } /* figure out what a unit's chances of survival are: */ + safety = r; if (!(r->terrain->flags & SEA_REGION)) { - probability = CANAL_SWIMMER_CHANCE; + probability = COAST_SWIMMER_CHANCE; } else { for (d = 0; d != MAXDIRECTIONS; ++d) { @@ -479,10 +483,9 @@ static void sink_ship(region * r, ship * sh, unit * saboteur) } ui = &u->next; } - if (sink_msg) + if (sink_msg) { msg_release(sink_msg); - /* finally, get rid of the ship */ - remove_ship(&sh->region->ships, sh); + } } int sabotage_cmd(unit * u, struct order *ord) @@ -514,7 +517,9 @@ int sabotage_cmd(unit * u, struct order *ord) effskill(u, SK_SPY, 0) - top_skill(u->region, u2->faction, sh, SK_PERCEPTION); } if (try_destruction(u, u2, sh, skdiff)) { - sink_ship(u->region, sh, u); + sink_ship(sh); + /* finally, get rid of the ship */ + remove_ship(&sh->region->ships, sh); } break; default: diff --git a/src/spy.h b/src/spy.h index 665595ef4..b0bd7ae0e 100644 --- a/src/spy.h +++ b/src/spy.h @@ -27,6 +27,7 @@ extern "C" { struct strlist; struct order; struct faction; + struct ship; int setstealth_cmd(struct unit *u, struct order *ord); int spy_cmd(struct unit *u, struct order *ord); @@ -34,10 +35,7 @@ extern "C" { void spy_message(int spy, const struct unit *u, const struct unit *target); void set_factionstealth(struct unit * u, struct faction * f); - - -#define OCEAN_SWIMMER_CHANCE 0.1 -#define CANAL_SWIMMER_CHANCE 0.9 + void sink_ship(struct ship * sh); #ifdef __cplusplus } From e89fe69d58518d76f1b28627655a5a9cbaabbfa8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 1 Aug 2018 11:55:57 +0200 Subject: [PATCH 12/17] simplicate the sink_ship function, do not rescue units. --- res/core/messages.xml | 15 ------ res/translations/messages.de.po | 6 --- res/translations/messages.en.po | 6 --- scripts/tests/e2/e2features.lua | 2 +- src/move.test.c | 3 ++ src/spy.c | 83 ++++++--------------------------- src/spy.test.c | 54 ++++++++++++++++----- 7 files changed, 60 insertions(+), 109 deletions(-) diff --git a/res/core/messages.xml b/res/core/messages.xml index d566c82e6..0cd66ca08 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -868,21 +868,6 @@ - - - - - - - - - - - - - - - diff --git a/res/translations/messages.de.po b/res/translations/messages.de.po index b87fe241a..1d45faaff 100644 --- a/res/translations/messages.de.po +++ b/res/translations/messages.de.po @@ -2303,9 +2303,6 @@ msgstr "\"$unit($mage) erleidet durch den Tod seines Vertrauten einen Schock.\"" msgid "error269" msgstr "\"$unit($unit) in $region($region): '$order($command)' - Hier kann man nicht zaubern.\"" -msgid "sink_saved_msg" -msgstr "\"$unit($unit) überlebt unbeschadet und rettet sich nach $region($region).\"" - msgid "race_noregroup" msgstr "\"$unit($unit) in $region($region): '$order($command)' - $race($race,0) können nicht neu gruppiert werden.\"" @@ -2654,9 +2651,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit kan msgid "analyse_building_noage" msgstr "\"$unit($mage) fand heraus, dass auf $building($building) der Zauber '$curse($curse)' liegt, dessen Kraft ausreicht, um noch Jahrhunderte bestehen zu bleiben.\"" -msgid "sink_lost_msg" -msgstr "\"$int($amount) Personen von $unit($unit) ertrinken.$if($isnull($region),\"\",\" Die Einheit rettet sich nach $region($region).\")\"" - msgid "error130" msgstr "\"$unit($unit) in $region($region): '$order($command)' - Syntax: MAGIEGEBIET [1-5].\"" diff --git a/res/translations/messages.en.po b/res/translations/messages.en.po index 6eaf6f258..bf9d8e3c9 100644 --- a/res/translations/messages.en.po +++ b/res/translations/messages.en.po @@ -2303,9 +2303,6 @@ msgstr "\"$unit($mage) receives a shock when his familiar dies.\"" msgid "error269" msgstr "\"$unit($unit) in $region($region): '$order($command)' - You cannot cast spells here.\"" -msgid "sink_saved_msg" -msgstr "\"$unit($unit) survives unscathed and makes it to $region($region).\"" - msgid "race_noregroup" msgstr "\"$unit($unit) in $region($region): '$order($command)' - $race($race,0) cannot be regrouped.\"" @@ -2654,9 +2651,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit cannot msgid "analyse_building_noage" msgstr "\"$unit($mage) discovers that $building($building) is charmed with '$curse($curse)', which will last for centuries.\"" -msgid "sink_lost_msg" -msgstr "\"$int($amount) people of $unit($unit) drown.$if($isnull($region),\"\",\" The unit makes it to $region($region).\")\"" - msgid "error130" msgstr "\"$unit($unit) in $region($region): '$order($command)' - Syntax: MAGIC SPHERE [1-5].\"" diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index 721ad7a1c..bf90ab6a0 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -522,7 +522,7 @@ function test_seaserpent_attack() local r = region.create(0, 0, 'ocean') local sh = ship.create(r, 'boat') local us = unit.create(get_monsters(), r, 1, 'seaserpent') - local u = unit.create(faction.create('human'), r, 20, 'human') + local u = unit.create(faction.create('human', 'enno@example.com'), r, 20, 'human') u.ship = sh us:clear_orders() us:add_order('ATTACKIERE ' .. itoa36(u.id)) diff --git a/src/move.test.c b/src/move.test.c index f8c11114f..f01915e2a 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -287,6 +287,9 @@ void setup_drift (struct drift_fixture *fix) { u_set_ship(fix->u, fix->sh = test_create_ship(fix->u->region, fix->st_boat)); assert(fix->sh); + mt_create_va(mt_new("sink_msg", NULL), + "ship:ship", "region:region", MT_NEW_END); + mt_create_va(mt_new("ship_drift", NULL), "ship:ship", "dir:int", MT_NEW_END); mt_create_va(mt_new("shipsink", NULL), diff --git a/src/spy.c b/src/spy.c index c0afbe43c..ae70f4db8 100644 --- a/src/spy.c +++ b/src/spy.c @@ -392,16 +392,10 @@ static int try_destruction(unit * u, unit * u2, const ship * sh, int skilldiff) return 1; /* success */ } -#define OCEAN_SWIMMER_CHANCE 0.1 -#define COAST_SWIMMER_CHANCE 0.9 - void sink_ship(ship * sh) { - unit **ui, *u; - region *r, *safety; - int i; - direction_t d; - double probability = 0.0; + unit *u; + region *r; message *sink_msg = NULL; faction *f; @@ -416,72 +410,23 @@ void sink_ship(ship * sh) } } - /* figure out what a unit's chances of survival are: */ - safety = r; - if (!(r->terrain->flags & SEA_REGION)) { - probability = COAST_SWIMMER_CHANCE; - } - else { - for (d = 0; d != MAXDIRECTIONS; ++d) { - region *rn = rconnect(r, d); - if (rn && !(rn->terrain->flags & SEA_REGION) && !move_blocked(NULL, r, rn)) { - safety = rn; - probability = OCEAN_SWIMMER_CHANCE; - break; - } - } - } - for (ui = &r->units; *ui;) { + for (f = NULL, u = r->units; u; u = u->next) { /* inform this faction about the sinking ship: */ - u = *ui; - if (!(u->faction->flags & FFL_SELECT)) { - fset(u->faction, FFL_SELECT); - if (sink_msg == NULL) { - sink_msg = msg_message("sink_msg", "ship region", sh, r); - } - add_message(&f->msgs, sink_msg); - } - if (u->ship == sh) { - int dead = 0; - message *msg; - - /* if this fails, I misunderstood something: */ - for (i = 0; i != u->number; ++i) - if (chance(probability)) - ++dead; - - if (dead != u->number) { - /* she will live. but her items get stripped */ - if (dead > 0) { - msg = - msg_message("sink_lost_msg", "dead region unit", dead, safety, u); - } - else { - msg = msg_message("sink_saved_msg", "region unit", safety, u); - } - leave_ship(u); - if (r != safety) { - setguard(u, false); - } - while (u->items) { - i_remove(&u->items, u->items); - } - move_unit(u, safety, NULL); - } - else { - msg = msg_message("sink_lost_msg", "dead region unit", dead, (region *)NULL, u); - } - add_message(&u->faction->msgs, msg); - msg_release(msg); - if (dead == u->number) { - if (remove_unit(ui, u) == 0) { - /* ui is already pointing at u->next */ - continue; + if (f != u->faction) { + f = u->faction; + if (!(f->flags & FFL_SELECT)) { + f->flags |= FFL_SELECT; + if (sink_msg == NULL) { + sink_msg = msg_message("sink_msg", "ship region", sh, r); + } + add_message(&f->msgs, sink_msg); } } } - ui = &u->next; + else if (f != NULL) { + break; + } } if (sink_msg) { msg_release(sink_msg); diff --git a/src/spy.test.c b/src/spy.test.c index ed10c4b7e..0224698a0 100644 --- a/src/spy.test.c +++ b/src/spy.test.c @@ -55,10 +55,6 @@ static void setup_spy(spy_fixture *fix) { "ship:ship", MT_NEW_END); mt_create_va(mt_new("sink_msg", NULL), "ship:ship", "region:region", MT_NEW_END); - mt_create_va(mt_new("sink_lost_msg", NULL), - "unit:unit", "region:region", "dead:int", MT_NEW_END); - mt_create_va(mt_new("sink_saved_msg", NULL), - "unit:unit", "region:region", MT_NEW_END); if (fix) { fix->r = test_create_region(0, 0, NULL); @@ -112,6 +108,7 @@ static void test_sabotage_self(CuTest *tc) { unit *u; region *r; order *ord; + message *msg; test_setup(); setup_spy(NULL); @@ -119,17 +116,49 @@ static void test_sabotage_self(CuTest *tc) { assert(r); u = test_create_unit(test_create_faction(NULL), r); assert(u && u->faction && u->region == r); - u->ship = test_create_ship(r, test_create_shiptype("boat")); + u->ship = test_create_ship(r, NULL); assert(u->ship); ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF"); assert(ord); CuAssertIntEquals(tc, 0, sabotage_cmd(u, ord)); - CuAssertPtrEquals(tc, 0, r->ships); - CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "sink_msg")); + CuAssertPtrEquals(tc, NULL, r->ships); + CuAssertPtrNotNull(tc, msg = test_find_messagetype(u->faction->msgs, "sink_msg")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype_ex(u->faction->msgs, "sink_msg", msg)); free_order(ord); test_teardown(); } +static void test_sink_ship(CuTest *tc) { + ship *sh; + unit *u1, *u2, *u3; + region *r; + message *msg; + + test_setup(); + setup_spy(NULL); + r = test_create_ocean(0, 0); + u1 = test_create_unit(test_create_faction(NULL), r); + u2 = test_create_unit(u1->faction, r); + u3 = test_create_unit(test_create_faction(NULL), r); + u1->ship = u2->ship = u3->ship = sh = test_create_ship(r, NULL); + + sink_ship(sh); + CuAssertPtrEquals(tc, r, sh->region); + CuAssertPtrEquals(tc, sh, r->ships); + CuAssertPtrNotNull(tc, msg = test_find_messagetype(u1->faction->msgs, "sink_msg")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype_ex(u1->faction->msgs, "sink_msg", msg)); + CuAssertPtrNotNull(tc, msg = test_find_messagetype(u3->faction->msgs, "sink_msg")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype_ex(u3->faction->msgs, "sink_msg", msg)); + + remove_ship(&r->ships, sh); + CuAssertPtrEquals(tc, NULL, sh->region); + CuAssertPtrEquals(tc, NULL, r->ships); + CuAssertPtrEquals(tc, NULL, u1->ship); + CuAssertPtrEquals(tc, NULL, u2->ship); + CuAssertPtrEquals(tc, NULL, u3->ship); + + test_teardown(); +} static void test_sabotage_other_fail(CuTest *tc) { unit *u, *u2; @@ -145,7 +174,7 @@ static void test_sabotage_other_fail(CuTest *tc) { u = test_create_unit(test_create_faction(NULL), r); u2 = test_create_unit(test_create_faction(NULL), r); assert(u && u2); - u2->ship = test_create_ship(r, test_create_shiptype("boat")); + u2->ship = test_create_ship(r, NULL); assert(u2->ship); u->ship = u2->ship; ship_update_owner(u->ship); @@ -167,7 +196,7 @@ static void test_setstealth_cmd(CuTest *tc) { const struct locale *lang; test_setup(); - u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); + u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0)); lang = u->faction->locale; u->flags = UFL_ANON_FACTION | UFL_SIEGE; u->thisorder = create_order(K_SETSTEALTH, lang, "%s %s", @@ -191,7 +220,7 @@ static void test_setstealth_demon(CuTest *tc) { test_setup(); lang = test_create_locale(); rc = test_create_race("demon"); - u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); + u = test_create_unit(test_create_faction(rc), test_create_plain(0, 0)); rc = test_create_race("dwarf"); init_races(lang); u->thisorder = create_order(K_SETSTEALTH, lang, racename(lang, u, rc)); @@ -208,7 +237,7 @@ static void test_setstealth_demon_bad(CuTest *tc) { test_setup(); lang = test_create_locale(); rc = test_create_race("demon"); - u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); + u = test_create_unit(test_create_faction(rc), test_create_plain(0, 0)); rc = test_create_race("smurf"); rc->flags &= ~RCF_PLAYABLE; @@ -232,7 +261,7 @@ static void test_sabotage_other_success(CuTest *tc) { u = test_create_unit(test_create_faction(NULL), r); u2 = test_create_unit(test_create_faction(NULL), r); assert(u && u2); - u2->ship = test_create_ship(r, test_create_shiptype("boat")); + u2->ship = test_create_ship(r, NULL); assert(u2->ship); u->ship = u2->ship; ship_update_owner(u->ship); @@ -251,6 +280,7 @@ CuSuite *get_spy_suite(void) CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_simple_spy_message); SUITE_ADD_TEST(suite, test_all_spy_message); + SUITE_ADD_TEST(suite, test_sink_ship); SUITE_ADD_TEST(suite, test_sabotage_self); SUITE_ADD_TEST(suite, test_setstealth_cmd); SUITE_ADD_TEST(suite, test_setstealth_demon); From 3880960acf47510d63a0a9a9b93cf470e3c1848e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 2 Aug 2018 13:53:41 +0200 Subject: [PATCH 13/17] BUG 2458: fix insect recruit warnings. --- res/translations/messages.de.po | 4 +-- src/economy.c | 2 +- src/reports.c | 27 +++++++++---------- src/reports.h | 2 +- src/reports.test.c | 47 +++++++++++++++++++++++++-------- 5 files changed, 52 insertions(+), 30 deletions(-) diff --git a/res/translations/messages.de.po b/res/translations/messages.de.po index 1d45faaff..507f0e39d 100644 --- a/res/translations/messages.de.po +++ b/res/translations/messages.de.po @@ -1773,7 +1773,7 @@ msgid "storm" msgstr "\"Die $ship($ship) wird in $region($region) von Stürmen abgetrieben$if($sink,\" und sinkt\",\"\").\"" msgid "nr_insectwinter" -msgstr "Es ist Winter, und Insekten können nur in Wüsten oder mit Hilfe des Nestwärme-Tranks Personen rekrutieren." +msgstr "Insekten können wegen des Winterwetters in der kommenden Woche nur in Wüsten oder mit Hilfe des Nestwärme-Tranks Personen rekrutieren." msgid "spellfail_nomonsters" msgstr "\"$unit($unit) in $region($region): '$order($command)' - Dieser Zauber kann nicht auf Monster gezaubert werden.\"" @@ -2727,7 +2727,7 @@ msgid "volcanostartsmoke" msgstr "\"Aus dem Vulkankrater von $region($region) steigt plötzlich Rauch.\"" msgid "nr_insectfall" -msgstr "Es ist Spätherbst, und diese Woche ist die letzte vor dem Winter, in der Insekten rekrutieren können." +msgstr "Es ist Spätherbst, und die kommende Woche ist die letzte vor dem Winter, in der Insekten rekrutieren können." msgid "error296" msgstr "\"$unit($unit) in $region($region): '$order($command)' - Hier werden niemals Bäume wachsen.\"" diff --git a/src/economy.c b/src/economy.c index 3bb7b1066..ae5be2c77 100644 --- a/src/economy.c +++ b/src/economy.c @@ -477,7 +477,7 @@ static void recruit(unit * u, struct order *ord, econ_request ** recruitorders) if (rc == get_race(RC_INSECT)) { gamedate date; get_gamedate(turn, &date); - if (date.season == 0 && r->terrain != newterrain(T_DESERT)) { + if (date.season == SEASON_WINTER && r->terrain != newterrain(T_DESERT)) { bool usepotion = false; unit *u2; diff --git a/src/reports.c b/src/reports.c index ac413bfc6..9d9ab5f6f 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1517,24 +1517,23 @@ static void cb_add_seen(region *r, unit *u, void *cbdata) { } } -void report_warnings(faction *f, const gamedate *date) +void report_warnings(faction *f, int now) { if (f->age < NewbieImmunity()) { ADDMSG(&f->msgs, msg_message("newbieimmunity", "turns", NewbieImmunity() - f->age)); } - if (date) { - if (f->race == get_race(RC_INSECT)) { - if (date->season == 0) { - ADDMSG(&f->msgs, msg_message("nr_insectwinter", "")); - } - else { - gamedate next; - get_gamedate(date->turn + 1, &next); - if (next.season == 0) { - ADDMSG(&f->msgs, msg_message("nr_insectfall", "")); - } + if (f->race == get_race(RC_INSECT)) { + gamedate date; + get_gamedate(now + 1, &date); + + if (date.season == SEASON_WINTER) { + ADDMSG(&f->msgs, msg_message("nr_insectwinter", "")); + } + else if (date.season == SEASON_AUTUMN) { + if (get_gamedate(now + 2 + 2, &date)->season == SEASON_WINTER) { + ADDMSG(&f->msgs, msg_message("nr_insectfall", "")); } } } @@ -1552,11 +1551,9 @@ void prepare_report(report_context *ctx, faction *f) static bool rule_region_owners; static bool rule_lighthouse_units; const struct building_type *bt_lighthouse = bt_find("lighthouse"); - gamedate now; /* Insekten-Winter-Warnung */ - get_gamedate(turn, &now); - report_warnings(f, &now); + report_warnings(f, turn); if (bt_lighthouse && config_changed(&config)) { rule_region_owners = config_token("rules.region_owner_pay_building", bt_lighthouse->_name); diff --git a/src/reports.h b/src/reports.h index 0bdaf7d8c..a6dddb1b4 100644 --- a/src/reports.h +++ b/src/reports.h @@ -115,7 +115,7 @@ extern "C" { int size, const struct faction *viewer, bool see_unit); int report_items(const struct unit *u, struct item *result, int size, const struct unit *owner, const struct faction *viewer); - void report_warnings(struct faction *f, const struct gamedate *date); + void report_warnings(struct faction *f, int now); void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length); void report_race_skills(const struct race *rc, char *zText, size_t length, const struct locale *lang); void report_item(const struct unit *owner, const struct item *i, diff --git a/src/reports.test.c b/src/reports.test.c index e86080b0e..703abc232 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -785,23 +785,48 @@ static void test_stealth_modifier(CuTest *tc) { test_teardown(); } +static void setup_calendar(void) { + months_per_year = 9; + month_season = malloc(sizeof(int) * months_per_year); + month_season[0] = SEASON_SUMMER; + month_season[1] = SEASON_AUTUMN; + month_season[2] = SEASON_AUTUMN; + month_season[3] = SEASON_WINTER; + month_season[4] = SEASON_WINTER; + month_season[5] = SEASON_WINTER; + month_season[6] = SEASON_SPRING; + month_season[7] = SEASON_SPRING; + month_season[8] = SEASON_SUMMER; +} + static void test_insect_warnings(CuTest *tc) { faction *f; gamedate gd; - /* OBS: in unit tests, get_gamedate always returns season = 0 */ test_setup(); + setup_calendar(); + config_set_int("game.start", 184); test_inject_messagetypes(); f = test_create_faction(test_create_race("insect")); - gd.turn = 0; - gd.season = 3; - report_warnings(f, &gd); - CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "nr_insectfall")); - - gd.season = 0; - report_warnings(f, &gd); + CuAssertIntEquals(tc, SEASON_AUTUMN, get_gamedate(1083, &gd)->season); + report_warnings(f, gd.turn); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "nr_insectfall")); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "nr_insectwinter")); + test_clear_messages(f); + + CuAssertIntEquals(tc, SEASON_AUTUMN, get_gamedate(1082, &gd)->season); + report_warnings(f, gd.turn); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "nr_insectfall")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "nr_insectwinter")); + test_clear_messages(f); + + CuAssertIntEquals(tc, SEASON_WINTER, get_gamedate(1084, &gd)->season); + report_warnings(f, gd.turn); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "nr_insectfall")); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "nr_insectwinter")); + test_clear_messages(f); + test_teardown(); } @@ -810,16 +835,16 @@ static void test_newbie_warning(CuTest *tc) { test_setup(); test_inject_messagetypes(); - f = test_create_faction(test_create_race("insect")); + f = test_create_faction(NULL); config_set_int("NewbieImmunity", 3); f->age = 2; - report_warnings(f, NULL); + report_warnings(f, 0); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "newbieimmunity")); test_clear_messages(f); f->age = 3; - report_warnings(f, NULL); + report_warnings(f, 0); CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "newbieimmunity")); test_clear_messages(f); From 8d8857957095c8af259d6ddfac138022233f54d0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 2 Aug 2018 14:31:00 +0200 Subject: [PATCH 14/17] Refactor: extract can_recruit, write tests for insects. --- src/economy.c | 152 +++++++++++++++++++++++---------------------- src/economy.h | 2 + src/economy.test.c | 30 +++++++++ src/reports.test.c | 17 +---- src/tests.c | 15 +++++ src/tests.h | 1 + 6 files changed, 128 insertions(+), 89 deletions(-) diff --git a/src/economy.c b/src/economy.c index ae5be2c77..dc7e6148b 100644 --- a/src/economy.c +++ b/src/economy.c @@ -426,6 +426,59 @@ static int recruit_cost(const faction * f, const race * rc) return -1; } +message *can_recruit(unit *u, const race *rc, order *ord, int now) +{ + region *r = u->region; + + /* this is a very special case because the recruiting unit may be empty + * at this point and we have to look at the creating unit instead. This + * is done in cansee, which is called indirectly by is_guarded(). */ + if (is_guarded(r, u)) { + return msg_error(u, ord, 70); + } + + if (rc == get_race(RC_INSECT)) { + gamedate date; + get_gamedate(now, &date); + if (date.season == SEASON_WINTER && r->terrain != newterrain(T_DESERT)) { + bool usepotion = false; + unit *u2; + + for (u2 = r->units; u2; u2 = u2->next) { + if (fval(u2, UFL_WARMTH)) { + usepotion = true; + break; + } + } + if (!usepotion) { + return msg_error(u, ord, 98); + } + } + /* in Gletschern, Eisbergen gar nicht rekrutieren */ + if (r_insectstalled(r)) { + return msg_error(u, ord, 97); + } + } + if (is_cursed(r->attribs, &ct_riotzone)) { + /* Die Region befindet sich in Aufruhr */ + return msg_error(u, ord, 237); + } + + if (rc && !playerrace(rc)) { + return msg_error(u, ord, 139); + } + + if (fval(u, UFL_HERO)) { + return msg_feedback(u, ord, "error_herorecruit", ""); + } + if (has_skill(u, SK_MAGIC)) { + /* error158;de;{unit} in {region}: '{command}' - Magier arbeiten + * grunds�tzlich nur alleine! */ + return msg_error(u, ord, 158); + } + return NULL; +} + static void recruit(unit * u, struct order *ord, econ_request ** recruitorders) { region *r = u->region; @@ -434,6 +487,7 @@ static void recruit(unit * u, struct order *ord, econ_request ** recruitorders) const faction *f = u->faction; const struct race *rc = u_race(u); int n; + message *msg; init_order_depr(ord); n = getint(); @@ -456,6 +510,7 @@ static void recruit(unit * u, struct order *ord, econ_request ** recruitorders) } } } + if (recruitcost < 0) { rc = u_race(u); recruitcost = recruit_cost(f, rc); @@ -463,95 +518,46 @@ static void recruit(unit * u, struct order *ord, econ_request ** recruitorders) recruitcost = INT_MAX; } } - assert(rc); - u_setrace(u, rc); - /* this is a very special case because the recruiting unit may be empty - * at this point and we have to look at the creating unit instead. This - * is done in cansee, which is called indirectly by is_guarded(). */ - if (is_guarded(r, u)) { - cmistake(u, ord, 70, MSG_EVENT); - return; - } - - if (rc == get_race(RC_INSECT)) { - gamedate date; - get_gamedate(turn, &date); - if (date.season == SEASON_WINTER && r->terrain != newterrain(T_DESERT)) { - bool usepotion = false; - unit *u2; - - for (u2 = r->units; u2; u2 = u2->next) - if (fval(u2, UFL_WARMTH)) { - usepotion = true; - break; - } - if (!usepotion) - { - cmistake(u, ord, 98, MSG_EVENT); - return; - } - } - /* in Gletschern, Eisbergen gar nicht rekrutieren */ - if (r_insectstalled(r)) { - cmistake(u, ord, 97, MSG_EVENT); - return; - } - } - if (is_cursed(r->attribs, &ct_riotzone)) { - /* Die Region befindet sich in Aufruhr */ - cmistake(u, ord, 237, MSG_EVENT); - return; - } - - if (recruitcost) { + if (recruitcost > 0) { + int pool; plane *pl = getplane(r); - if (pl && fval(pl, PFL_NORECRUITS)) { + + if (pl && (pl->flags & PFL_NORECRUITS)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_pflnorecruit", "")); return; } - if (get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, - recruitcost) < recruitcost) { + pool = get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, recruitcost * n); + if (pool < recruitcost) { cmistake(u, ord, 142, MSG_EVENT); return; } + pool /= recruitcost; + if (n > pool) n = pool; } - if (!playerrace(rc)) { - cmistake(u, ord, 139, MSG_EVENT); - return; - } - - if (fval(u, UFL_HERO)) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_herorecruit", "")); - return; - } - if (has_skill(u, SK_MAGIC)) { - /* error158;de;{unit} in {region}: '{command}' - Magier arbeiten - * grunds�tzlich nur alleine! */ - cmistake(u, ord, 158, MSG_EVENT); - return; - } - if (has_skill(u, SK_ALCHEMY) - && count_skill(u->faction, SK_ALCHEMY) + n > - skill_limit(u->faction, SK_ALCHEMY)) { - cmistake(u, ord, 156, MSG_EVENT); - return; - } - if (recruitcost > 0) { - int pooled = - get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, recruitcost * n); - int pr = pooled / recruitcost; - if (n > pr) n = pr; - } - - u->wants = n; if (!n) { cmistake(u, ord, 142, MSG_EVENT); return; } + if (has_skill(u, SK_ALCHEMY)) { + if (count_skill(u->faction, SK_ALCHEMY) + n > skill_limit(u->faction, SK_ALCHEMY)) { + cmistake(u, ord, 156, MSG_EVENT); + return; + } + } + assert(rc); + msg = can_recruit(u, rc, ord, turn); + if (msg) { + add_message(&u->faction->msgs, msg); + msg_release(msg); + return; + } + + u_setrace(u, rc); + u->wants = n; o = (econ_request *)calloc(1, sizeof(econ_request)); o->qty = n; o->unit = u; diff --git a/src/economy.h b/src/economy.h index 67762b513..9456a4c93 100644 --- a/src/economy.h +++ b/src/economy.h @@ -44,6 +44,7 @@ extern "C" { #define MAXNEWBIES 5 struct unit; + struct race; struct region; struct faction; struct order; @@ -94,6 +95,7 @@ extern "C" { void steal_cmd(struct unit * u, struct order *ord, struct econ_request ** stealorders); void expandstealing(struct region * r, struct econ_request * stealorders); + struct message *can_recruit(struct unit *u, const struct race *rc, struct order *ord, int now); void add_recruits(struct unit * u, int number, int wanted); #ifdef __cplusplus diff --git a/src/economy.test.c b/src/economy.test.c index 91d462770..90a4bd260 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -480,6 +480,35 @@ static void test_recruit(CuTest *tc) { test_teardown(); } +static void test_recruit_insect(CuTest *tc) { + unit *u; + faction *f; + message * msg; + + test_setup(); + test_create_calendar(); + f = test_create_faction(test_create_race("insect")); + u = test_create_unit(f, test_create_region(0, 0, NULL)); + u->thisorder = create_order(K_RECRUIT, f->locale, "%d", 1); + + msg = can_recruit(u, f->race, u->thisorder, 1083); /* Autumn */ + CuAssertPtrEquals(tc, NULL, msg); + + msg = can_recruit(u, f->race, u->thisorder, 1084); /* Insects, Winter */ + CuAssertPtrNotNull(tc, msg); + msg_release(msg); + + u->flags |= UFL_WARMTH; + msg = can_recruit(u, f->race, u->thisorder, 1084); /* Insects, potion, Winter */ + CuAssertPtrEquals(tc, NULL, msg); + + u->flags = 0; + msg = can_recruit(u, NULL, u->thisorder, 1084); /* Other races, Winter */ + CuAssertPtrEquals(tc, NULL, msg); + + test_teardown(); +} + static void test_income(CuTest *tc) { race *rc; @@ -764,6 +793,7 @@ CuSuite *get_economy_suite(void) SUITE_ADD_TEST(suite, test_trade_insect); SUITE_ADD_TEST(suite, test_maintain_buildings); SUITE_ADD_TEST(suite, test_recruit); + SUITE_ADD_TEST(suite, test_recruit_insect); SUITE_ADD_TEST(suite, test_loot); SUITE_ADD_TEST(suite, test_expand_production); return suite; diff --git a/src/reports.test.c b/src/reports.test.c index 703abc232..65b5b06b0 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -785,27 +785,12 @@ static void test_stealth_modifier(CuTest *tc) { test_teardown(); } -static void setup_calendar(void) { - months_per_year = 9; - month_season = malloc(sizeof(int) * months_per_year); - month_season[0] = SEASON_SUMMER; - month_season[1] = SEASON_AUTUMN; - month_season[2] = SEASON_AUTUMN; - month_season[3] = SEASON_WINTER; - month_season[4] = SEASON_WINTER; - month_season[5] = SEASON_WINTER; - month_season[6] = SEASON_SPRING; - month_season[7] = SEASON_SPRING; - month_season[8] = SEASON_SUMMER; -} - static void test_insect_warnings(CuTest *tc) { faction *f; gamedate gd; test_setup(); - setup_calendar(); - config_set_int("game.start", 184); + test_create_calendar(); test_inject_messagetypes(); f = test_create_faction(test_create_race("insect")); diff --git a/src/tests.c b/src/tests.c index 09f533a9f..4ee38d195 100644 --- a/src/tests.c +++ b/src/tests.c @@ -260,6 +260,21 @@ static void test_reset(void) { } } +void test_create_calendar(void) { + config_set_int("game.start", 184); + months_per_year = 9; + month_season = malloc(sizeof(int) * months_per_year); + month_season[0] = SEASON_SUMMER; + month_season[1] = SEASON_AUTUMN; + month_season[2] = SEASON_AUTUMN; + month_season[3] = SEASON_WINTER; + month_season[4] = SEASON_WINTER; + month_season[5] = SEASON_WINTER; + month_season[6] = SEASON_SPRING; + month_season[7] = SEASON_SPRING; + month_season[8] = SEASON_SUMMER; +} + void test_inject_messagetypes(void) { message_handle_missing(MESSAGE_MISSING_REPLACE); diff --git a/src/tests.h b/src/tests.h index dd8bed3c8..441db9e16 100644 --- a/src/tests.h +++ b/src/tests.h @@ -40,6 +40,7 @@ extern "C" { struct log_t * test_log_start(int flags, struct strlist **slist); void test_log_stop(struct log_t *log, struct strlist *slist); + void test_create_calendar(void); struct locale * test_create_locale(void); struct terrain_type * test_create_terrain(const char * name, int flags); struct race *test_create_race(const char *name); From 116ff7247dcde0be4334748f47b555f7c11022df Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 2 Aug 2018 16:41:23 +0200 Subject: [PATCH 15/17] Remove unused "message" events (old NPC sh*t). --- src/laws.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/laws.c b/src/laws.c index 35e4732f1..8d75b0897 100644 --- a/src/laws.c +++ b/src/laws.c @@ -2058,17 +2058,6 @@ int mail_cmd(unit * u, struct order *ord) break; } else { - attrib *a = a_find(u2->attribs, &at_eventhandler); - if (a != NULL) { - event_arg args[3]; - args[0].data.v = (void *)s; - args[0].type = "string"; - args[1].data.v = (void *)u; - args[1].type = "unit"; - args[2].type = NULL; - handle_event(a, "message", args); - } - mailunit(r, u, n, ord, s); } return 0; From fc0616ed1ec8d59636e74713ea0eb6f5e0051ddd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Aug 2018 06:47:29 +0200 Subject: [PATCH 16/17] kill lua triggers for npc logic, never used. --- scripts/tests/common.lua | 39 --------------------------------------- src/bind_unit.c | 32 -------------------------------- 2 files changed, 71 deletions(-) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index febcc2a3f..403db0a46 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -338,45 +338,6 @@ function test_message() return msg end -function test_events() - local fail = 1 - local function msg_handler(u, evt) - str = evt:get(0) - u2 = evt:get(1) - assert(u2~=nil) - assert(str=="Du Elf stinken") - message_unit(u, u2, "thanks unit, i got your message: " .. str) - message_faction(u, u2.faction, "thanks faction, i got your message: " .. str) - message_region(u, "thanks region, i got your message: " .. str) - fail = 0 - end - - plain = region.create(0, 0, "plain") - skill = 8 - - f = create_faction('elf') - f.age = 20 - - u = unit.create(f, plain) - u.number = 1 - u:add_item("money", u.number*100) - u:clear_orders() - u:add_order("NUMMER PARTEI test") - u:add_handler("message", msg_handler) - msg = "BOTSCHAFT EINHEIT " .. itoa36(u.id) .. " Du~Elf~stinken" - f = create_faction('elf') - f.age = 20 - - u = unit.create(f, plain) - u.number = 1 - u:add_item("money", u.number*100) - u:clear_orders() - u:add_order("NUMMER PARTEI eviL") - u:add_order(msg) - process_orders() - assert(fail==0) -end - function test_renumber_ship() local r = region.create(0, 0, "plain") local f = create_faction('human') diff --git a/src/bind_unit.c b/src/bind_unit.c index 7858aadf2..c6b045d33 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -468,35 +468,6 @@ static void fctr_done(trigger * t) free(fd); } -static struct trigger_type tt_lua = { - "lua_event", - fctr_init, - fctr_done, - fctr_handle -}; - -static trigger *trigger_lua(struct unit *u, int handle) -{ - trigger *t = t_new(&tt_lua); - fctr_data *td = (fctr_data *)t->data.v; - td->target = u; - td->fhandle = handle; - return t; -} - -static int tolua_unit_addhandler(lua_State * L) -{ - unit *self = (unit *)tolua_tousertype(L, 1, 0); - const char *ename = tolua_tostring(L, 2, 0); - int handle; - - lua_pushvalue(L, 3); - handle = luaL_ref(L, LUA_REGISTRYINDEX); - add_trigger(&self->attribs, ename, trigger_lua(self, handle)); - - return 0; -} - static int tolua_unit_addnotice(lua_State * L) { unit *self = (unit *)tolua_tousertype(L, 1, 0); @@ -1046,9 +1017,6 @@ void tolua_unit_open(lua_State * L) tolua_function(L, TOLUA_CAST "add_notice", tolua_unit_addnotice); - /* npc logic: */ - tolua_function(L, TOLUA_CAST "add_handler", tolua_unit_addhandler); - tolua_variable(L, TOLUA_CAST "race_name", tolua_unit_get_racename, tolua_unit_set_racename); tolua_function(L, TOLUA_CAST "add_spell", tolua_unit_addspell); From 4978e95b9ae9c5b113617b2a1f29fe5f1f638bbc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Aug 2018 06:52:37 +0200 Subject: [PATCH 17/17] delete leftover npc callbacks. --- src/bind_unit.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/bind_unit.c b/src/bind_unit.c index c6b045d33..fddcd5608 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -455,19 +455,6 @@ int fctr_handle(struct trigger *tp, void *data) return 0; } -static void fctr_init(trigger * t) -{ - t->data.v = calloc(sizeof(fctr_data), 1); -} - -static void fctr_done(trigger * t) -{ - fctr_data *fd = (fctr_data *)t->data.v; - lua_State *L = (lua_State *)global.vm_state; - luaL_unref(L, LUA_REGISTRYINDEX, fd->fhandle); - free(fd); -} - static int tolua_unit_addnotice(lua_State * L) { unit *self = (unit *)tolua_tousertype(L, 1, 0);