From 18abbb6c498b7fe18b874526203fbbef09b96afe Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 4 Sep 2017 14:38:39 +0200 Subject: [PATCH 1/9] fix intermittent test caused by produceexp --- scripts/tests/e2/e2features.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index 7e143c0cc..20b21ce75 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -8,6 +8,7 @@ function setup() eressea.settings.set("rules.food.flags", "4") eressea.settings.set("rules.ship.storms", "0") eressea.settings.set("rules.encounters", "0") + eressea.settings.set("study.produceexp", "0") end function test_calendar() @@ -57,6 +58,7 @@ function test_dwarf_bonus() u.building = building.create(r, "mine") u.building.size = 10 u:add_item("money", 500) -- maintenance + assert_equal(1, u:get_skill("mining")) process_orders() assert_equal(70, u:get_item("iron")) assert_equal(70, r:get_resource("iron")) From d2291d03c8d96b2773a69972fc8476be3f41975f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 4 Sep 2017 14:38:39 +0200 Subject: [PATCH 2/9] fix intermittent test caused by produceexp --- scripts/tests/e2/e2features.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index 7e143c0cc..20b21ce75 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -8,6 +8,7 @@ function setup() eressea.settings.set("rules.food.flags", "4") eressea.settings.set("rules.ship.storms", "0") eressea.settings.set("rules.encounters", "0") + eressea.settings.set("study.produceexp", "0") end function test_calendar() @@ -57,6 +58,7 @@ function test_dwarf_bonus() u.building = building.create(r, "mine") u.building.size = 10 u:add_item("money", 500) -- maintenance + assert_equal(1, u:get_skill("mining")) process_orders() assert_equal(70, u:get_item("iron")) assert_equal(70, r:get_resource("iron")) From 873b1a81af6c7252f5670ea181d005aafd5e424e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 4 Sep 2017 20:08:34 +0200 Subject: [PATCH 3/9] testing that words do not get split, lines get split at spaces. --- src/reports.test.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/reports.test.c b/src/reports.test.c index 891f7d4af..58ac425f1 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -153,6 +153,23 @@ static void test_sparagraph(CuTest *tc) { freestrlist(sp); } +static void test_sparagraph_long(CuTest *tc) { + strlist *sp = 0; + + split_paragraph(&sp, "HelloWorld HelloWorld", 0, 16, 0); + CuAssertPtrNotNull(tc, sp); + CuAssertStrEquals(tc, "HelloWorld", sp->s); + CuAssertStrEquals(tc, "HelloWorld", sp->next->s); + CuAssertPtrEquals(tc, NULL, sp->next->next); + freestrlist(sp); + + split_paragraph(&sp, "HelloWorldHelloWorld", 0, 16, 0); + CuAssertPtrNotNull(tc, sp); + CuAssertStrEquals(tc, "HelloWorldHelloWorld", sp->s); + CuAssertPtrEquals(tc, NULL, sp->next); + freestrlist(sp); +} + static void test_bufunit_fstealth(CuTest *tc) { faction *f1, *f2; region *r; @@ -767,6 +784,7 @@ CuSuite *get_reports_suite(void) SUITE_ADD_TEST(suite, test_seen_faction); SUITE_ADD_TEST(suite, test_regionid); SUITE_ADD_TEST(suite, test_sparagraph); + SUITE_ADD_TEST(suite, test_sparagraph_long); SUITE_ADD_TEST(suite, test_bufunit); SUITE_ADD_TEST(suite, test_bufunit_fstealth); SUITE_ADD_TEST(suite, test_arg_resources); From 46b065dd290eec771084715976ea68348a991fe1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 4 Sep 2017 20:08:56 +0200 Subject: [PATCH 4/9] BUG 2203: Schattenrichter sind gewichtslos --- res/e3a/races.xml | 2 +- res/eressea/races.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/e3a/races.xml b/res/e3a/races.xml index 79d9ff9bd..ce0ce336a 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -830,7 +830,7 @@ - + diff --git a/res/eressea/races.xml b/res/eressea/races.xml index 04f621526..b04311cb9 100644 --- a/res/eressea/races.xml +++ b/res/eressea/races.xml @@ -1071,7 +1071,7 @@ - + From 127cc41e8e4903a8d91bc0af66d5869460a8d1b0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 5 Sep 2017 18:56:47 +0200 Subject: [PATCH 5/9] BUG 1779: Elfenwald-Effekte bei Trankzaubern. https://bugs.eressea.de/view.php?id=1779 --- scripts/eressea/spells.lua | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/scripts/eressea/spells.lua b/scripts/eressea/spells.lua index edfa83aad..5e04c4ed1 100644 --- a/scripts/eressea/spells.lua +++ b/scripts/eressea/spells.lua @@ -19,44 +19,49 @@ local function create_item(mage, level, name, number) return level end +local function create_potion(mage, level, name, force) + count = math.floor(force * 2 + 0.5) + return create_item(mage, level, name, count) +end + -- Wasser des Lebens function create_potion_p2(r, mage, level, force) - return create_item(mage, level, "p2", level) + return create_potion(mage, level, "p2", force) end -- Siebenmeilentee function create_potion_p0(r, mage, level, force) - return create_item(mage, level, "p0", level) + return create_potion(mage, level, "p0", force) end -- Wundsalbe function create_potion_ointment(r, mage, level, force) - return create_item(mage, level, "ointment", level) + return create_potion(mage, level, "ointment", force) end -- Bauernblut function create_potion_peasantblood(r, mage, level, force) - return create_item(mage, level, "peasantblood", level) + return create_potion(mage, level, "peasantblood", force) end -- Pferdeglueck function create_potion_p9(r, mage, level, force) - return create_item(mage, level, "p9", level) + return create_potion(mage, level, "p9", force) end -- Schaffenstrunk function create_potion_p3(r, mage, level, force) - return create_item(mage, level, "p3", level) + return create_potion(mage, level, "p3", force) end -- Heiltrank function create_potion_p14(r, mage, level, force) - return create_item(mage, level, "p14", level) + return create_potion(mage, level, "p14", force) end -- Elixier der Macht function create_potion_p13(r, mage, level, force) - return create_item(mage, level, "p13", level) + return create_potion(mage, level, "p13", force) end -- Erschaffe ein Flammenschwert From e7fe3f8292a41583deca5497c538d01703b2a3a4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 5 Sep 2017 19:52:48 +0200 Subject: [PATCH 6/9] push stream compatibility calls back to cr_output_region. --- src/creport.c | 120 +++++++++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 50 deletions(-) diff --git a/src/creport.c b/src/creport.c index 14f2a6c56..12cb4e5b5 100644 --- a/src/creport.c +++ b/src/creport.c @@ -101,7 +101,6 @@ struct locale *crtag_locale(void) { static const char *crtag(const char *key) { - /* TODO: those locale lookups are shit, but static kills testing */ const char *result; result = LOC(crtag_locale(), key); return result; @@ -382,8 +381,8 @@ static int cr_skill(variant var, char *buffer, const void *userdata) UNUSED_ARG(userdata); if (sk != NOSKILL) sprintf(buffer, "\"%s\"", - translate(mkname("skill", skillnames[sk]), skillname(sk, - report->locale))); + translate(mkname("skill", skillnames[sk]), skillname(sk, + report->locale))); else strcpy(buffer, "\"\""); return 0; @@ -426,7 +425,7 @@ static int cr_resources(variant var, char *buffer, const void *userdata) assert(name); wp += sprintf(wp, "\"%d %s", rlist->number, translate(name, LOC(f->locale, - name))); + name))); for (;;) { rlist = rlist->next; if (rlist == NULL) @@ -435,7 +434,7 @@ static int cr_resources(variant var, char *buffer, const void *userdata) assert(name); wp += sprintf(wp, ", %d %s", rlist->number, translate(name, - LOC(f->locale, name))); + LOC(f->locale, name))); } strcat(wp, "\""); } @@ -621,86 +620,106 @@ static void cr_output_messages(FILE * F, message_list * msgs, faction * f) } /* prints a building */ -static void -cr_output_building(FILE * F, building * b, const unit * owner, int fno, -faction * f) +static void cr_output_building(struct stream *out, building *b, + const unit *owner, int fno, faction *f) { const char *bname, *billusion; - fprintf(F, "BURG %d\n", b->no); + stream_printf(out, "BURG %d\n", b->no); report_building(b, &bname, &billusion); if (billusion) { - fprintf(F, "\"%s\";Typ\n", translate(billusion, LOC(f->locale, + stream_printf(out, "\"%s\";Typ\n", translate(billusion, LOC(f->locale, billusion))); if (owner && owner->faction == f) { - fprintf(F, "\"%s\";wahrerTyp\n", translate(bname, LOC(f->locale, + stream_printf(out, "\"%s\";wahrerTyp\n", translate(bname, LOC(f->locale, bname))); } } else { - fprintf(F, "\"%s\";Typ\n", translate(bname, LOC(f->locale, bname))); + stream_printf(out, "\"%s\";Typ\n", translate(bname, LOC(f->locale, bname))); + } + stream_printf(out, "\"%s\";Name\n", b->name); + if (b->display && b->display[0]) { + stream_printf(out, "\"%s\";Beschr\n", b->display); + } + if (b->size) { + stream_printf(out, "%d;Groesse\n", b->size); } - fprintf(F, "\"%s\";Name\n", b->name); - if (b->display && b->display[0]) - fprintf(F, "\"%s\";Beschr\n", b->display); - if (b->size) - fprintf(F, "%d;Groesse\n", b->size); if (owner) { - fprintf(F, "%d;Besitzer\n", owner->no); + stream_printf(out, "%d;Besitzer\n", owner->no); } - if (fno >= 0) - fprintf(F, "%d;Partei\n", fno); - if (b->besieged) - fprintf(F, "%d;Belagerer\n", b->besieged); - cr_output_curses_compat(F, f, b, TYP_BUILDING); + if (fno >= 0) { + stream_printf(out, "%d;Partei\n", fno); + } + if (b->besieged) { + stream_printf(out, "%d;Belagerer\n", b->besieged); + } + cr_output_curses(out, f, b, TYP_BUILDING); +} + +static void cr_output_building_compat(FILE *F, building *b, + const unit *owner, int fno, faction *f) +{ + /* TODO: eliminate this function */ + stream strm; + fstream_init(&strm, F); + cr_output_building(&strm, b, owner, fno, f); } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* prints a ship */ -static void -cr_output_ship(FILE * F, const ship * sh, const unit * u, int fcaptain, -const faction * f, const region * r) +static void cr_output_ship(struct stream *out, const ship *sh, const unit *u, + int fcaptain, const faction *f, const region *r) { int w = 0; assert(sh); - fprintf(F, "SCHIFF %d\n", sh->no); - fprintf(F, "\"%s\";Name\n", sh->name); + stream_printf(out, "SCHIFF %d\n", sh->no); + stream_printf(out, "\"%s\";Name\n", sh->name); if (sh->display && sh->display[0]) - fprintf(F, "\"%s\";Beschr\n", sh->display); - fprintf(F, "\"%s\";Typ\n", translate(sh->type->_name, + stream_printf(out, "\"%s\";Beschr\n", sh->display); + stream_printf(out, "\"%s\";Typ\n", translate(sh->type->_name, LOC(f->locale, sh->type->_name))); - fprintf(F, "%d;Groesse\n", sh->size); + stream_printf(out, "%d;Groesse\n", sh->size); if (sh->damage) { int percent = (sh->damage * 100 + DAMAGE_SCALE - 1) / (sh->size * DAMAGE_SCALE); - fprintf(F, "%d;Schaden\n", percent); + stream_printf(out, "%d;Schaden\n", percent); } if (u) { - fprintf(F, "%d;Kapitaen\n", u->no); + stream_printf(out, "%d;Kapitaen\n", u->no); + } + if (fcaptain >= 0) { + stream_printf(out, "%d;Partei\n", fcaptain); } - if (fcaptain >= 0) - fprintf(F, "%d;Partei\n", fcaptain); - /* calculate cargo */ if (u && (u->faction == f || omniscient(f))) { int n = 0, p = 0; int mweight = shipcapacity(sh); getshipweight(sh, &n, &p); - fprintf(F, "%d;capacity\n", mweight); - fprintf(F, "%d;cargo\n", n); - fprintf(F, "%d;speed\n", shipspeed(sh, u)); + stream_printf(out, "%d;capacity\n", mweight); + stream_printf(out, "%d;cargo\n", n); + stream_printf(out, "%d;speed\n", shipspeed(sh, u)); } /* shore */ w = NODIRECTION; if (!fval(r->terrain, SEA_REGION)) w = sh->coast; if (w != NODIRECTION) - fprintf(F, "%d;Kueste\n", w); + stream_printf(out, "%d;Kueste\n", w); - cr_output_curses_compat(F, f, sh, TYP_SHIP); + cr_output_curses(out, f, sh, TYP_SHIP); +} + +static void cr_output_ship_compat(FILE *F, const ship *sh, const unit *u, + int fcaptain, const faction *f, const region *r) +{ + /* TODO: eliminate this function */ + stream strm; + fstream_init(&strm, F); + cr_output_ship(&strm, sh, u, fcaptain, f, r); } static int stream_order(stream *out, const struct order *ord) { @@ -798,11 +817,12 @@ void cr_output_unit(stream *out, const region * r, const faction * f, if (fother) { stream_printf(out, "%d;Anderepartei\n", fother->no); } - } else if (!fval(u, UFL_ANON_FACTION)) { + } + else if (!fval(u, UFL_ANON_FACTION)) { /* OBS: anonymity overrides everything */ /* we have no alliance, so we get duped */ stream_printf(out, "%d;Partei\n", (fother ? fother : u->faction)->no); - if (fother==f) { + if (fother == f) { /* sieht aus wie unsere, ist es aber nicht. */ stream_printf(out, "1;Verraeter\n"); } @@ -929,7 +949,7 @@ void cr_output_unit(stream *out, const region * r, const faction * f, } stream_printf(out, "%d %d;%s\n", u->number * level_days(sv->level), esk, translate(mkname("skill", skillnames[sk]), skillname(sk, - f->locale))); + f->locale))); } } @@ -944,7 +964,7 @@ void cr_output_unit(stream *out, const region * r, const faction * f, if (sp) { const char *name = translate(mkname("spell", sp->sname), spell_name(sp, - f->locale)); + f->locale)); stream_printf(out, "KAMPFZAUBER %d\n", i); stream_printf(out, "\"%s\";name\n", name); stream_printf(out, "%d;level\n", mage->combatspells[i].level); @@ -1201,7 +1221,7 @@ void cr_output_resources(stream *out, const faction * f, const region *r, bool s if (result[n].number >= 0) { pos = cr_output_resource(pos, result[n].rtype, f->locale, result[n].number, - result[n].level); + result[n].level); } } if (pos != cbuf) { @@ -1458,7 +1478,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r) const faction *sf = visible_faction(f, u); fno = sf->no; } - cr_output_building(F, b, u, fno, f); + cr_output_building_compat(F, b, u, fno, f); } /* ships */ @@ -1470,7 +1490,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r) fno = sf->no; } - cr_output_ship(F, sh, u, fno, f, r); + cr_output_ship_compat(F, sh, u, fno, f, r); } /* visible units */ @@ -1516,7 +1536,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom) fprintf(F, "VERSION %d\n", C_REPORT_VERSION); fprintf(F, "\"UTF-8\";charset\n\"%s\";locale\n", - locale_name(f->locale)); + locale_name(f->locale)); fprintf(F, "%d;noskillpoints\n", 1); fprintf(F, "%lld;date\n", (long long)ctx->report_time); fprintf(F, "\"%s\";Spiel\n", game_name()); @@ -1683,7 +1703,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom) } } report_crtypes(F, f->locale); - if (f->locale!=crtag_locale()) { + if (f->locale != crtag_locale()) { report_translations(F); } reset_translations(); From b9b3f0322ee07dc0384f5cf0ae9352c40319370b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 8 Sep 2017 22:24:17 +0200 Subject: [PATCH 7/9] slightly faster lookup for equipment, probably. --- src/kernel/equipment.c | 108 +++++++++++++++++++++-------------------- src/kernel/equipment.h | 1 - 2 files changed, 55 insertions(+), 54 deletions(-) diff --git a/src/kernel/equipment.c b/src/kernel/equipment.c index d9a971455..c5070b3a9 100644 --- a/src/kernel/equipment.c +++ b/src/kernel/equipment.c @@ -29,6 +29,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include +#include #include #include @@ -37,41 +38,35 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -static equipment *equipment_sets; - -equipment *get_or_create_equipment(const char *eqname) -{ - equipment **eqp = &equipment_sets; - for (;;) { - struct equipment *eq = *eqp; - int i = eq ? strcmp(eq->name, eqname) : 1; - if (i > 0) { - eq = (equipment *)calloc(1, sizeof(equipment)); - eq->name = strdup(eqname); - eq->next = *eqp; - memset(eq->skills, 0, sizeof(eq->skills)); - *eqp = eq; - break; - } - else if (i == 0) { - break; - } - eqp = &eq->next; - } - return *eqp; -} +static critbit_tree cb_equipments = { 0 }; equipment *get_equipment(const char *eqname) { - equipment *eq = equipment_sets; - for (; eq; eq = eq->next) { - int i = strcmp(eq->name, eqname); - if (i == 0) - return eq; - else if (i > 0) - break; + const char *match; + equipment *eq = NULL; + + match = cb_find_str(&cb_equipments, eqname); + if (match) { + cb_get_kv(match, &eq, sizeof(eq)); } - return NULL; + return eq; +} + +equipment *get_or_create_equipment(const char *eqname) +{ + equipment *eq = get_equipment(eqname); + if (!eq) { + size_t len; + char data[64]; + + eq = (equipment *)calloc(1, sizeof(equipment)); + eq->name = strdup(eqname); + + len = cb_new_kv(eqname, strlen(eqname), &eq, sizeof(eq), data); + assert(len <= sizeof(data)); + cb_insert(&cb_equipments, data, len); + } + return eq; } void equipment_setskill(equipment * eq, skill_t sk, const char *value) @@ -236,27 +231,34 @@ void free_ls(void *arg) { free(ls); } -void equipment_done(void) { - equipment **eqp = &equipment_sets; - while (*eqp) { - int i; - equipment *eq = *eqp; - *eqp = eq->next; - free(eq->name); - if (eq->spells) { - selist_foreach(eq->spells, free_ls); - selist_free(eq->spells); - } - while (eq->items) { - itemdata *next = eq->items->next; - free(eq->items->value); - free(eq->items); - eq->items = next; - } - /* TODO: subsets, skills */ - for (i=0;i!=MAXSKILLS;++i) { - free(eq->skills[i]); - } - free(eq); +static void free_equipment(equipment *eq) { + int i; + free(eq->name); + if (eq->spells) { + selist_foreach(eq->spells, free_ls); + selist_free(eq->spells); + } + while (eq->items) { + itemdata *next = eq->items->next; + free(eq->items->value); + free(eq->items); + eq->items = next; + } + /* TODO: subsets, skills */ + for (i = 0; i != MAXSKILLS; ++i) { + free(eq->skills[i]); } } + +static int free_equipment_cb(const void * match, const void * key, size_t keylen, void *cbdata) { + equipment *eq; + cb_get_kv(match, &eq, sizeof(eq)); + free_equipment(eq); + free(eq); + return 0; +} + +void equipment_done(void) { + cb_foreach(&cb_equipments, "", 0, free_equipment_cb, 0); + cb_clear(&cb_equipments); +} diff --git a/src/kernel/equipment.h b/src/kernel/equipment.h index 53475b510..928182dfb 100644 --- a/src/kernel/equipment.h +++ b/src/kernel/equipment.h @@ -50,7 +50,6 @@ extern "C" { char *skills[MAXSKILLS]; struct selist *spells; struct subset *subsets; - struct equipment *next; void(*callback) (const struct equipment *, struct unit *); } equipment; From c5181195d772767dae5bca83a4b37b1ff8d1a810 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 9 Sep 2017 12:58:10 +0200 Subject: [PATCH 8/9] new feature: sea serpents will not go after small targets. --- src/kernel/equipment.c | 62 +++++++++++++++++++++--------------------- src/monsters.c | 8 ++++++ 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/src/kernel/equipment.c b/src/kernel/equipment.c index c5070b3a9..11fe594f5 100644 --- a/src/kernel/equipment.c +++ b/src/kernel/equipment.c @@ -38,37 +38,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -static critbit_tree cb_equipments = { 0 }; - -equipment *get_equipment(const char *eqname) -{ - const char *match; - equipment *eq = NULL; - - match = cb_find_str(&cb_equipments, eqname); - if (match) { - cb_get_kv(match, &eq, sizeof(eq)); - } - return eq; -} - -equipment *get_or_create_equipment(const char *eqname) -{ - equipment *eq = get_equipment(eqname); - if (!eq) { - size_t len; - char data[64]; - - eq = (equipment *)calloc(1, sizeof(equipment)); - eq->name = strdup(eqname); - - len = cb_new_kv(eqname, strlen(eqname), &eq, sizeof(eq), data); - assert(len <= sizeof(data)); - cb_insert(&cb_equipments, data, len); - } - return eq; -} - void equipment_setskill(equipment * eq, skill_t sk, const char *value) { if (eq != NULL) { @@ -231,6 +200,37 @@ void free_ls(void *arg) { free(ls); } +static critbit_tree cb_equipments = { 0 }; + +equipment *get_equipment(const char *eqname) +{ + const char *match; + equipment *eq = NULL; + + match = cb_find_str(&cb_equipments, eqname); + if (match) { + cb_get_kv(match, &eq, sizeof(eq)); + } + return eq; +} + +equipment *get_or_create_equipment(const char *eqname) +{ + equipment *eq = get_equipment(eqname); + if (!eq) { + size_t len; + char data[64]; + + eq = (equipment *)calloc(1, sizeof(equipment)); + eq->name = strdup(eqname); + + len = cb_new_kv(eqname, strlen(eqname), &eq, sizeof(eq), data); + assert(len <= sizeof(data)); + cb_insert(&cb_equipments, data, len); + } + return eq; +} + static void free_equipment(equipment *eq) { int i; free(eq->name); diff --git a/src/monsters.c b/src/monsters.c index 57b557999..ddc30ca4d 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -191,6 +192,7 @@ void monsters_desert(struct faction *monsters) int monster_attacks(unit * monster, bool rich_only) { + const race *rc_serpent = get_race(RC_SEASERPENT); if (monster->status < ST_AVOID) { region *r = monster->region; unit *u2; @@ -199,6 +201,12 @@ int monster_attacks(unit * monster, bool rich_only) for (u2 = r->units; u2; u2 = u2->next) { if (u2->faction != monster->faction && cansee(monster->faction, r, u2, 0) && !in_safe_building(u2, monster)) { int m = get_money(u2); + if (u_race(monster) == rc_serpent) { + /* attack bigger ships only */ + if (!u2->ship || u2->ship->type->cargo <= 50000) { + continue; + } + } if (!rich_only || m > 0) { order *ord = monster_attack(monster, u2); if (ord) { From 1319f546b888385b860ea15345eabcc82f1432e9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 9 Sep 2017 15:24:50 +0200 Subject: [PATCH 9/9] fix seaserpent tests, simplify monster tests. --- src/monsters.test.c | 69 +++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/src/monsters.test.c b/src/monsters.test.c index b09bb23de..51f122b87 100644 --- a/src/monsters.test.c +++ b/src/monsters.test.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include @@ -41,43 +43,43 @@ static order *find_order(const char *expected, const unit *unit) return NULL; } -static void create_monsters(faction **player, faction **monsters, unit **u, unit **m) { +static void create_monsters(unit **up, unit **um) { race* rc; region *r; + faction *fp, *fm; test_cleanup(); test_create_horse(); default_locale = test_create_locale(); - *player = test_create_faction(NULL); - *monsters = get_or_create_monsters(); - assert(rc_find((*monsters)->race->_name)); - rc = rc_get_or_create((*monsters)->race->_name); + fp = test_create_faction(NULL); + fm = get_or_create_monsters(); + assert(rc_find(fm->race->_name)); + rc = rc_get_or_create(fm->race->_name); fset(rc, RCF_UNARMEDGUARD|RCF_NPC|RCF_DRAGON); - fset(*monsters, FFL_NOIDLEOUT); - assert(fval(*monsters, FFL_NPC) && fval((*monsters)->race, RCF_UNARMEDGUARD) && fval((*monsters)->race, RCF_NPC) && fval(*monsters, FFL_NOIDLEOUT)); + fset(fm, FFL_NOIDLEOUT); + assert(fval(fm, FFL_NPC) && fval(fm->race, RCF_UNARMEDGUARD) && fval(fm->race, RCF_NPC) && fval(fm, FFL_NOIDLEOUT)); test_create_region(-1, 0, test_create_terrain("ocean", SEA_REGION | SWIM_INTO | FLY_INTO)); test_create_region(1, 0, 0); r = test_create_region(0, 0, 0); - *u = test_create_unit(*player, r); - unit_setid(*u, 1); - *m = test_create_unit(*monsters, r); - unit_setstatus(*m, ST_FIGHT); + *up = test_create_unit(fp, r); + unit_setid(*up, 1); + *um = test_create_unit(fm, r); + unit_setstatus(*um, ST_FIGHT); } static void test_monsters_attack(CuTest * tc) { - faction *f, *f2; unit *u, *m; - create_monsters(&f, &f2, &u, &m); + create_monsters(&u, &m); setguard(m, true); config_set("rules.monsters.attack_chance", "1"); - plan_monsters(f2); + plan_monsters(m->faction); CuAssertPtrNotNull(tc, find_order("attack 1", m)); test_cleanup(); @@ -85,11 +87,10 @@ static void test_monsters_attack(CuTest * tc) static void test_monsters_attack_ocean(CuTest * tc) { - faction *f, *f2; region *r; unit *u, *m; - create_monsters(&f, &f2, &u, &m); + create_monsters(&u, &m); r = findregion(-1, 0); /* ocean */ u = test_create_unit(u->faction, r); unit_setid(u, 2); @@ -98,7 +99,7 @@ static void test_monsters_attack_ocean(CuTest * tc) config_set("rules.monsters.attack_chance", "1"); - plan_monsters(f2); + plan_monsters(m->faction); CuAssertPtrNotNull(tc, find_order("attack 2", m)); test_cleanup(); @@ -106,10 +107,9 @@ static void test_monsters_attack_ocean(CuTest * tc) static void test_monsters_waiting(CuTest * tc) { - faction *f, *f2; unit *u, *m; - create_monsters(&f, &f2, &u, &m); + create_monsters(&u, &m); setguard(m, true); fset(m, UFL_ISNEW); monster_attacks(m, false); @@ -119,14 +119,16 @@ static void test_monsters_waiting(CuTest * tc) static void test_seaserpent_piracy(CuTest * tc) { - faction *f, *f2; region *r; unit *u, *m; race *rc; + ship_type * stype; - create_monsters(&f, &f2, &u, &m); + create_monsters(&u, &m); + stype = test_create_shiptype("yacht"); r = findregion(-1, 0); /* ocean */ u = test_create_unit(u->faction, r); + u->ship = test_create_ship(r, stype); unit_setid(u, 2); m = test_create_unit(m->faction, r); u_setrace(m, rc = test_create_race("seaserpent")); @@ -136,25 +138,28 @@ static void test_seaserpent_piracy(CuTest * tc) config_set("rules.monsters.attack_chance", "1"); - plan_monsters(f2); + stype->cargo = 50000; + plan_monsters(m->faction); CuAssertPtrNotNull(tc, find_order("piracy", m)); + CuAssertPtrEquals(tc, NULL, find_order("attack 2", m)); + stype->cargo = 50001; + plan_monsters(m->faction); CuAssertPtrNotNull(tc, find_order("attack 2", m)); test_cleanup(); } static void test_monsters_attack_not(CuTest * tc) { - faction *f, *f2; unit *u, *m; - create_monsters(&f, &f2, &u, &m); + create_monsters(&u, &m); setguard(m, true); setguard(u, true); config_set("rules.monsters.attack_chance", "0"); - plan_monsters(f2); + plan_monsters(m->faction); CuAssertPtrEquals(tc, 0, find_order("attack 1", m)); test_cleanup(); @@ -162,11 +167,10 @@ static void test_monsters_attack_not(CuTest * tc) static void test_dragon_attacks_the_rich(CuTest * tc) { - faction *f, *f2; unit *u, *m; const item_type *i_silver; - create_monsters(&f, &f2, &u, &m); + create_monsters(&u, &m); init_resources(); setguard(m, true); @@ -180,8 +184,7 @@ static void test_dragon_attacks_the_rich(CuTest * tc) config_set("rules.monsters.attack_chance", "0.00001"); - plan_monsters(f2); - + plan_monsters(m->faction); CuAssertPtrNotNull(tc, find_order("attack 1", m)); CuAssertPtrNotNull(tc, find_order("loot", m)); test_cleanup(); @@ -191,12 +194,11 @@ extern void random_growl(const unit *u, region *tr, int rand); static void test_dragon_moves(CuTest * tc) { - faction *f, *f2; region *r; unit *u, *m; struct message *msg; - create_monsters(&f, &f2, &u, &m); + create_monsters(&u, &m); rsetmoney(findregion(1, 0), 1000); r = findregion(0, 0); /* plain */ rsetpeasants(r, 0); @@ -204,8 +206,8 @@ static void test_dragon_moves(CuTest * tc) set_level(m, SK_WEAPONLESS, 10); config_set("rules.monsters.attack_chance", ".0"); - plan_monsters(f2); + plan_monsters(m->faction); CuAssertPtrNotNull(tc, find_order("move east", m)); mt_register(mt_new_va("dragon_growl", "dragon:unit", "number:int", "target:region", "growl:string", 0)); @@ -224,11 +226,10 @@ static void test_dragon_moves(CuTest * tc) static void test_monsters_learn_exp(CuTest * tc) { - faction *f, *f2; unit *u, *m; skill* sk; - create_monsters(&f, &f2, &u, &m); + create_monsters(&u, &m); config_set("study.produceexp", "30"); u_setrace(u, u_race(m));