From d9cbbd9052ea3a756de3a8272646f5bae7c7746e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 20 Oct 2019 17:11:58 +0200 Subject: [PATCH 01/10] Bug 2614: Einheiten bewachen Region vor sich selbst. --- src/economy.c | 5 ++--- src/modules/autoseed.c | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/economy.c b/src/economy.c index b73845c06..377a71a6c 100644 --- a/src/economy.c +++ b/src/economy.c @@ -607,9 +607,8 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) if (itype->rtype && (itype->rtype == get_resourcetype(R_IRON) || itype->rtype == rt_find("laen"))) { unit *u2; for (u2 = r->units; u2; u2 = u2->next) { - if (is_guard(u) - && !fval(u2, UFL_ISNEW) - && u2->number && !alliedunit(u2, u->faction, HELP_GUARD)) { + if (!fval(u2, UFL_ISNEW) && u2->number + && is_guard(u2) && !alliedunit(u2, u->faction, HELP_GUARD)) { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "region_guarded", "guard", u2)); return; diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c index 2cf931498..fca838c2a 100644 --- a/src/modules/autoseed.c +++ b/src/modules/autoseed.c @@ -874,10 +874,10 @@ int build_island(int x, int y, int minsize, newfaction ** players, int numfactio fset(r, RF_MARK); if (r->land) { if (nsize < minsize) { - nsize += random_neighbours(r, &rlist, &random_terrain, minsize - nsize); + nsize += random_neighbours(r, &rlist, random_terrain, minsize - nsize); } else { - nsize += random_neighbours(r, &rlist, &get_ocean, minsize - nsize); + nsize += random_neighbours(r, &rlist, get_ocean, minsize - nsize); } } regionqueue_push(&island, r); From d04fe741a9584fa2cd72949cd1d9b1328d233035 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 20 Oct 2019 18:04:49 +0200 Subject: [PATCH 02/10] https://bugs.eressea.de/view.php?id=2615 in the report, calculate max size of ships correctly. --- src/kernel/ship.c | 7 ++++++- src/kernel/ship.h | 14 +++++++------- src/report.c | 4 ++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 601c36d82..80acbec12 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -373,10 +373,15 @@ const char *shipname(const ship * sh) return write_shipname(sh, ibuf, sizeof(idbuf[0])); } +int ship_maxsize(const ship *sh) +{ + return sh->number * sh->type->construction->maxsize; +} + bool ship_finished(const ship *sh) { if (sh->type->construction) { - return (sh->size >= sh->number * sh->type->construction->maxsize); + return (sh->size >= ship_maxsize(sh)); } return true; } diff --git a/src/kernel/ship.h b/src/kernel/ship.h index a9a678848..d21f9f3c3 100644 --- a/src/kernel/ship.h +++ b/src/kernel/ship.h @@ -93,20 +93,20 @@ extern "C" { const char *shipname(const struct ship *self); int ship_capacity(const struct ship *sh); int ship_cabins(const struct ship *sh); + int ship_maxsize(const struct ship *sh); bool ship_finished(const struct ship *sh); - extern void getshipweight(const struct ship *sh, int *weight, int *cabins); + void getshipweight(const struct ship *sh, int *weight, int *cabins); - extern ship *new_ship(const struct ship_type *stype, struct region *r, + ship *new_ship(const struct ship_type *stype, struct region *r, const struct locale *lang); - extern const char *write_shipname(const struct ship *sh, char *buffer, + const char *write_shipname(const struct ship *sh, char *buffer, size_t size); - extern struct ship *findship(int n); - extern struct ship *findshipr(const struct region *r, int n); + struct ship *findship(int n); - extern const struct ship_type *findshiptype(const char *s, + const struct ship_type *findshiptype(const char *s, const struct locale *lang); - extern void write_ship_reference(const struct ship *sh, + void write_ship_reference(const struct ship *sh, struct storage *store); void remove_ship(struct ship **slist, struct ship *s); diff --git a/src/report.c b/src/report.c index 407db00ff..7fdf8e690 100644 --- a/src/report.c +++ b/src/report.c @@ -1737,10 +1737,10 @@ nr_ship(struct stream *out, const region *r, const ship * sh, const faction * f, sbs_printf(&sbs, "%s, %s", shipname(sh), LOC(f->locale, sh->type->_name)); } - if (sh->size != sh->type->construction->maxsize) { + if (!ship_finished(sh)) { sbs_printf(&sbs, ", %s (%d/%d)", LOC(f->locale, "nr_undercons"), sh->size, - sh->type->construction->maxsize); + ship_maxsize(sh)); } if (sh->damage) { int percent = ship_damage_percent(sh); From 70b148296f8d9bfa60d51c9933fd9dec53d550a0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 21 Oct 2019 20:04:32 +0200 Subject: [PATCH 03/10] =?UTF-8?q?MACHE=20besch=C3=A4digte=20Konvois?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/tests/e2/ships.lua | 64 +++++++++++++++++++++++++++++++++++++- src/creport.c | 3 +- src/economy.c | 4 +-- src/kernel/build.c | 32 ++++++++++--------- src/kernel/build.h | 2 +- src/kernel/build.test.c | 24 +++++++------- src/kernel/ship.c | 5 ++- 7 files changed, 100 insertions(+), 34 deletions(-) diff --git a/scripts/tests/e2/ships.lua b/scripts/tests/e2/ships.lua index 416677d26..bab27d0a9 100644 --- a/scripts/tests/e2/ships.lua +++ b/scripts/tests/e2/ships.lua @@ -312,7 +312,6 @@ function test_give_ship_compatible_coasts() assert_equal(1, u1.ship.number) assert_equal(4, u2.ship.number) assert_equal(2, u2.ship.coast) - end function test_give_ship_only_from_captain() @@ -453,3 +452,66 @@ function test_no_speedsail_on_convoy() process_orders() assert_equal(nil, sh:get_curse('shipspeedup')) end + +function test_build_ship() + local r = region.create(1, 0, 'plain') + local f = faction.create("insect") + local u = unit.create(f, r, 25) + local sh = ship.create(r, 'longboat') + u.ship = sh + sh.size = 25 + u:set_skill('shipcraft', 1) + u:add_item("log", 50) + u:add_order("MACHE SCHIFF " .. itoa36(sh.id)) + process_orders() + assert_equal(50, sh.size) + assert_equal(25, u:get_item('log')) +end + +function test_build_convoi() + local r = region.create(1, 0, 'plain') + local f = faction.create("insect") + local u = unit.create(f, r, 50) + local sh = ship.create(r, 'longboat') + u.ship = sh + sh.number = 2 + sh.size = 25 + u:set_skill('shipcraft', 1) + u:add_item("log", 100) + u:add_order("MACHE SCHIFF " .. itoa36(sh.id)) + process_orders() + assert_equal(75, sh.size) + assert_equal(50, u:get_item('log')) +end + +function test_repair_convoi() + local r = region.create(1, 0, 'plain') + local f = faction.create("insect") + local u = unit.create(f, r, 50) + local sh = ship.create(r, 'longboat') + u.ship = sh + sh.number = 2 + sh.damage = 7500 -- 75 Holz + u:set_skill('shipcraft', 1) + u:add_item("log", 100) + u:add_order("MACHE SCHIFF " .. itoa36(sh.id)) + process_orders() + assert_equal(2500, sh.damage) + assert_equal(50, u:get_item('log')) +end + +function test_build_convoi_max() + local r = region.create(1, 0, 'plain') + local f = faction.create("insect") + local u = unit.create(f, r, 100) + local sh = ship.create(r, 'longboat') + u.ship = sh + sh.number = 2 + sh.size = 25 + u:set_skill('shipcraft', 1) + u:add_item("log", 100) + u:add_order("MACHE SCHIFF " .. itoa36(sh.id)) + process_orders() + assert_equal(100, sh.size) + assert_equal(25, u:get_item('log')) +end diff --git a/src/creport.c b/src/creport.c index 46b998066..f9bffd177 100644 --- a/src/creport.c +++ b/src/creport.c @@ -700,8 +700,7 @@ static void cr_output_ship(struct stream *out, const ship *sh, const unit *u, stream_printf(out, "%d;Anzahl\n", sh->number); stream_printf(out, "%d;Groesse\n", sh->size); if (sh->damage) { - int percent = - (sh->damage * 100 + DAMAGE_SCALE - 1) / (sh->size * DAMAGE_SCALE); + int percent = ship_damage_percent(sh); stream_printf(out, "%d;Schaden\n", percent); } if (u) { diff --git a/src/economy.c b/src/economy.c index 377a71a6c..7cd28f6b9 100644 --- a/src/economy.c +++ b/src/economy.c @@ -509,7 +509,7 @@ static void manufacture(unit * u, const item_type * itype, int want) if (want == 0) { want = maxbuild(u, itype->construction); } - n = build(u, itype->construction, 0, want, skill_mod); + n = build(u, 1, itype->construction, 0, want, skill_mod); switch (n) { case ENEEDSKILL: ADDMSG(&u->faction->msgs, @@ -850,7 +850,7 @@ static void create_potion(unit * u, const item_type * itype, int want) if (want == 0) { want = maxbuild(u, itype->construction); } - built = build(u, itype->construction, 0, want, 0); + built = build(u, 1, itype->construction, 0, want, 0); switch (built) { case ELOWSKILL: case ENEEDSKILL: diff --git a/src/kernel/build.c b/src/kernel/build.c index 447db8662..29dfc81f0 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -224,7 +224,7 @@ int destroy_cmd(unit * u, struct order *ord) return 14; } - if (n >= (sh->size * 100) / sh->type->construction->maxsize) { + if (n >= (sh->size * 100) / ship_maxsize(sh)) { /* destroy completly */ /* all units leave the ship */ for (u2 = r->units; u2; u2 = u2->next) { @@ -509,9 +509,9 @@ int build_skill(unit *u, int basesk, int skill_mod) { * of the first object have already been finished. return the * actual size that could be built. */ -static int build_limited(unit * u, const construction * con, int completed, int want, int basesk, int *skill_total) { +static int build_limited(unit * u, const construction * con, int completed, int number, int want, int basesk, int *skill_total) { int skills = *skill_total; - int made = 0; + int made = 0, maxsize = con->maxsize * number; if (want <= 0) { return 0; @@ -519,7 +519,7 @@ static int build_limited(unit * u, const construction * con, int completed, int if (con == NULL) { return ENOMATERIALS; } - if (completed == con->maxsize) { + if (completed == maxsize) { return ECOMPLETE; } for (; want > 0 && skills > 0;) { @@ -530,8 +530,8 @@ static int build_limited(unit * u, const construction * con, int completed, int * (enno): Nein, das ist fuer Dinge, bei denen die naechste Ausbaustufe * die gleiche wie die vorherige ist. z.b. Gegenstaende. */ - if (con->maxsize > 0) { - completed = completed % con->maxsize; + if (maxsize > 0) { + completed = completed % (maxsize); } else { completed = 0; @@ -566,8 +566,8 @@ static int build_limited(unit * u, const construction * con, int completed, int if (want < n) n = want; - if (con->maxsize > 0) { - int req = con->maxsize - completed; + if (maxsize > 0) { + int req = maxsize - completed; if (req < n) n = req; want = n; } @@ -592,11 +592,12 @@ static int build_limited(unit * u, const construction * con, int completed, int return made; } -int build(unit * u, const construction * con, int completed, int want, int skill_mod) +int build(unit * u, int number, const construction * con, int completed, int want, int skill_mod) { int skills = INT_MAX; /* number of skill points remainig */ int made, basesk = 0; + assert(number >= 1); assert(con->skill != NOSKILL); basesk = effskill(u, con->skill, NULL); if (basesk == 0) { @@ -604,7 +605,7 @@ int build(unit * u, const construction * con, int completed, int want, int skill } skills = build_skill(u, basesk, skill_mod); - made = build_limited(u, con, completed, want, basesk, &skills); + made = build_limited(u, con, completed, number, want, basesk, &skills); /* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */ if (made > 0) { produceexp(u, con->skill, (made < u->number) ? made : u->number); @@ -698,7 +699,7 @@ static int build_stages(unit *u, const building_type *btype, int built, int n, i want = todo; } } - err = build_limited(u, con, built, want, basesk, skill_total); + err = build_limited(u, con, 1, built, want, basesk, skill_total); if (err < 0) { if (made == 0) { /* could not make any part at all */ @@ -904,9 +905,9 @@ static void build_ship(unit * u, ship * sh, int want) const construction *construction = sh->type->construction; int size = (sh->size * DAMAGE_SCALE - sh->damage) / DAMAGE_SCALE; int n; - int can = build(u, construction, size, want, 0); + int can = build(u, sh->number, construction, size, want, 0); - if ((n = construction->maxsize - sh->size) > 0 && can > 0) { + if ((n = ship_maxsize(sh) - sh->size) > 0 && can > 0) { if (can >= n) { sh->size += n; can -= n; @@ -1000,11 +1001,12 @@ void continue_ship(unit * u, int want) cmistake(u, u->thisorder, 20, MSG_PRODUCE); return; } - cons = sh->type->construction; - if (sh->size == cons->maxsize && !sh->damage) { + msize = ship_maxsize(sh); + if (sh->size >= msize && !sh->damage) { cmistake(u, u->thisorder, 16, MSG_PRODUCE); return; } + cons = sh->type->construction; if (effskill(u, cons->skill, NULL) < cons->minskill) { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_build_skill_low", "value", cons->minskill)); diff --git a/src/kernel/build.h b/src/kernel/build.h index d37d7fa12..523ec0e63 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -44,7 +44,7 @@ extern "C" { void sunhash(struct ship *sh); int roqf_factor(void); - int build(struct unit *u, const construction * ctype, int completed, int want, int skill_mod); + int build(struct unit *u, int number, const construction * ctype, int completed, int want, int skill_mod); int maxbuild(const struct unit *u, const construction * cons); struct message *msg_materials_required(struct unit *u, struct order *ord, const struct construction *ctype, int multi); diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c index 4eba0baaf..5534ebc32 100644 --- a/src/kernel/build.test.c +++ b/src/kernel/build.test.c @@ -145,10 +145,10 @@ static void test_build_requires_materials(CuTest *tc) { u = setup_build(&bf); set_level(u, SK_ARMORER, 2); - CuAssertIntEquals(tc, ENOMATERIALS, build(u, &bf.cons, 0, 1, 0)); + CuAssertIntEquals(tc, ENOMATERIALS, build(u, 1, &bf.cons, 0, 1, 0)); itype = bf.cons.materials[0].rtype->itype; i_change(&u->items, itype, 2); - CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1, 0)); + CuAssertIntEquals(tc, 1, build(u, 1, &bf.cons, 0, 1, 0)); CuAssertIntEquals(tc, 1, i_get(u->items, itype)); teardown_build(&bf); } @@ -161,7 +161,7 @@ static void test_build_failure_missing_skill(CuTest *tc) { u = setup_build(&bf); rtype = bf.cons.materials[0].rtype; i_change(&u->items, rtype->itype, 1); - CuAssertIntEquals(tc, ENEEDSKILL, build(u, &bf.cons, 1, 1, 0)); + CuAssertIntEquals(tc, ENEEDSKILL, build(u, 1, &bf.cons, 1, 1, 0)); teardown_build(&bf); } @@ -174,7 +174,7 @@ static void test_build_failure_low_skill(CuTest *tc) { rtype = bf.cons.materials[0].rtype; i_change(&u->items, rtype->itype, 1); set_level(u, SK_ARMORER, bf.cons.minskill - 1); - CuAssertIntEquals(tc, ELOWSKILL, build(u, &bf.cons, 0, 10, 0)); + CuAssertIntEquals(tc, ELOWSKILL, build(u, 1, &bf.cons, 0, 10, 0)); teardown_build(&bf); } @@ -188,7 +188,7 @@ static void test_build_failure_completed(CuTest *tc) { i_change(&u->items, rtype->itype, 1); set_level(u, SK_ARMORER, bf.cons.minskill); bf.cons.maxsize = 1; - CuAssertIntEquals(tc, ECOMPLETE, build(u, &bf.cons, bf.cons.maxsize, 10, 0)); + CuAssertIntEquals(tc, ECOMPLETE, build(u, 1, &bf.cons, bf.cons.maxsize, 10, 0)); CuAssertIntEquals(tc, 1, i_get(u->items, rtype->itype)); teardown_build(&bf); } @@ -203,19 +203,19 @@ static void test_build_limits(CuTest *tc) { assert(rtype); i_change(&u->items, rtype->itype, 1); set_level(u, SK_ARMORER, bf.cons.minskill); - CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 10, 0)); + CuAssertIntEquals(tc, 1, build(u, 1, &bf.cons, 0, 10, 0)); CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype)); scale_number(u, 2); set_level(u, SK_ARMORER, bf.cons.minskill); i_change(&u->items, rtype->itype, 2); - CuAssertIntEquals(tc, 2, build(u, &bf.cons, 0, 10, 0)); + CuAssertIntEquals(tc, 2, build(u, 1, &bf.cons, 0, 10, 0)); CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype)); scale_number(u, 2); set_level(u, SK_ARMORER, bf.cons.minskill * 2); i_change(&u->items, rtype->itype, 4); - CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 10, 0)); + CuAssertIntEquals(tc, 4, build(u, 1, &bf.cons, 0, 10, 0)); CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype)); teardown_build(&bf); } @@ -234,7 +234,7 @@ static void test_build_with_ring(CuTest *tc) { set_level(u, SK_ARMORER, bf.cons.minskill); i_change(&u->items, rtype->itype, 20); i_change(&u->items, ring, 1); - CuAssertIntEquals(tc, 10, build(u, &bf.cons, 0, 20, 0)); + CuAssertIntEquals(tc, 10, build(u, 1, &bf.cons, 0, 20, 0)); CuAssertIntEquals(tc, 10, i_get(u->items, rtype->itype)); teardown_build(&bf); } @@ -253,16 +253,16 @@ static void test_build_with_potion(CuTest *tc) { i_change(&u->items, rtype->itype, 20); change_effect(u, ptype, 4); set_level(u, SK_ARMORER, bf.cons.minskill); - CuAssertIntEquals(tc, 2, build(u, &bf.cons, 0, 20, 0)); + CuAssertIntEquals(tc, 2, build(u, 1, &bf.cons, 0, 20, 0)); CuAssertIntEquals(tc, 18, i_get(u->items, rtype->itype)); CuAssertIntEquals(tc, 3, get_effect(u, ptype)); set_level(u, SK_ARMORER, bf.cons.minskill * 2); - CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 20, 0)); + CuAssertIntEquals(tc, 4, build(u, 1, &bf.cons, 0, 20, 0)); CuAssertIntEquals(tc, 2, get_effect(u, ptype)); set_level(u, SK_ARMORER, bf.cons.minskill); scale_number(u, 2); /* OBS: this scales the effects, too: */ CuAssertIntEquals(tc, 4, get_effect(u, ptype)); - CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 20, 0)); + CuAssertIntEquals(tc, 4, build(u, 1, &bf.cons, 0, 20, 0)); CuAssertIntEquals(tc, 2, get_effect(u, ptype)); teardown_build(&bf); } diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 80acbec12..56551e0f2 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -538,5 +538,8 @@ const char *ship_getname(const ship * sh) } int ship_damage_percent(const ship *sh) { - return (sh->damage * 100 + DAMAGE_SCALE - 1) / (sh->size * DAMAGE_SCALE); + /* Schaden muss granularer sein als Größe, deshalb ist er skaliert + * DAMAGE_SCALE ist der Faktor zwischen 1 Schadenspunkt und 1 Größenpunkt. + */ + return ((DAMAGE_SCALE - 1) + sh->damage * 100) / (sh->size * DAMAGE_SCALE); } From f64020157cfc15f5836f83ba247534f75d281849 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 21 Oct 2019 20:07:55 +0200 Subject: [PATCH 04/10] test name spelling fix --- scripts/tests/e2/ships.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/tests/e2/ships.lua b/scripts/tests/e2/ships.lua index bab27d0a9..5b77220ec 100644 --- a/scripts/tests/e2/ships.lua +++ b/scripts/tests/e2/ships.lua @@ -468,7 +468,7 @@ function test_build_ship() assert_equal(25, u:get_item('log')) end -function test_build_convoi() +function test_build_convoy() local r = region.create(1, 0, 'plain') local f = faction.create("insect") local u = unit.create(f, r, 50) @@ -484,7 +484,7 @@ function test_build_convoi() assert_equal(50, u:get_item('log')) end -function test_repair_convoi() +function test_repair_convoy() local r = region.create(1, 0, 'plain') local f = faction.create("insect") local u = unit.create(f, r, 50) @@ -500,7 +500,7 @@ function test_repair_convoi() assert_equal(50, u:get_item('log')) end -function test_build_convoi_max() +function test_build_convoy_max() local r = region.create(1, 0, 'plain') local f = faction.create("insect") local u = unit.create(f, r, 100) From 75a71c36aae902a8bcdfc5cb62dba5081cc482d2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 22 Oct 2019 18:46:00 +0200 Subject: [PATCH 05/10] ZERSTOERE Schiffe evtl. auch richtig? Best effort. --- src/kernel/build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/build.c b/src/kernel/build.c index 29dfc81f0..d9e1cc8bc 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -239,7 +239,7 @@ int destroy_cmd(unit * u, struct order *ord) } else { /* partial destroy */ - sh->size -= (sh->type->construction->maxsize * n) / 100; + sh->size -= (ship_maxsize(sh) * n) / 100; ADDMSG(&u->faction->msgs, msg_message("shipdestroy_partial", "unit region ship", u, r, sh)); } From 1c358b99823806923c0d3f5fdb8d5ae01d9dde9b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 22 Oct 2019 18:56:04 +0200 Subject: [PATCH 06/10] bug 2263: skeletons and undead can guard and desert. --- res/e3a/races.xml | 8 ++++---- res/eressea/races.xml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/res/e3a/races.xml b/res/e3a/races.xml index e2fea2acb..117759ca8 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -703,8 +703,8 @@ + walk="yes" learn="no" teach="no" noheal="yes" desert="yes" + undead="yes" equipment="yes" giveperson="yes" unarmedguard="yes"> @@ -801,7 +801,7 @@ - + @@ -816,7 +816,7 @@ - + diff --git a/res/eressea/races.xml b/res/eressea/races.xml index c858aceb1..82b642ba2 100644 --- a/res/eressea/races.xml +++ b/res/eressea/races.xml @@ -732,7 +732,7 @@ - + @@ -1044,7 +1044,7 @@ - + @@ -1058,7 +1058,7 @@ - + From c82b3b27dda63b54e02f2e7187f6d63402bf15c6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 22 Oct 2019 21:30:14 +0200 Subject: [PATCH 07/10] =?UTF-8?q?Bug=202616:=20FOLGE=20schiesst=20=C3=BCbe?= =?UTF-8?q?r=20das=20Ziel=20hinaus.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/move.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/move.c b/src/move.c index 484ee993f..7a636d2f0 100644 --- a/src/move.c +++ b/src/move.c @@ -2227,6 +2227,7 @@ int follow_ship(unit * u, order * ord) int moves, id, speed; char command[256]; direction_t dir; + ship *sh; if (fval(u, UFL_NOTMOVING)) { return 0; @@ -2251,10 +2252,10 @@ int follow_ship(unit * u, order * ord) return 0; } + sh = findship(id); dir = hunted_dir(rc->attribs, id); if (dir == NODIRECTION) { - ship *sh = findship(id); if (sh == NULL || sh->region != rc) { cmistake(u, ord, 20, MSG_MOVE); } @@ -2278,7 +2279,7 @@ int follow_ship(unit * u, order * ord) speed = maxspeed; } rc = rconnect(rc, dir); - while (rc && moves < speed && (dir = hunted_dir(rc->attribs, id)) != NODIRECTION) { + while (rc && rc != sh->region && moves < speed && (dir = hunted_dir(rc->attribs, id)) != NODIRECTION) { const char *loc = LOC(u->faction->locale, directions[dir]); sbs_strcat(&sbcmd, " "); sbs_strcat(&sbcmd, loc); From 533a0aceec949ea2ee2caed8370b728e34b61505 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 23 Oct 2019 23:17:31 +0200 Subject: [PATCH 08/10] fix crash when following a lost ship --- src/move.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/move.c b/src/move.c index 7a636d2f0..18cb5098d 100644 --- a/src/move.c +++ b/src/move.c @@ -2279,7 +2279,7 @@ int follow_ship(unit * u, order * ord) speed = maxspeed; } rc = rconnect(rc, dir); - while (rc && rc != sh->region && moves < speed && (dir = hunted_dir(rc->attribs, id)) != NODIRECTION) { + while (rc && (!sh || rc != sh->region) && moves < speed && (dir = hunted_dir(rc->attribs, id)) != NODIRECTION) { const char *loc = LOC(u->faction->locale, directions[dir]); sbs_strcat(&sbcmd, " "); sbs_strcat(&sbcmd, loc); From c8769a4412782d45e2de8550f598386acc313f0b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 27 Oct 2019 10:56:16 +0100 Subject: [PATCH 09/10] Fehler in ship_crewed Berechnung --- src/kernel/ship.c | 13 ++++------- src/kernel/ship.test.c | 53 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 56551e0f2..87194834b 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -407,22 +407,19 @@ int crew_skill(const ship *sh) { } bool ship_crewed(const ship *sh) { - unit *u; + unit *u, *cap = ship_owner(sh); int capskill = -1, sumskill = 0; for (u = sh->region->units; u; u = u->next) { if (u->ship == sh) { int es = effskill(u, SK_SAILING, NULL); - if (capskill < 0) { - if (u->number >= sh->number) { + if (es > 0) { + if (u == cap && u->number >= sh->number) { capskill = es; } - else { - capskill = 0; + if (es >= sh->type->minskill) { + sumskill += es * u->number; } } - if (es >= sh->type->minskill) { - sumskill += es * u->number; - } } } return (capskill >= ship_captain_minskill(sh)) && (sumskill >= sh->type->sumskill * sh->number); diff --git a/src/kernel/ship.test.c b/src/kernel/ship.test.c index 062e7cd20..ddc0d7795 100644 --- a/src/kernel/ship.test.c +++ b/src/kernel/ship.test.c @@ -30,6 +30,58 @@ static void test_register_ship(CuTest * tc) test_teardown(); } +static void test_ship_crewed(CuTest * tc) +{ + struct region *r; + struct faction *f; + struct ship *sh; + struct unit *u1, *u2; + struct ship_type *stype; + + test_setup(); + f = test_create_faction(NULL); + r = test_create_ocean(0, 0); + stype = test_create_shiptype("longboat"); + stype->cptskill = 2; + stype->sumskill = 4; + sh = test_create_ship(r, stype); + CuAssertTrue(tc, !ship_crewed(sh)); + u1 = test_create_unit(f, r); + set_level(u1, SK_SAILING, 4); + u_set_ship(u1, sh); + CuAssertTrue(tc, ship_crewed(sh)); + u2 = test_create_unit(f, r); + set_level(u1, SK_SAILING, 2); + set_level(u1, SK_SAILING, 2); + u_set_ship(u2, sh); + CuAssertTrue(tc, ship_crewed(sh)); + set_level(u1, SK_SAILING, 1); + set_level(u2, SK_SAILING, 2); + CuAssertTrue(tc, !ship_crewed(sh)); + set_level(u1, SK_SAILING, 2); + set_level(u2, SK_SAILING, 1); + CuAssertTrue(tc, !ship_crewed(sh)); + set_level(u1, SK_SAILING, 3); + set_level(u2, SK_SAILING, 1); + CuAssertTrue(tc, ship_crewed(sh)); + stype->minskill = 2; + CuAssertTrue(tc, !ship_crewed(sh)); + set_level(u1, SK_SAILING, 2); + set_level(u2, SK_SAILING, 2); + CuAssertTrue(tc, ship_crewed(sh)); + sh->number = 2; + CuAssertTrue(tc, !ship_crewed(sh)); + set_level(u1, SK_SAILING, 4); + set_level(u2, SK_SAILING, 4); + CuAssertTrue(tc, !ship_crewed(sh)); + u1->number = 2; + set_level(u1, SK_SAILING, 2); + set_level(u2, SK_SAILING, 4); + CuAssertTrue(tc, ship_crewed(sh)); + + test_teardown(); +} + static void test_ship_set_owner(CuTest * tc) { struct region *r; @@ -665,6 +717,7 @@ CuSuite *get_ship_suite(void) SUITE_ADD_TEST(suite, test_register_ship); SUITE_ADD_TEST(suite, test_stype_defaults); SUITE_ADD_TEST(suite, test_ship_set_owner); + SUITE_ADD_TEST(suite, test_ship_crewed); SUITE_ADD_TEST(suite, test_shipowner_resets_when_empty); SUITE_ADD_TEST(suite, test_shipowner_goes_to_next_when_empty); SUITE_ADD_TEST(suite, test_shipowner_goes_to_other_when_empty); From 7f57aa2a18faeaeff0a249d101977695c665e245 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 27 Oct 2019 10:57:32 +0100 Subject: [PATCH 10/10] small copy/paste error --- src/kernel/ship.test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/ship.test.c b/src/kernel/ship.test.c index ddc0d7795..174762182 100644 --- a/src/kernel/ship.test.c +++ b/src/kernel/ship.test.c @@ -52,7 +52,7 @@ static void test_ship_crewed(CuTest * tc) CuAssertTrue(tc, ship_crewed(sh)); u2 = test_create_unit(f, r); set_level(u1, SK_SAILING, 2); - set_level(u1, SK_SAILING, 2); + set_level(u2, SK_SAILING, 2); u_set_ship(u2, sh); CuAssertTrue(tc, ship_crewed(sh)); set_level(u1, SK_SAILING, 1);