From 00ca4126340d22407761cb407dd9da7f1a1057a3 Mon Sep 17 00:00:00 2001 From: Steffen Mecke Date: Sat, 11 Jun 2016 16:50:55 +0200 Subject: [PATCH 001/218] show item and race if possible --- src/laws.c | 10 ++++++---- src/laws.test.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/laws.c b/src/laws.c index 203970dc4..9cd0a6f27 100755 --- a/src/laws.c +++ b/src/laws.c @@ -2390,6 +2390,7 @@ static void display_race(unit * u, const race * rc) static void reshow_other(unit * u, struct order *ord, const char *s) { int err = 21; + bool found = false; if (s) { const spell *sp = 0; @@ -2426,7 +2427,7 @@ static void reshow_other(unit * u, struct order *ord, const char *s) { else { display_item(u, itype); } - return; + found = true; } if (sp) { @@ -2437,15 +2438,16 @@ static void reshow_other(unit * u, struct order *ord, const char *s) { if (a != NULL) { a_remove(&u->faction->attribs, a); } - return; + found = true; } if (rc && u_race(u) == rc) { display_race(u, rc); - return; + found = true; } } - cmistake(u, ord, err, MSG_EVENT); + if (!found) + cmistake(u, ord, err, MSG_EVENT); } static void reshow(unit * u, struct order *ord, const char *s, param_t p) diff --git a/src/laws.test.c b/src/laws.test.c index 623717619..aeee60ad7 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1329,6 +1329,48 @@ static void test_show_race(CuTest *tc) { test_cleanup(); } +static void test_show_both(CuTest *tc) { + order *ord; + race * rc; + unit *u; + struct locale *loc; + message * msg; + + test_cleanup(); + + mt_register(mt_new_va("msg_event", "string:string", 0)); + mt_register(mt_new_va("displayitem", "weight:int", "item:resource", "description:string", 0)); + rc = test_create_race("elf"); + test_create_itemtype("elvenhorse"); + + loc = get_or_create_locale("de"); + locale_setstring(loc, "elvenhorse", "Elfenpferd"); + locale_setstring(loc, "elvenhorse_p", "Elfenpferde"); + locale_setstring(loc, "iteminfo::elvenhorse", "Hiyaa!"); + locale_setstring(loc, "race::elf_p", "Elfen"); + locale_setstring(loc, "race::elf", "Elf"); + init_locale(loc); + + CuAssertPtrNotNull(tc, finditemtype("elf", loc)); + CuAssertPtrNotNull(tc, findrace("elf", loc)); + + u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); + u->faction->locale = loc; + i_change(&u->items, finditemtype("elfenpferd", loc), 1); + ord = create_order(K_RESHOW, loc, "Elf"); + reshow_cmd(u, ord); + CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "error36") == NULL); + msg = test_find_messagetype(u->faction->msgs, "msg_event"); + CuAssertPtrNotNull(tc, msg); + CuAssertTrue(tc, memcmp("Elf:", msg->parameters[0].v, 4) == 0); + msg = test_find_messagetype(u->faction->msgs, "displayitem"); + CuAssertPtrNotNull(tc, msg); + CuAssertTrue(tc, memcmp("Hiyaa!", msg->parameters[2].v, 4) == 0); + test_clear_messages(u->faction); + free_order(ord); + test_cleanup(); +} + static int low_wage(const region * r, const faction * f, const race * rc, int in_turn) { return 1; } @@ -1466,6 +1508,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_show_without_item); SUITE_ADD_TEST(suite, test_show_elf); SUITE_ADD_TEST(suite, test_show_race); + SUITE_ADD_TEST(suite, test_show_both); SUITE_ADD_TEST(suite, test_immigration); SUITE_ADD_TEST(suite, test_demon_hunger); From 9baba00087bd8bdaf2d68ecbaad2b2352d20267a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 11 Sep 2016 21:29:42 +0200 Subject: [PATCH 002/218] use mtype->key instead of repeated hashstring calls. --- src/util/crmessage.c | 4 ++-- src/util/nrmessage.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/util/crmessage.c b/src/util/crmessage.c index 98afe0f05..56f1e5dcd 100644 --- a/src/util/crmessage.c +++ b/src/util/crmessage.c @@ -81,7 +81,7 @@ static crmessage_type *crtypes[CRMAXHASH]; static crmessage_type *crt_find(const struct message_type *mtype) { - unsigned int hash = hashstring(mtype->name) % CRMAXHASH; + unsigned int hash = mtype->key % CRMAXHASH; crmessage_type *found = NULL; crmessage_type *type = crtypes[hash]; while (type) { @@ -94,7 +94,7 @@ static crmessage_type *crt_find(const struct message_type *mtype) void crt_register(const struct message_type *mtype) { - unsigned int hash = hashstring(mtype->name) % CRMAXHASH; + unsigned int hash = mtype->key % CRMAXHASH; crmessage_type *crt = crtypes[hash]; while (crt && crt->mtype != mtype) { crt = crt->next; diff --git a/src/util/nrmessage.c b/src/util/nrmessage.c index e3b0bcc0b..79638ec30 100644 --- a/src/util/nrmessage.c +++ b/src/util/nrmessage.c @@ -40,7 +40,7 @@ nrmessage_type *nrt_find(const struct locale * lang, const struct message_type * mtype) { nrmessage_type *found = NULL; - unsigned int hash = hashstring(mtype->name) % NRT_MAXHASH; + unsigned int hash = mtype->key % NRT_MAXHASH; nrmessage_type *type = nrtypes[hash]; while (type) { if (type->mtype == mtype) { @@ -101,7 +101,7 @@ void nrt_register(const struct message_type *mtype, const struct locale *lang, const char *string, int level, const char *section) { - unsigned int hash = hashstring(mtype->name) % NRT_MAXHASH; + unsigned int hash = mtype->key % NRT_MAXHASH; nrmessage_type *nrt = nrtypes[hash]; while (nrt && (nrt->lang != lang || nrt->mtype != mtype)) { nrt = nrt->next; From b0905f8e6e9512c4859327e8896754c85712168e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 23 Sep 2016 17:03:18 +0200 Subject: [PATCH 003/218] incomplete new get_regions_distance implementation --- src/reports.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/reports.c b/src/reports.c index ff076a866..e0c2642ba 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1112,6 +1112,29 @@ void reports_done(void) { } } +static int get_regions_distance_arr(region *r, int radius, + region *result[], int size) +{ + int n = 0, i; + + if (size>n) { + result[n++] = r; + } + for (i = 0; i != n; ++i) { + region *adj[MAXDIRECTIONS]; + int d; + + r = result[i]; + get_neighbours(r, adj); + for (d = 0; d != MAXDIRECTIONS; ++d) { + r = adj[d]; + if (size>n) { + result[n++] = r; + } + } + } +} + static quicklist *get_regions_distance(region * root, int radius) { quicklist *ql, *rlist = NULL; From c755c1d69e52c147138c3e4e84b93c577474e502 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 23 Sep 2016 19:51:33 +0200 Subject: [PATCH 004/218] for short lighthouse ranges, don't use lists. --- src/reports.c | 67 ++++++++++++++++++++++++++++++++++------------ src/reports.h | 3 ++- src/reports.test.c | 38 ++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 18 deletions(-) diff --git a/src/reports.c b/src/reports.c index e0c2642ba..3e67f2f2b 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1112,30 +1112,43 @@ void reports_done(void) { } } -static int get_regions_distance_arr(region *r, int radius, - region *result[], int size) +int get_regions_distance_arr(region *rc, int radius, region *result[], int size) { int n = 0, i; if (size>n) { - result[n++] = r; + result[n++] = rc; } for (i = 0; i != n; ++i) { - region *adj[MAXDIRECTIONS]; - int d; - + region *r; + int dist; + r = result[i]; - get_neighbours(r, adj); - for (d = 0; d != MAXDIRECTIONS; ++d) { - r = adj[d]; - if (size>n) { - result[n++] = r; + dist = distance(rc, r); + if (dist n) { + if (dist < distance(rc, r)) { + result[n++] = r; + } + } + else { + return -1; + } + } } } } + return n; } -static quicklist *get_regions_distance(region * root, int radius) +quicklist *get_regions_distance(region * root, int radius) { quicklist *ql, *rlist = NULL; int qi = 0; @@ -1193,11 +1206,8 @@ static void add_seen_nb(faction *f, region *r, seen_mode mode) { /** mark all regions seen by the lighthouse. */ -static void prepare_lighthouse(building * b, report_context *ctx) -{ - faction *f = ctx->f; - int range = lighthouse_range(b, f); - quicklist *ql, *rlist = get_regions_distance(b->region, range); +static void prepare_lighthouse_ql(faction *f, quicklist *rlist) { + quicklist *ql; int qi; for (ql = rlist, qi = 0; ql; ql_advance(&ql, &qi, 1)) { @@ -1209,6 +1219,29 @@ static void prepare_lighthouse(building * b, report_context *ctx) ql_free(rlist); } +static void prepare_lighthouse(building * b, report_context *ctx) +{ + faction *f = ctx->f; + int range = lighthouse_range(b, f); + + if (range > 2) { + prepare_lighthouse_ql(f, get_regions_distance(b->region, range)); + } + else { + region *result[64]; + int n, i; + + n = get_regions_distance_arr(b->region, range, result, 64); + 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); + } + } + } +} + void reorder_units(region * r) { unit **unext = &r->units; diff --git a/src/reports.h b/src/reports.h index 8684dfa3f..e2484de74 100644 --- a/src/reports.h +++ b/src/reports.h @@ -49,7 +49,8 @@ extern "C" { struct unit *can_find(struct faction *, struct faction *); bool omniscient(const struct faction *f); - + struct quicklist *get_regions_distance(struct region * root, int radius); + int get_regions_distance_arr(struct region *r, int radius, struct region *result[], int size); /* funktionen zum schreiben eines reports */ void sparagraph(struct strlist **SP, const char *s, unsigned int indent, char mark); void lparagraph(struct strlist **SP, char *s, unsigned int indent, char mark); diff --git a/src/reports.test.c b/src/reports.test.c index d9b427ff2..ffa2d215c 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -425,9 +425,47 @@ static void test_seen_travelthru(CuTest *tc) { test_cleanup(); } +static void test_region_distance(CuTest *tc) { + region *r; + region *result[8]; + test_setup(); + r = test_create_region(0, 0, 0); + CuAssertIntEquals(tc, 1, get_regions_distance_arr(r, 0, result, 8)); + CuAssertPtrEquals(tc, r, result[0]); + CuAssertIntEquals(tc, 1, get_regions_distance_arr(r, 1, result, 8)); + test_create_region(1, 0, 0); + test_create_region(0, 1, 0); + CuAssertIntEquals(tc, 1, get_regions_distance_arr(r, 0, result, 8)); + CuAssertIntEquals(tc, 3, get_regions_distance_arr(r, 1, result, 8)); + CuAssertIntEquals(tc, 3, get_regions_distance_arr(r, 2, result, 8)); + test_cleanup(); +} + +static void test_region_distance_ql(CuTest *tc) { + region *r; + quicklist *ql; + test_setup(); + r = test_create_region(0, 0, 0); + ql = get_regions_distance(r, 0); + CuAssertIntEquals(tc, 1, ql_length(ql)); + CuAssertPtrEquals(tc, r, ql_get(ql, 0)); + ql_free(ql); + test_create_region(1, 0, 0); + test_create_region(0, 1, 0); + ql = get_regions_distance(r, 1); + CuAssertIntEquals(tc, 3, ql_length(ql)); + ql_free(ql); + ql = get_regions_distance(r, 2); + CuAssertIntEquals(tc, 3, ql_length(ql)); + ql_free(ql); + test_cleanup(); +} + CuSuite *get_reports_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_region_distance); + SUITE_ADD_TEST(suite, test_region_distance_ql); SUITE_ADD_TEST(suite, test_prepare_report); SUITE_ADD_TEST(suite, test_seen_neighbours); SUITE_ADD_TEST(suite, test_seen_travelthru); From 9eb376e0e5b4fe640a0490919c4b5e80d1196d99 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Sep 2016 11:20:33 +0200 Subject: [PATCH 005/218] clumsy repair of duplicate regions for range >= 2 (RF_MARK) --- src/reports.c | 7 ++++++- src/reports.test.c | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/reports.c b/src/reports.c index 3e67f2f2b..be8693e95 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1118,6 +1118,7 @@ int get_regions_distance_arr(region *rc, int radius, region *result[], int size) if (size>n) { result[n++] = rc; + fset(rc, RF_MARK); } for (i = 0; i != n; ++i) { region *r; @@ -1134,8 +1135,9 @@ int get_regions_distance_arr(region *rc, int radius, region *result[], int size) r = adj[d]; if (r) { if (size > n) { - if (dist < distance(rc, r)) { + if (!fval(r, RF_MARK) && dist < distance(rc, r)) { result[n++] = r; + fset(r, RF_MARK); } } else { @@ -1145,6 +1147,9 @@ int get_regions_distance_arr(region *rc, int radius, region *result[], int size) } } } + for (i = 0; i != n; ++i) { + freset(result[i], RF_MARK); + } return n; } diff --git a/src/reports.test.c b/src/reports.test.c index ffa2d215c..bef1047d8 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -425,6 +425,26 @@ static void test_seen_travelthru(CuTest *tc) { test_cleanup(); } +static void test_region_distance_max(CuTest *tc) { + region *r; + region *result[64]; + int x, y; + test_setup(); + r = test_create_region(0, 0, 0); + for (x=-3;x<=3;++x) { + for (y = -3; y <= 3; ++y) { + if (x != 0 || y != 0) { + test_create_region(x, y, 0); + } + } + } + CuAssertIntEquals(tc, 1, get_regions_distance_arr(r, 0, result, 64)); + CuAssertIntEquals(tc, 7, get_regions_distance_arr(r, 1, result, 64)); + CuAssertIntEquals(tc, 19, get_regions_distance_arr(r, 2, result, 64)); + CuAssertIntEquals(tc, 37, get_regions_distance_arr(r, 3, result, 64)); + test_cleanup(); +} + static void test_region_distance(CuTest *tc) { region *r; region *result[8]; @@ -465,6 +485,7 @@ CuSuite *get_reports_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_region_distance); + SUITE_ADD_TEST(suite, test_region_distance_max); SUITE_ADD_TEST(suite, test_region_distance_ql); SUITE_ADD_TEST(suite, test_prepare_report); SUITE_ADD_TEST(suite, test_seen_neighbours); From d758f065d533d2cdd8fd1a4bc158841cccfbb85d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Sep 2016 11:33:00 +0200 Subject: [PATCH 006/218] only use lists for lighthouses with range > 3. --- src/reports.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reports.c b/src/reports.c index be8693e95..504ab299d 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1229,7 +1229,7 @@ static void prepare_lighthouse(building * b, report_context *ctx) faction *f = ctx->f; int range = lighthouse_range(b, f); - if (range > 2) { + if (range > 3) { prepare_lighthouse_ql(f, get_regions_distance(b->region, range)); } else { From 0738090f281811d72d4a55aafebeae34545b0274 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 13:19:47 +0100 Subject: [PATCH 007/218] no more funpointers in resource_limit. change how resource limits in lua are called. --- src/economy.c | 34 +++++++++++++--------------------- src/helpers.c | 11 +++++------ src/kernel/resources.c | 21 +++++++++++++++++++++ src/kernel/resources.h | 13 ++++++------- src/kernel/xmlreader.c | 35 ----------------------------------- 5 files changed, 45 insertions(+), 69 deletions(-) diff --git a/src/economy.c b/src/economy.c index f9ded29de..b1b9afb32 100644 --- a/src/economy.c +++ b/src/economy.c @@ -914,10 +914,6 @@ struct message * get_modifiers(unit *u, const resource_mod *mod, variant *savep, return NULL; } -static resource_limit *get_resourcelimit(const resource_type *rtype) { - return rtype->limit; -} - static void allocate_resource(unit * u, const resource_type * rtype, int want) { const item_type *itype = resource2item(rtype); @@ -925,7 +921,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) int dm = 0; allocation_list *alist; allocation *al; - resource_limit *rdata = get_resourcelimit(rtype); + resource_limit *rdata = rtype->limit; const resource_type *rring; int amount, skill, skill_mod = 0; variant save_mod; @@ -936,8 +932,8 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) || itype->construction->materials == NULL)); assert(rdata != NULL); - if (rdata->limit != NULL) { - int avail = rdata->limit(r, rtype); + if (!rtype->raw) { + int avail = limit_resource(r, rtype); if (avail <= 0) { cmistake(u, u->thisorder, 121, MSG_PRODUCE); return; @@ -1122,17 +1118,17 @@ attrib_allocation(const resource_type * rtype, region * r, allocation * alist) { allocation *al; int nreq = 0; - resource_limit *rdata = get_resourcelimit(rtype); int avail = 0; for (al = alist; al; al = al->next) { nreq += required(al->want, al->save); } - if (rdata->limit) { - avail = rdata->limit(r, rtype); - if (avail < 0) + if (!rtype->raw) { + avail = limit_resource(r, rtype); + if (avail < 0) { avail = 0; + } } avail = MIN(avail, nreq); @@ -1147,10 +1143,11 @@ attrib_allocation(const resource_type * rtype, region * r, allocation * alist) nreq -= want; al->get = x * al->save.sa[0] / al->save.sa[1]; al->get = MIN(al->want, al->get); - if (rdata->produce) { + if (!rtype->raw) { int use = required(al->get, al->save); - if (use) - rdata->produce(r, rtype, use); + if (use) { + produce_resource(r, rtype, use); + } } } } @@ -1162,15 +1159,10 @@ typedef void(*allocate_function) (const resource_type *, struct region *, static allocate_function get_allocator(const struct resource_type *rtype) { - resource_limit *rdata = get_resourcelimit(rtype); - - if (rdata) { - if (rdata->limit != NULL) { - return attrib_allocation; - } + if (rtype->raw) { return leveled_allocation; } - return NULL; + return attrib_allocation; } void split_allocations(region * r) diff --git a/src/helpers.c b/src/helpers.c index e9502e075..ad222a0c6 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -27,6 +27,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include #include #include @@ -78,7 +79,7 @@ lua_giveitem(unit * s, unit * d, const item_type * itype, int n, struct order *o return result; } -static int limit_resource(const region * r, const resource_type * rtype) +static int limit_resource_lua(const region * r, const resource_type * rtype) { char fname[64]; int result = -1; @@ -110,7 +111,7 @@ static int limit_resource(const region * r, const resource_type * rtype) } static void -produce_resource(region * r, const resource_type * rtype, int norders) +produce_resource_lua(region * r, const resource_type * rtype, int norders) { lua_State *L = (lua_State *)global.vm_state; char fname[64]; @@ -564,9 +565,7 @@ void register_tolua_helpers(void) register_function((pf_generic)lua_maintenance, TOLUA_CAST "lua_maintenance"); - register_function((pf_generic)produce_resource, - TOLUA_CAST "lua_produceresource"); - register_function((pf_generic)limit_resource, - TOLUA_CAST "lua_limitresource"); + res_produce_fun = produce_resource_lua; + res_limit_fun = limit_resource_lua; register_item_give(lua_giveitem, TOLUA_CAST "lua_giveitem"); } diff --git a/src/kernel/resources.c b/src/kernel/resources.c index ae93d542a..f99783763 100644 --- a/src/kernel/resources.c +++ b/src/kernel/resources.c @@ -69,6 +69,7 @@ const resource_type * rtype) rm->divisor = divisor; rm->flags = 0; rm->type = rmt_get(rtype); + assert(rm->type); update_resource(rm, 1.0); rm->type->terraform(rm, r); } @@ -211,3 +212,23 @@ struct rawmaterial_type *rmt_create(struct resource_type *rtype) rmtype->visible = visible_default; return rmtype; } + +int(*res_limit_fun)(const struct region *, const struct resource_type *); +void(*res_produce_fun)(struct region *, const struct resource_type *, int); + +int limit_resource(const struct region *r, const resource_type *rtype) +{ + assert(!rtype->raw); + if (res_limit_fun) { + return res_limit_fun(r, rtype); + } + return -1; +} + +void produce_resource(struct region *r, const struct resource_type *rtype, int amount) +{ + assert(!rtype->raw); + if (res_produce_fun) { + res_produce_fun(r, rtype, amount); + } +} diff --git a/src/kernel/resources.h b/src/kernel/resources.h index d7c0e5bfd..6ee021fc1 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -43,11 +43,6 @@ extern "C" { struct rawmaterial *next; } rawmaterial; - typedef int(*rlimit_limit) (const struct region * r, - const struct resource_type * rtype); - typedef void(*rlimit_produce) (struct region * r, - const struct resource_type * rtype, int n); - typedef struct resource_mod { variant value; const struct building_type *btype; @@ -56,8 +51,6 @@ extern "C" { } resource_mod; typedef struct resource_limit { - rlimit_limit limit; - rlimit_produce produce; resource_mod *modifiers; } resource_limit; @@ -83,6 +76,12 @@ extern "C" { const struct resource_type *rtype); struct rawmaterial_type *rmt_create(struct resource_type *rtype); + extern int(*res_limit_fun)(const struct region *, const struct resource_type *); + extern void(*res_produce_fun)(struct region *, const struct resource_type *, int); + + int limit_resource(const struct region *r, const struct resource_type *rtype); + void produce_resource(struct region *r, const struct resource_type *rtype, int amount); + #ifdef __cplusplus } #endif diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 737a12f66..ae8a76163 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -933,8 +933,6 @@ static int parse_resources(xmlDocPtr doc) if (xml_bvalue(node, "pooled", true)) flags |= RTF_POOLED; - if (xml_bvalue(node, "limited", false)) - flags |= RTF_LIMITED; name = xmlGetProp(node, BAD_CAST "name"); if (!name) { @@ -1044,39 +1042,6 @@ static int parse_resources(xmlDocPtr doc) xmlFree(propValue); } } - xmlXPathFreeObject(result); - - /* reading eressea/resources/resource/resourcelimit/function */ - result = xmlXPathEvalExpression(BAD_CAST "function", xpath); - if (result->nodesetval != NULL) { - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - pf_generic fun; - - propValue = xmlGetProp(node, BAD_CAST "value"); - assert(propValue != NULL); - fun = get_function((const char *)propValue); - if (fun == NULL) { - log_error("unknown limit '%s' for resource %s\n", (const char *)propValue, rtype->_name); - xmlFree(propValue); - continue; - } - xmlFree(propValue); - - propValue = xmlGetProp(node, BAD_CAST "name"); - assert(propValue != NULL); - if (strcmp((const char *)propValue, "produce") == 0) { - rdata->produce = (rlimit_produce)fun; - } - else if (strcmp((const char *)propValue, "limit") == 0) { - rdata->limit = (rlimit_limit)fun; - } - else { - log_error("unknown limit '%s' for resource %s\n", (const char *)propValue, rtype->_name); - } - xmlFree(propValue); - } - } } xmlXPathFreeObject(result); /* reading eressea/resources/resource/resourcelimit/function */ From c3b0b9e8b339fee47f065e67762aef0d5d0a4af9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 13:47:22 +0100 Subject: [PATCH 008/218] fix missing limit-flags. --- res/core/resources/horse.xml | 4 ---- res/core/resources/log.xml | 4 +--- res/core/resources/mallorn.xml | 4 +--- res/core/resources/mallornseed.xml | 4 ---- res/core/resources/seed.xml | 4 ---- src/economy.c | 3 +-- src/kernel/xmlreader.c | 4 +++- 7 files changed, 6 insertions(+), 21 deletions(-) diff --git a/res/core/resources/horse.xml b/res/core/resources/horse.xml index d7f794491..243b547db 100644 --- a/res/core/resources/horse.xml +++ b/res/core/resources/horse.xml @@ -4,8 +4,4 @@ - - - - diff --git a/res/core/resources/log.xml b/res/core/resources/log.xml index 48662878f..3a1e8db50 100644 --- a/res/core/resources/log.xml +++ b/res/core/resources/log.xml @@ -1,12 +1,10 @@ - + - - diff --git a/res/core/resources/mallorn.xml b/res/core/resources/mallorn.xml index 96892b802..39a0230d1 100644 --- a/res/core/resources/mallorn.xml +++ b/res/core/resources/mallorn.xml @@ -1,12 +1,10 @@ - + - - diff --git a/res/core/resources/mallornseed.xml b/res/core/resources/mallornseed.xml index 01b8a3416..7a5a0310f 100644 --- a/res/core/resources/mallornseed.xml +++ b/res/core/resources/mallornseed.xml @@ -3,8 +3,4 @@ - - - - diff --git a/res/core/resources/seed.xml b/res/core/resources/seed.xml index 2bda26eeb..99f5f5804 100644 --- a/res/core/resources/seed.xml +++ b/res/core/resources/seed.xml @@ -3,8 +3,4 @@ - - - - diff --git a/src/economy.c b/src/economy.c index b1b9afb32..f7f23eb16 100644 --- a/src/economy.c +++ b/src/economy.c @@ -930,7 +930,6 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) * Materialverbrauch hat: */ assert(itype != NULL && (itype->construction == NULL || itype->construction->materials == NULL)); - assert(rdata != NULL); if (!rtype->raw) { int avail = limit_resource(r, rtype); @@ -945,7 +944,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) return; } - if (rdata->modifiers) { + if (rdata && rdata->modifiers) { message *msg = get_modifiers(u, rdata->modifiers, &save_mod, &skill_mod); if (msg) { ADDMSG(&u->faction->msgs, msg); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index ae8a76163..d4c31001e 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -980,6 +980,9 @@ static int parse_resources(xmlDocPtr doc) rmt_create(rtype); } + if (xml_bvalue(node, "limited", false)) { + rtype->flags |= RTF_LIMITED; + } /* reading eressea/resources/resource/resourcelimit */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "resourcelimit", xpath); @@ -988,7 +991,6 @@ static int parse_resources(xmlDocPtr doc) resource_limit *rdata = rtype->limit = calloc(1, sizeof(resource_limit)); xmlNodePtr limit = result->nodesetval->nodeTab[0]; - rtype->flags |= RTF_LIMITED; xpath->node = limit; xmlXPathFreeObject(result); From d4b973fea4eb2791693f052cf1aca07a4511b23a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 13:55:19 +0100 Subject: [PATCH 009/218] remove resource_limit struct indirection. --- src/economy.c | 5 ++--- src/economy.test.c | 18 ++++++++---------- src/kernel/item.c | 9 +++------ src/kernel/item.h | 4 ++-- src/kernel/resources.h | 4 ---- src/kernel/xmlreader.c | 19 +++++++++---------- 6 files changed, 24 insertions(+), 35 deletions(-) diff --git a/src/economy.c b/src/economy.c index f7f23eb16..ab6862aa4 100644 --- a/src/economy.c +++ b/src/economy.c @@ -921,7 +921,6 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) int dm = 0; allocation_list *alist; allocation *al; - resource_limit *rdata = rtype->limit; const resource_type *rring; int amount, skill, skill_mod = 0; variant save_mod; @@ -944,8 +943,8 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) return; } - if (rdata && rdata->modifiers) { - message *msg = get_modifiers(u, rdata->modifiers, &save_mod, &skill_mod); + if (rtype->modifiers) { + message *msg = get_modifiers(u, rtype->modifiers, &save_mod, &skill_mod); if (msg) { ADDMSG(&u->faction->msgs, msg); return; diff --git a/src/economy.test.c b/src/economy.test.c index 6d9c84542..8b1b0b0fa 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -348,7 +348,6 @@ static void test_make_item(CuTest *tc) { struct item_type *itype; const struct resource_type *rt_silver; resource_type *rtype; - resource_limit *rdata; double d = 0.6; test_setup(); @@ -382,7 +381,6 @@ static void test_make_item(CuTest *tc) { itype->construction->materials = 0; rtype->flags |= RTF_LIMITED; rmt_create(rtype); - rdata = rtype->limit = calloc(1, sizeof(resource_limit)); add_resource(u->region, 1, 300, 150, rtype); u->region->resources->amount = 300; /* there are 300 stones at level 1 */ set_level(u, SK_ALCHEMY, 10); @@ -392,11 +390,11 @@ static void test_make_item(CuTest *tc) { CuAssertIntEquals(tc, 11, get_item(u, itype)); CuAssertIntEquals(tc, 290, u->region->resources->amount); /* used 10 stones to make 10 stones */ - rdata->modifiers = calloc(2, sizeof(resource_mod)); - rdata->modifiers[0].flags = RMF_SAVEMATERIAL; - rdata->modifiers[0].race = u->_race; - rdata->modifiers[0].value.sa[0] = (short)(0.5+100*d); - rdata->modifiers[0].value.sa[1] = 100; + rtype->modifiers = calloc(2, sizeof(resource_mod)); + rtype->modifiers[0].flags = RMF_SAVEMATERIAL; + rtype->modifiers[0].race = u->_race; + rtype->modifiers[0].value.sa[0] = (short)(0.5+100*d); + rtype->modifiers[0].value.sa[1] = 100; make_item(u, itype, 10); split_allocations(u->region); CuAssertIntEquals(tc, 21, get_item(u, itype)); @@ -407,9 +405,9 @@ static void test_make_item(CuTest *tc) { CuAssertIntEquals(tc, 22, get_item(u, itype)); CuAssertIntEquals(tc, 283, u->region->resources->amount); /* no free lunches */ - rdata->modifiers[0].flags = RMF_REQUIREDBUILDING; - rdata->modifiers[0].race = NULL; - rdata->modifiers[0].btype = bt_get_or_create("mine"); + rtype->modifiers[0].flags = RMF_REQUIREDBUILDING; + rtype->modifiers[0].race = NULL; + rtype->modifiers[0].btype = bt_get_or_create("mine"); make_item(u, itype, 10); CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error104")); diff --git a/src/kernel/item.c b/src/kernel/item.c index 6e64c147f..38d2e8711 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -1236,15 +1236,12 @@ void free_rtype(resource_type *rtype) { if (rtype->wtype) { free_wtype(rtype->wtype); } - if (rtype->atype) { - free(rtype->atype); - } if (rtype->itype) { free_itype(rtype->itype); } - if (rtype->raw) { - free(rtype->raw); - } + free(rtype->atype); + free(rtype->modifiers); + free(rtype->raw); free(rtype->_name); free(rtype); } diff --git a/src/kernel/item.h b/src/kernel/item.h index c1ac38517..4351d611d 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -39,7 +39,7 @@ extern "C" { struct storage; struct gamedata; struct rawmaterial_type; - struct resource_limit; + struct resource_mod; typedef struct item { struct item *next; @@ -80,7 +80,7 @@ extern "C" { rtype_uget uget; rtype_name name; struct rawmaterial_type *raw; - struct resource_limit *limit; + struct resource_mod *modifiers; /* --- pointers --- */ struct attrib *attribs; struct item_type *itype; diff --git a/src/kernel/resources.h b/src/kernel/resources.h index 6ee021fc1..b448425f4 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -50,10 +50,6 @@ extern "C" { unsigned int flags; } resource_mod; - typedef struct resource_limit { - resource_mod *modifiers; - } resource_limit; - typedef struct rawmaterial_type { const struct resource_type *rtype; diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index d4c31001e..3cf8b8601 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -988,7 +988,6 @@ static int parse_resources(xmlDocPtr doc) result = xmlXPathEvalExpression(BAD_CAST "resourcelimit", xpath); assert(result->nodesetval->nodeNr <= 1); if (result->nodesetval->nodeNr != 0) { - resource_limit *rdata = rtype->limit = calloc(1, sizeof(resource_limit)); xmlNodePtr limit = result->nodesetval->nodeTab[0]; xpath->node = limit; @@ -996,7 +995,7 @@ static int parse_resources(xmlDocPtr doc) result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); if (result->nodesetval != NULL) { - rdata->modifiers = + rtype->modifiers = calloc(result->nodesetval->nodeNr + 1, sizeof(resource_mod)); for (k = 0; k != result->nodesetval->nodeNr; ++k) { xmlNodePtr node = result->nodesetval->nodeTab[k]; @@ -1010,31 +1009,31 @@ static int parse_resources(xmlDocPtr doc) rc = rc_get_or_create((const char *)propValue); xmlFree(propValue); } - rdata->modifiers[k].race = rc; + rtype->modifiers[k].race = rc; propValue = xmlGetProp(node, BAD_CAST "building"); if (propValue != NULL) { btype = bt_get_or_create((const char *)propValue); xmlFree(propValue); } - rdata->modifiers[k].btype = btype; + rtype->modifiers[k].btype = btype; propValue = xmlGetProp(node, BAD_CAST "type"); assert(propValue != NULL); if (strcmp((const char *)propValue, "skill") == 0) { - rdata->modifiers[k].value.i = xml_ivalue(node, "value", 0); - rdata->modifiers[k].flags = RMF_SKILL; + rtype->modifiers[k].value.i = xml_ivalue(node, "value", 0); + rtype->modifiers[k].flags = RMF_SKILL; } else if (strcmp((const char *)propValue, "material") == 0) { - rdata->modifiers[k].value = xml_fraction(node, "value"); - rdata->modifiers[k].flags = RMF_SAVEMATERIAL; + rtype->modifiers[k].value = xml_fraction(node, "value"); + rtype->modifiers[k].flags = RMF_SAVEMATERIAL; } else if (strcmp((const char *)propValue, "require") == 0) { xmlChar *propBldg = xmlGetProp(node, BAD_CAST "building"); if (propBldg != NULL) { btype = bt_get_or_create((const char *)propBldg); - rdata->modifiers[k].btype = btype; - rdata->modifiers[k].flags = RMF_REQUIREDBUILDING; + rtype->modifiers[k].btype = btype; + rtype->modifiers[k].flags = RMF_REQUIREDBUILDING; xmlFree(propBldg); } } From 6e27adb892c1f7ed7f4d627797fa243bd7d79840 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 14:00:20 +0100 Subject: [PATCH 010/218] remove pointless wrapper from XML. --- res/adamantium.xml | 4 +- res/core/resources/iron.xml | 8 +-- res/core/resources/laen.xml | 8 +-- res/core/resources/log.xml | 8 +-- res/core/resources/mallorn.xml | 8 +-- res/core/resources/stone.xml | 8 +-- res/e3a/resources/iron.xml | 8 +-- res/e3a/resources/stone.xml | 8 +-- src/kernel/xmlreader.c | 101 +++++++++++++++------------------ 9 files changed, 68 insertions(+), 93 deletions(-) diff --git a/res/adamantium.xml b/res/adamantium.xml index bb94dfc12..77e138f77 100644 --- a/res/adamantium.xml +++ b/res/adamantium.xml @@ -5,9 +5,7 @@ - - - + diff --git a/res/core/resources/iron.xml b/res/core/resources/iron.xml index 469840669..70d5c1080 100644 --- a/res/core/resources/iron.xml +++ b/res/core/resources/iron.xml @@ -1,11 +1,9 @@ - - - - + + + - diff --git a/res/core/resources/laen.xml b/res/core/resources/laen.xml index 30531c0fe..4099f5ca9 100644 --- a/res/core/resources/laen.xml +++ b/res/core/resources/laen.xml @@ -1,9 +1,7 @@ - - - - + + + - diff --git a/res/core/resources/log.xml b/res/core/resources/log.xml index 3a1e8db50..e3710d496 100644 --- a/res/core/resources/log.xml +++ b/res/core/resources/log.xml @@ -1,10 +1,8 @@ - - - - + + + - diff --git a/res/core/resources/mallorn.xml b/res/core/resources/mallorn.xml index 39a0230d1..3dff091c6 100644 --- a/res/core/resources/mallorn.xml +++ b/res/core/resources/mallorn.xml @@ -1,10 +1,8 @@ - - - - + + + - diff --git a/res/core/resources/stone.xml b/res/core/resources/stone.xml index 91d3aac5d..e1c5651ed 100644 --- a/res/core/resources/stone.xml +++ b/res/core/resources/stone.xml @@ -1,11 +1,9 @@ - - - - + + + - diff --git a/res/e3a/resources/iron.xml b/res/e3a/resources/iron.xml index 7ffe36f1e..01e0d8d6d 100644 --- a/res/e3a/resources/iron.xml +++ b/res/e3a/resources/iron.xml @@ -1,10 +1,8 @@ - - - - + + + - diff --git a/res/e3a/resources/stone.xml b/res/e3a/resources/stone.xml index dfb039093..d8fd08573 100644 --- a/res/e3a/resources/stone.xml +++ b/res/e3a/resources/stone.xml @@ -1,10 +1,8 @@ - - - - + + + - diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 3cf8b8601..21c80566c 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -983,65 +983,56 @@ static int parse_resources(xmlDocPtr doc) if (xml_bvalue(node, "limited", false)) { rtype->flags |= RTF_LIMITED; } - /* reading eressea/resources/resource/resourcelimit */ + /* reading eressea/resources/resource/modifier */ xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "resourcelimit", xpath); - assert(result->nodesetval->nodeNr <= 1); - if (result->nodesetval->nodeNr != 0) { - xmlNodePtr limit = result->nodesetval->nodeTab[0]; + result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); + if (result->nodesetval != NULL && result->nodesetval->nodeNr > 0) { + rtype->modifiers = + calloc(result->nodesetval->nodeNr + 1, sizeof(resource_mod)); + for (k = 0; k != result->nodesetval->nodeNr; ++k) { + xmlNodePtr node = result->nodesetval->nodeTab[k]; + building_type *btype = NULL; + const race *rc = NULL; - xpath->node = limit; - xmlXPathFreeObject(result); - - result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); - if (result->nodesetval != NULL) { - rtype->modifiers = - calloc(result->nodesetval->nodeNr + 1, sizeof(resource_mod)); - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - building_type *btype = NULL; - const race *rc = NULL; - - propValue = xmlGetProp(node, BAD_CAST "race"); - if (propValue != NULL) { - rc = rc_find((const char *)propValue); - if (rc == NULL) - rc = rc_get_or_create((const char *)propValue); - xmlFree(propValue); - } - rtype->modifiers[k].race = rc; - - propValue = xmlGetProp(node, BAD_CAST "building"); - if (propValue != NULL) { - btype = bt_get_or_create((const char *)propValue); - xmlFree(propValue); - } - rtype->modifiers[k].btype = btype; - - propValue = xmlGetProp(node, BAD_CAST "type"); - assert(propValue != NULL); - if (strcmp((const char *)propValue, "skill") == 0) { - rtype->modifiers[k].value.i = xml_ivalue(node, "value", 0); - rtype->modifiers[k].flags = RMF_SKILL; - } - else if (strcmp((const char *)propValue, "material") == 0) { - rtype->modifiers[k].value = xml_fraction(node, "value"); - rtype->modifiers[k].flags = RMF_SAVEMATERIAL; - } - else if (strcmp((const char *)propValue, "require") == 0) { - xmlChar *propBldg = xmlGetProp(node, BAD_CAST "building"); - if (propBldg != NULL) { - btype = bt_get_or_create((const char *)propBldg); - rtype->modifiers[k].btype = btype; - rtype->modifiers[k].flags = RMF_REQUIREDBUILDING; - xmlFree(propBldg); - } - } - else { - log_error("unknown type '%s' for resourcelimit-modifier '%s'\n", (const char *)propValue, rtype->_name); - } + propValue = xmlGetProp(node, BAD_CAST "race"); + if (propValue != NULL) { + rc = rc_find((const char *)propValue); + if (rc == NULL) + rc = rc_get_or_create((const char *)propValue); xmlFree(propValue); } + rtype->modifiers[k].race = rc; + + propValue = xmlGetProp(node, BAD_CAST "building"); + if (propValue != NULL) { + btype = bt_get_or_create((const char *)propValue); + xmlFree(propValue); + } + rtype->modifiers[k].btype = btype; + + propValue = xmlGetProp(node, BAD_CAST "type"); + assert(propValue != NULL); + if (strcmp((const char *)propValue, "skill") == 0) { + rtype->modifiers[k].value.i = xml_ivalue(node, "value", 0); + rtype->modifiers[k].flags = RMF_SKILL; + } + else if (strcmp((const char *)propValue, "material") == 0) { + rtype->modifiers[k].value = xml_fraction(node, "value"); + rtype->modifiers[k].flags = RMF_SAVEMATERIAL; + } + else if (strcmp((const char *)propValue, "require") == 0) { + xmlChar *propBldg = xmlGetProp(node, BAD_CAST "building"); + if (propBldg != NULL) { + btype = bt_get_or_create((const char *)propBldg); + rtype->modifiers[k].btype = btype; + rtype->modifiers[k].flags = RMF_REQUIREDBUILDING; + xmlFree(propBldg); + } + } + else { + log_error("unknown type '%s' for resourcelimit-modifier '%s'\n", (const char *)propValue, rtype->_name); + } + xmlFree(propValue); } } xmlXPathFreeObject(result); From 67252e29247b84155e6e2ee434462a9c88113ac8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 15:03:47 +0100 Subject: [PATCH 011/218] add conversion program --- src/CMakeLists.txt | 10 ++++++++++ src/convert.c | 3 +++ 2 files changed, 13 insertions(+) create mode 100644 src/convert.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 43f109fed..7be3dd3b1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -187,6 +187,15 @@ target_link_libraries(eressea ${INIPARSER_LIBRARIES} ) +add_executable(convert convert.c) +target_link_libraries(convert + game + ${LUA_MATH_LIBRARY} + ${STORAGE_LIBRARIES} + ${CLIBS_LIBRARIES} + ${INIPARSER_LIBRARIES} +) + set(TESTS_SRC monsters.test.c names.test.c @@ -268,6 +277,7 @@ endif(CURSES_FOUND) if (LIBXML2_FOUND) include_directories (${LIBXML2_INCLUDE_DIR}) target_link_libraries(eressea ${LIBXML2_LIBRARIES}) +target_link_libraries(convert ${LIBXML2_LIBRARIES}) target_link_libraries(test_eressea ${LIBXML2_LIBRARIES}) add_definitions(-DUSE_LIBXML2) endif (LIBXML2_FOUND) diff --git a/src/convert.c b/src/convert.c new file mode 100644 index 000000000..4558ed3ab --- /dev/null +++ b/src/convert.c @@ -0,0 +1,3 @@ +int main(void) { + return -1; +} From f406c476574a86657b7f679ebba398366187d465 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 15:30:58 +0100 Subject: [PATCH 012/218] use converter frm noxml branch --- src/convert.c | 26 ++++++++++++++++++++++++-- src/kernel/CMakeLists.txt | 1 + src/kernel/rules.c | 12 ++++++++++++ src/kernel/rules.h | 5 +++++ 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/kernel/rules.c create mode 100644 src/kernel/rules.h diff --git a/src/convert.c b/src/convert.c index 4558ed3ab..3b982e64f 100644 --- a/src/convert.c +++ b/src/convert.c @@ -1,3 +1,25 @@ -int main(void) { - return -1; +#include + +#include +#include +#include + +#include + +#include + +#include + +int main(int argc, char **argv) { + const char * xmlfile, *catalog; + + register_races(); + register_xmlreader(); + + if (argc < 3) return -1; + xmlfile = argv[1]; + catalog = argv[2]; + read_xml(xmlfile, catalog); + write_rules("rules.dat"); + return 0; } diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index d3a2e8e56..b8423ae03 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -54,6 +54,7 @@ pool.c race.c region.c resources.c +rules.c save.c ship.c skills.c diff --git a/src/kernel/rules.c b/src/kernel/rules.c new file mode 100644 index 000000000..c7499fe0c --- /dev/null +++ b/src/kernel/rules.c @@ -0,0 +1,12 @@ +#include +#include "rules.h" + +int write_rules(const char *filename) { + return -1; +} + +int read_rules(const char *filename) +{ + return -1; +} + diff --git a/src/kernel/rules.h b/src/kernel/rules.h new file mode 100644 index 000000000..98f0bf240 --- /dev/null +++ b/src/kernel/rules.h @@ -0,0 +1,5 @@ +#pragma once + +int read_rules(const char *filename); +int write_rules(const char * filename); + From 71e5d101a82272d2c67d35201314cf52cf292002 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 15:33:32 +0100 Subject: [PATCH 013/218] converter compiles fine, does nothing --- src/convert.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/convert.c b/src/convert.c index 3b982e64f..a67c5a287 100644 --- a/src/convert.c +++ b/src/convert.c @@ -1,25 +1,44 @@ #include + +#ifdef USE_LIBXML2 +#include +#include +#endif #include #include -#include - #include -#include - #include +#include + +static int usage(void) { + return -1; +} + int main(int argc, char **argv) { - const char * xmlfile, *catalog; + const char *mode; register_races(); +#ifdef USE_LIBXML2 register_xmlreader(); - - if (argc < 3) return -1; - xmlfile = argv[1]; - catalog = argv[2]; - read_xml(xmlfile, catalog); - write_rules("rules.dat"); - return 0; +#endif + if (argc < 2) return usage(); + mode = argv[1]; +#ifdef USE_LIBXML2 + if (strcmp(mode, "rules")==0) { + const char *xmlfile, *catalog; + if (argc < 4) return usage(); + xmlfile = argv[2]; + catalog = argv[3]; + read_xml(xmlfile, catalog); + write_rules("rules.dat"); + return 0; + } +#endif + if (strcmp(mode, "po")==0) { + return 0; + } + return usage(); } From 56eb1b753cb33f9db228644370450dc91b905517 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 15:52:58 +0100 Subject: [PATCH 014/218] fix header missing a struct --- src/kernel/xmlreader.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/kernel/xmlreader.h b/src/kernel/xmlreader.h index 5dfb643f1..290b785c3 100644 --- a/src/kernel/xmlreader.h +++ b/src/kernel/xmlreader.h @@ -12,6 +12,9 @@ without prior permission by the authors of Eressea. #ifndef H_KRNL_XMLREADER_H #define H_KRNL_XMLREADER_H + +struct spell; + #ifdef __cplusplus extern "C" { #endif From 3c60f863a572ad5c04f2c9c0be69267a04000c78 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 18:17:58 +0100 Subject: [PATCH 015/218] remove the special_resources trie. memory leak, bad performance. --- scripts/eressea/xmasitems.lua | 1 + src/bind_region.c | 93 +++++++++++++++-------------------- 2 files changed, 41 insertions(+), 53 deletions(-) diff --git a/scripts/eressea/xmasitems.lua b/scripts/eressea/xmasitems.lua index a05e023b8..27ea641ee 100644 --- a/scripts/eressea/xmasitems.lua +++ b/scripts/eressea/xmasitems.lua @@ -25,6 +25,7 @@ end function use_stardust(u, amount) local p = u.region:get_resource("peasant") + assert(p>0) p = math.ceil(1.5 * p) u.region:set_resource("peasant", p) local msg = usepotion_message(u, "stardust") diff --git a/src/bind_region.c b/src/bind_region.c index 51a5bedd4..9e4e2f778 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -341,20 +341,16 @@ static int tolua_region_get_resourcelevel(lua_State * L) #define LUA_ASSERT(c, s) if (!(c)) { log_error("%s(%d): %s\n", __FILE__, __LINE__, (s)); return 0; } -static critbit_tree * special_resources(void) -{ - static critbit_tree cb = CRITBIT_TREE(); - if (!cb.root) { - const char * special[] = { "seed", "sapling", "tree", "grave", "chaos", 0 }; - char buffer[32]; - int i; - for (i = 0; special[i]; ++i) { - size_t len = strlen(special[i]); - len = cb_new_kv(special[i], len, &i, sizeof(int), buffer); - cb_insert(&cb, buffer, len); +static int special_resource(const char *type) { + const char * special[] = { "seed", "sapling", "tree", "grave", "chaos", 0 }; + int i; + + for (i = 0; special[i]; ++i) { + if (strcmp(type, special[i]) == 0) { + return i; } } - return &cb; + return -1; } static int tolua_region_get_resource(lua_State * L) @@ -362,32 +358,27 @@ static int tolua_region_get_resource(lua_State * L) region *r; const char *type; const resource_type *rtype; - int result = 0; - void * match; - critbit_tree * cb = special_resources(); + int result; r = (region *)tolua_tousertype(L, 1, 0); LUA_ASSERT(r != NULL, "invalid parameter"); type = tolua_tostring(L, 2, 0); LUA_ASSERT(type != NULL, "invalid parameter"); - - if (cb_find_prefix(cb, type, strlen(type) + 1, &match, 1, 0)) { - cb_get_kv(match, &result, sizeof(result)); - switch (result) { - case 0: - case 1: - case 2: - result = rtrees(r, result); - break; - case 3: - result = deathcount(r); - break; - case 4: - result = get_chaoscount(r); - break; - } - } - else { + + result = special_resource(type); + switch (result) { + case 0: + case 1: + case 2: + result = rtrees(r, result); + break; + case 3: + result = deathcount(r); + break; + case 4: + result = get_chaoscount(r); + break; + default: rtype = rt_find(type); if (rtype) { result = region_getresource(r, rtype); @@ -406,27 +397,23 @@ static int tolua_region_set_resource(lua_State * L) region *r = (region *)tolua_tousertype(L, 1, 0); const char *type = tolua_tostring(L, 2, 0); int result, value = (int)tolua_tonumber(L, 3, 0); - critbit_tree * cb = special_resources(); - void * match; + const resource_type *rtype; - if (cb_find_prefix(cb, type, strlen(type) + 1, &match, 1, 0)) { - cb_get_kv(match, &result, sizeof(result)); - switch (result) { - case 0: - case 1: - case 2: - rsettrees(r, result, value); - break; - case 3: - deathcounts(r, value - deathcount(r)); - break; - case 4: - add_chaoscount(r, value - get_chaoscount(r)); - break; - } - } - else { - const resource_type *rtype = rt_find(type); + result = special_resource(type); + switch (result) { + case 0: + case 1: + case 2: + rsettrees(r, result, value); + break; + case 3: + deathcounts(r, value - deathcount(r)); + break; + case 4: + add_chaoscount(r, value - get_chaoscount(r)); + break; + default: + rtype = rt_find(type); if (rtype != NULL) { region_setresource(r, rtype, value); } From b8ffc20d87c4b592e4c8c8cf43a21b2abec840f6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 19:54:58 +0100 Subject: [PATCH 016/218] remove item_useonother callbacks (use is fine). add a test for foolpotion. --- res/core/common/potions.xml | 2 +- scripts/tests/e2/e2features.lua | 24 ++++++++++++++++++++++++ src/kernel/item.c | 13 ++++++------- src/kernel/item.h | 2 -- src/kernel/xmlreader.c | 5 ----- src/laws.c | 22 ++++++---------------- 6 files changed, 37 insertions(+), 31 deletions(-) diff --git a/res/core/common/potions.xml b/res/core/common/potions.xml index 84b1e5f52..12ac67aa2 100644 --- a/res/core/common/potions.xml +++ b/res/core/common/potions.xml @@ -101,7 +101,7 @@ - + diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index de94ea34f..28cbbf69b 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -230,6 +230,30 @@ function test_no_uruk() assert_equal(f1.race, "orc") end +function test_foolpotion() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("p7", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242") + process_orders() + assert_equal(1, u:get_item("p7")) + assert_equal(1, f:count_msg_type('feedback_unit_not_found')) + local u2 = unit.create(f, r, 1) + + u:clear_orders() + u:add_order("BENUTZEN 1 Dumpfbackenbrot " .. itoa36(u2.id)) + process_orders() + assert_equal(1, u:get_item("p7")) + assert_equal(1, f:count_msg_type('error64')) + + u:set_skill("stealth", 1); + process_orders() + assert_equal(0, u:get_item("p7")) + assert_equal(1, f:count_msg_type('givedumb')) +end + function test_snowman() local r = region.create(0, 0, "glacier") local f = faction.create("noreply@eressea.de", "human", "de") diff --git a/src/kernel/item.c b/src/kernel/item.c index 38d2e8711..9240a7994 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -820,9 +820,8 @@ struct order *ord) return 0; } -static int -use_warmthpotion(struct unit *u, const struct item_type *itype, int amount, -struct order *ord) +static int use_warmthpotion(unit *u, const item_type *itype, + int amount, struct order *ord) { if (u->faction->race == get_race(RC_INSECT)) { fset(u, UFL_WARMTH); @@ -841,10 +840,10 @@ struct order *ord) return 0; } -static int -use_foolpotion(struct unit *u, int targetno, const struct item_type *itype, -int amount, struct order *ord) +static int use_foolpotion(unit *u, const item_type *itype, int amount, + struct order *ord) { + int targetno = read_unitid(u->faction, u->region); unit *target = findunit(targetno); if (target == NULL || u->region != target->region) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", @@ -1295,7 +1294,7 @@ void register_resources(void) register_item_use(use_warmthpotion, "usewarmthpotion"); register_item_use(use_bloodpotion, "usebloodpotion"); register_item_use(use_healingpotion, "usehealingpotion"); - register_item_useonother(use_foolpotion, "usefoolpotion"); + register_item_use(use_foolpotion, "usefoolpotion"); register_item_use(use_mistletoe, "usemistletoe"); register_item_use(use_magicboost, "usemagicboost"); register_item_use(use_snowball, "usesnowball"); diff --git a/src/kernel/item.h b/src/kernel/item.h index 4351d611d..a2e588318 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -127,8 +127,6 @@ extern "C" { const struct item_type * itype); int(*use) (struct unit * user, const struct item_type * itype, int amount, struct order * ord); - int(*useonother) (struct unit * user, int targetno, - const struct item_type * itype, int amount, struct order * ord); int(*give) (struct unit * src, struct unit * dest, const struct item_type * itm, int number, struct order * ord); int score; diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 21c80566c..f5e45dd5c 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -857,11 +857,6 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) itype->canuse = (bool(*)(const struct unit *, const struct item_type *))fun; } - else if (strcmp((const char *)propValue, "useonother") == 0) { - itype->useonother = - (int(*)(struct unit *, int, const struct item_type *, int, - struct order *))fun; - } else { log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, rtype->_name); } diff --git a/src/laws.c b/src/laws.c index 253b45b89..09b1439c0 100644 --- a/src/laws.c +++ b/src/laws.c @@ -3242,11 +3242,6 @@ void update_long_order(unit * u) static int use_item(unit * u, const item_type * itype, int amount, struct order *ord) { int i; - int target = -1; - - if (itype->useonother) { - target = read_unitid(u->faction, u->region); - } i = get_pooled(u, itype->rtype, GET_DEFAULT, amount); if (amount > i) { @@ -3257,19 +3252,14 @@ static int use_item(unit * u, const item_type * itype, int amount, struct order return ENOITEM; } - if (target == -1) { - if (itype->use) { - int result = itype->use(u, itype, amount, ord); - if (result > 0) { - use_pooled(u, itype->rtype, GET_DEFAULT, result); - } - return result; + if (itype->use) { + int result = itype->use(u, itype, amount, ord); + if (result > 0) { + use_pooled(u, itype->rtype, GET_DEFAULT, result); } - return EUNUSABLE; - } - else { - return itype->useonother(u, target, itype, amount, ord); + return result; } + return EUNUSABLE; } void monthly_healing(void) From b8d9fae4e446685b2e331036b80540283401f001 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 Feb 2017 20:16:22 +0100 Subject: [PATCH 017/218] begin version 3.12 --- src/kernel/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/version.c b/src/kernel/version.c index 633fbf7bf..39f4f30e6 100644 --- a/src/kernel/version.c +++ b/src/kernel/version.c @@ -5,7 +5,7 @@ #ifndef ERESSEA_VERSION /* the version number, if it was not passed to make with -D */ -#define ERESSEA_VERSION "3.11.0" +#define ERESSEA_VERSION "3.12.0" #endif const char *eressea_version(void) { From 8b69b6d003358e88b278f717bfb2e22d91355b0b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 04:00:45 +0100 Subject: [PATCH 018/218] test peasantblood effects --- scripts/tests/e2/e2features.lua | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index 28cbbf69b..eb2d06f0d 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -230,6 +230,32 @@ function test_no_uruk() assert_equal(f1.race, "orc") end +function test_bloodpotion_demon() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "demon", "de") + local u = unit.create(f, r, 1) + u:add_item("peasantblood", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Bauernblut") + process_orders() + assert_equal(0, u:get_item("peasantblood")) + assert_equal(1, f:count_msg_type('usepotion')) + assert_equal("demon", u.race) +end + +function test_bloodpotion_other() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("peasantblood", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Bauernblut") + process_orders() + assert_equal(0, u:get_item("peasantblood")) + assert_equal(1, f:count_msg_type('usepotion')) + assert_equal("smurf", u.race) +end + function test_foolpotion() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") From 44c3838d790c290bff577e385be65d3f2f8182b9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 04:22:28 +0100 Subject: [PATCH 019/218] WIP: itype->use elimination. --- res/e3a/items.xml | 4 +--- res/eressea/items.xml | 24 ++++++------------------ src/helpers.c | 10 +++++++--- src/kernel/item.h | 1 + src/kernel/resources.c | 2 ++ src/kernel/resources.h | 3 ++- src/kernel/xmlreader.c | 3 +++ src/laws.c | 4 ++-- 8 files changed, 24 insertions(+), 27 deletions(-) diff --git a/res/e3a/items.xml b/res/e3a/items.xml index 7d7e6b286..fa3af4b41 100644 --- a/res/e3a/items.xml +++ b/res/e3a/items.xml @@ -81,9 +81,7 @@ - - - + diff --git a/res/eressea/items.xml b/res/eressea/items.xml index 69f84c890..c0b8b5126 100644 --- a/res/eressea/items.xml +++ b/res/eressea/items.xml @@ -17,21 +17,15 @@ - - - + - - - + - - - + @@ -44,23 +38,17 @@ - - - + - - - + - - - + diff --git a/src/helpers.c b/src/helpers.c index ad222a0c6..e5bdf6ff9 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -490,14 +490,18 @@ static int lua_equipmentcallback(const struct equipment *eq, unit * u) } /** callback for an item-use function written in lua. */ -int -lua_useitem(struct unit *u, const struct item_type *itype, int amount, +static int +use_item_lua(struct unit *u, const struct item_type *itype, int amount, struct order *ord) { lua_State *L = (lua_State *)global.vm_state; int result = 0; char fname[64]; + if (itype->use) { + return itype->use(u, itype, amount, ord); + } + strlcpy(fname, "use_", sizeof(fname)); strlcat(fname, itype->rtype->_name, sizeof(fname)); @@ -551,7 +555,6 @@ void register_tolua_helpers(void) register_function((pf_generic)lua_callspell, TOLUA_CAST "lua_castspell"); register_function((pf_generic)lua_initfamiliar, TOLUA_CAST "lua_initfamiliar"); - register_item_use(&lua_useitem, TOLUA_CAST "lua_useitem"); register_function((pf_generic)lua_getresource, TOLUA_CAST "lua_getresource"); register_function((pf_generic)lua_canuse_item, @@ -565,6 +568,7 @@ void register_tolua_helpers(void) register_function((pf_generic)lua_maintenance, TOLUA_CAST "lua_maintenance"); + item_use_fun = use_item_lua; res_produce_fun = produce_resource_lua; res_limit_fun = limit_resource_lua; register_item_give(lua_giveitem, TOLUA_CAST "lua_giveitem"); diff --git a/src/kernel/item.h b/src/kernel/item.h index a2e588318..b0bc10cd8 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -107,6 +107,7 @@ extern "C" { #define ITF_BIG 0x0008 /* big item, e.g. does not fit in a bag of holding */ #define ITF_ANIMAL 0x0010 /* an animal */ #define ITF_VEHICLE 0x0020 /* a vehicle, drawn by two animals */ +#define ITF_CANUSE 0x0040 /* can be used with use_item_fun callout */ /* error codes for item_type::use */ #define ECUSTOM -1 diff --git a/src/kernel/resources.c b/src/kernel/resources.c index f99783763..10cb2bab6 100644 --- a/src/kernel/resources.c +++ b/src/kernel/resources.c @@ -213,6 +213,8 @@ struct rawmaterial_type *rmt_create(struct resource_type *rtype) return rmtype; } +int(*item_use_fun)(struct unit *u, const struct item_type *itype, int amount, + struct order *ord); int(*res_limit_fun)(const struct region *, const struct resource_type *); void(*res_produce_fun)(struct region *, const struct resource_type *, int); diff --git a/src/kernel/resources.h b/src/kernel/resources.h index b448425f4..7f48fa0dd 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -74,7 +74,8 @@ extern "C" { extern int(*res_limit_fun)(const struct region *, const struct resource_type *); extern void(*res_produce_fun)(struct region *, const struct resource_type *, int); - + extern int (*item_use_fun)(struct unit *, const struct item_type *, int amount, + struct order *ord); int limit_resource(const struct region *r, const struct resource_type *rtype); void produce_resource(struct region *r, const struct resource_type *rtype, int amount); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index f5e45dd5c..6f62738e3 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -767,6 +767,8 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) if (xml_bvalue(node, "cursed", false)) flags |= ITF_CURSED; + if (xml_bvalue(node, "use", false)) + flags |= ITF_CANUSE; if (xml_bvalue(node, "notlost", false)) flags |= ITF_NOTLOST; if (xml_bvalue(node, "herb", false)) @@ -849,6 +851,7 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) struct order *))fun; } else if (strcmp((const char *)propValue, "use") == 0) { + itype->flags |= ITF_CANUSE; itype->use = (int(*)(struct unit *, const struct item_type *, int, struct order *))fun; diff --git a/src/laws.c b/src/laws.c index 09b1439c0..0d0e53110 100644 --- a/src/laws.c +++ b/src/laws.c @@ -3252,8 +3252,8 @@ static int use_item(unit * u, const item_type * itype, int amount, struct order return ENOITEM; } - if (itype->use) { - int result = itype->use(u, itype, amount, ord); + if (itype->flags & ITF_CANUSE) { + int result = item_use_fun(u, itype, amount, ord); if (result > 0) { use_pooled(u, itype->rtype, GET_DEFAULT, result); } From 715c8569ba50b3f53d4824122244de34bf130a37 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 09:48:24 +0100 Subject: [PATCH 020/218] hacked the item-use function, XML needs cleaning up, funpointer needs to die --- src/helpers.c | 27 ++++++++++++++++++--------- src/kernel/item.c | 4 ++-- src/kernel/xmlreader.c | 4 ++++ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/helpers.c b/src/helpers.c index e5bdf6ff9..5124ca0ae 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -13,6 +13,7 @@ without prior permission by the authors of Eressea. #include #include "helpers.h" #include "vortex.h" +#include "alchemy.h" #include #include @@ -491,20 +492,21 @@ static int lua_equipmentcallback(const struct equipment *eq, unit * u) /** callback for an item-use function written in lua. */ static int -use_item_lua(struct unit *u, const struct item_type *itype, int amount, -struct order *ord) +use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord) { lua_State *L = (lua_State *)global.vm_state; int result = 0; char fname[64]; - - if (itype->use) { - return itype->use(u, itype, amount, ord); - } + int (*callout)(unit *, const item_type *, int, struct order *); strlcpy(fname, "use_", sizeof(fname)); strlcat(fname, itype->rtype->_name, sizeof(fname)); + callout = (int(*)(unit *, const item_type *, int, struct order *))get_function(fname); + if (callout) { + return callout(u, itype, amount, ord); + } + lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); @@ -520,11 +522,18 @@ struct order *ord) result = (int)lua_tonumber(L, -1); lua_pop(L, 1); } + return result; } - else { - log_error("use(%s) calling '%s': not a function.\n", unitname(u), fname); - lua_pop(L, 1); + if (itype->rtype->ptype) { + return use_potion(u, itype, amount, ord); + } else { + log_error("no such callout: %s", fname); } + if (itype->use) { + return itype->use(u, itype, amount, ord); + } + log_error("use(%s) calling '%s': not a function.\n", unitname(u), fname); + lua_pop(L, 1); return result; } diff --git a/src/kernel/item.c b/src/kernel/item.c index 9240a7994..5991eca96 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -1292,9 +1292,9 @@ void register_resources(void) register_item_use(use_tacticcrystal, "use_tacticcrystal"); register_item_use(use_birthdayamulet, "use_birthdayamulet"); register_item_use(use_warmthpotion, "usewarmthpotion"); - register_item_use(use_bloodpotion, "usebloodpotion"); + register_item_use(use_bloodpotion, "use_peasantblood"); register_item_use(use_healingpotion, "usehealingpotion"); - register_item_use(use_foolpotion, "usefoolpotion"); + register_item_use(use_foolpotion, "use_p7"); register_item_use(use_mistletoe, "usemistletoe"); register_item_use(use_magicboost, "usemagicboost"); register_item_use(use_snowball, "usesnowball"); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 6f62738e3..c4ce845a5 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -805,6 +805,10 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) result = xmlXPathEvalExpression(BAD_CAST "potion", xpath); assert(result->nodesetval->nodeNr <= 1); if (result->nodesetval->nodeNr != 0) { + if ((itype->flags & ITF_CANUSE) == 0) { + log_error("potion %s has no use attribute", rtype->_name); + itype->flags |= ITF_CANUSE; + } xpath->node = result->nodesetval->nodeTab[0]; rtype->ptype = xml_readpotion(xpath, itype); } From 604b574d0f25e600ea8b25ac520e567adcfab55f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 11:39:55 +0100 Subject: [PATCH 021/218] fix potion-use? need more testing --- res/core/common/potions.xml | 45 +++++++++++---------------------- res/e3a/items.xml | 24 ++++++------------ scripts/tests/e2/e2features.lua | 15 +++++++++++ src/kernel/item.c | 7 +++-- 4 files changed, 41 insertions(+), 50 deletions(-) diff --git a/res/core/common/potions.xml b/res/core/common/potions.xml index 12ac67aa2..4812727dd 100644 --- a/res/core/common/potions.xml +++ b/res/core/common/potions.xml @@ -4,8 +4,7 @@ - - + @@ -15,8 +14,7 @@ - - + @@ -26,8 +24,7 @@ - - + @@ -37,8 +34,7 @@ - - + @@ -48,8 +44,7 @@ - - + @@ -61,8 +56,7 @@ - - + @@ -74,8 +68,7 @@ - - + @@ -87,8 +80,7 @@ - - + @@ -100,8 +92,7 @@ - - + @@ -113,8 +104,7 @@ - - + @@ -126,8 +116,7 @@ - - + @@ -139,8 +128,7 @@ - - + @@ -152,8 +140,7 @@ - - + @@ -166,8 +153,7 @@ - - + @@ -181,8 +167,7 @@ - - + diff --git a/res/e3a/items.xml b/res/e3a/items.xml index fa3af4b41..9e928837e 100644 --- a/res/e3a/items.xml +++ b/res/e3a/items.xml @@ -7,64 +7,56 @@ - - + - - + - - + - - + - - + - - + - - + - - + diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index eb2d06f0d..c88dfdf22 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -230,6 +230,21 @@ function test_no_uruk() assert_equal(f1.race, "orc") end +function test_ointment() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + local hp = u.hp + u.hp = 0 + u:add_item("ointment", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Wundsalbe") + process_orders() + assert_equal(0, u:get_item("ointment")) + assert_equal(1, f:count_msg_type('usepotion')) + assert_equal(hp, u.hp) +end + function test_bloodpotion_demon() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "demon", "de") diff --git a/src/kernel/item.c b/src/kernel/item.c index 5991eca96..1fa006c73 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -1287,13 +1287,12 @@ void register_resources(void) register_function((pf_generic)res_changehp, "changehp"); register_function((pf_generic)res_changeaura, "changeaura"); - register_item_use(use_potion, "usepotion"); - register_item_use(use_potion_delayed, "usepotion_delayed"); + register_item_use(use_potion_delayed, "use_p2"); register_item_use(use_tacticcrystal, "use_tacticcrystal"); register_item_use(use_birthdayamulet, "use_birthdayamulet"); - register_item_use(use_warmthpotion, "usewarmthpotion"); + register_item_use(use_warmthpotion, "use_nestwarmth"); register_item_use(use_bloodpotion, "use_peasantblood"); - register_item_use(use_healingpotion, "usehealingpotion"); + register_item_use(use_healingpotion, "use_ointment"); register_item_use(use_foolpotion, "use_p7"); register_item_use(use_mistletoe, "usemistletoe"); register_item_use(use_magicboost, "usemagicboost"); From 60c2f1e8074a94f34325d4436c2aa4088045b974 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 14:01:41 +0100 Subject: [PATCH 022/218] test the birthday amulet --- res/core/common/items.xml | 4 +--- scripts/tests/e2/e2features.lua | 14 +++++++++++++- src/bind_region.c | 20 ++++++++++++++++++++ src/kernel/item.c | 2 +- src/kernel/xmlreader.c | 1 + 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/res/core/common/items.xml b/res/core/common/items.xml index c903a6b78..8745b6e59 100644 --- a/res/core/common/items.xml +++ b/res/core/common/items.xml @@ -62,9 +62,7 @@ - - - + diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index c88dfdf22..5af956980 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -230,12 +230,24 @@ function test_no_uruk() assert_equal(f1.race, "orc") end +function test_meow() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("aoc", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Katzenamulett") + process_orders() + assert_equal(1, u:get_item("aoc")) + assert_equal(1, r:count_msg_type('meow')) +end + function test_ointment() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) local hp = u.hp - u.hp = 0 + u.hp = 1 u:add_item("ointment", 1) u:clear_orders() u:add_order("BENUTZEN 1 Wundsalbe") diff --git a/src/bind_region.c b/src/bind_region.c index 9e4e2f778..05c0e3842 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -29,6 +29,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include #include #include @@ -46,6 +47,23 @@ without prior permission by the authors of Eressea. #include #include +static int tolua_region_count_msg_type(lua_State *L) { + region *self = (region *)tolua_tousertype(L, 1, 0); + const char *str = tolua_tostring(L, 2, 0); + int n = 0; + if (self->msgs) { + mlist * ml = self->msgs->begin; + while (ml) { + if (strcmp(str, ml->msg->type->name) == 0) { + ++n; + } + ml = ml->next; + } + } + lua_pushinteger(L, n); + return 1; +} + int tolua_regionlist_next(lua_State * L) { region **region_ptr = (region **)lua_touserdata(L, lua_upvalueindex(1)); @@ -671,6 +689,8 @@ void tolua_region_open(lua_State * L) tolua_function(L, TOLUA_CAST "destroy", tolua_region_destroy); tolua_function(L, TOLUA_CAST "__tostring", tolua_region_tostring); + tolua_function(L, TOLUA_CAST "count_msg_type", tolua_region_count_msg_type); + /* flags */ tolua_variable(L, TOLUA_CAST "blocked", tolua_region_get_blocked, tolua_region_set_blocked); diff --git a/src/kernel/item.c b/src/kernel/item.c index 1fa006c73..e0f8f64cc 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -1289,7 +1289,7 @@ void register_resources(void) register_item_use(use_potion_delayed, "use_p2"); register_item_use(use_tacticcrystal, "use_tacticcrystal"); - register_item_use(use_birthdayamulet, "use_birthdayamulet"); + register_item_use(use_birthdayamulet, "use_aoc"); register_item_use(use_warmthpotion, "use_nestwarmth"); register_item_use(use_bloodpotion, "use_peasantblood"); register_item_use(use_healingpotion, "use_ointment"); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index c4ce845a5..69e9c22d0 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -855,6 +855,7 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) struct order *))fun; } else if (strcmp((const char *)propValue, "use") == 0) { + log_error("%s has a use function", rtype->_name); itype->flags |= ITF_CANUSE; itype->use = (int(*)(struct unit *, const struct item_type *, int, From 5ffe60193bdbdaad2b72f019b020bc2dd1743f76 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 14:10:12 +0100 Subject: [PATCH 023/218] move items with tests to items.c --- src/items.c | 134 ++++++++++++++++++++++++++++++++++++++++++++-- src/kernel/item.c | 134 ++-------------------------------------------- 2 files changed, 133 insertions(+), 135 deletions(-) diff --git a/src/items.c b/src/items.c index bb5009038..cae5ea642 100644 --- a/src/items.c +++ b/src/items.c @@ -1,6 +1,7 @@ #include #include "items.h" +#include "alchemy.h" #include "study.h" #include "economy.h" #include "move.h" @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -21,9 +23,15 @@ #include +/* triggers includes */ +#include +#include + #include +#include #include #include +#include #include #include @@ -125,15 +133,15 @@ struct order *ord) UNUSED_ARG(ord); assert(sp); - /* Reduziert die Strke jedes Spruchs um effect */ + /* Reduziert die St�rke jedes Spruchs um effect */ effect = 5; - /* Hlt Sprche bis zu einem summierten Gesamtlevel von power aus. + /* H�lt Spr�che bis zu einem summierten Gesamtlevel von power aus. * Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone * um seine Stufe */ force = effect * 20; /* Stufe 5 =~ 100 */ - /* Regionszauber auflsen */ + /* Regionszauber aufl�sen */ while (*ap && force > 0) { curse *c; attrib *a = *ap; @@ -145,7 +153,7 @@ struct order *ord) } c = (curse *)a->data.v; - /* Immunitt prfen */ + /* Immunit�t pr�fen */ if (c_flags(c) & CURSE_IMMUNE) { do { ap = &(*ap)->next; @@ -264,6 +272,118 @@ int amount, struct order *ord) return 0; } +static int +use_birthdayamulet(unit * u, const struct item_type *itype, int amount, +struct order *ord) +{ + direction_t d; + message *msg = msg_message("meow", ""); + + UNUSED_ARG(ord); + UNUSED_ARG(amount); + UNUSED_ARG(itype); + + add_message(&u->region->msgs, msg); + for (d = 0; d < MAXDIRECTIONS; d++) { + region *tr = rconnect(u->region, d); + if (tr) + add_message(&tr->msgs, msg); + } + msg_release(msg); + return 0; +} + +static int use_foolpotion(unit *u, const item_type *itype, int amount, + struct order *ord) +{ + int targetno = read_unitid(u->faction, u->region); + unit *target = findunit(targetno); + if (target == NULL || u->region != target->region) { + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", + "")); + return ECUSTOM; + } + if (effskill(u, SK_STEALTH, 0) <= effskill(target, SK_PERCEPTION, 0)) { + cmistake(u, ord, 64, MSG_EVENT); + return ECUSTOM; + } + ADDMSG(&u->faction->msgs, msg_message("givedumb", + "unit recipient amount", u, target, amount)); + + change_effect(target, itype->rtype->ptype, amount); + use_pooled(u, itype->rtype, GET_DEFAULT, amount); + return 0; +} + +static int +use_bloodpotion(struct unit *u, const struct item_type *itype, int amount, +struct order *ord) +{ + if (u->number == 0 || u_race(u) == get_race(RC_DAEMON)) { + change_effect(u, itype->rtype->ptype, 100 * amount); + } + else { + const race *irace = u_irace(u); + if (irace == u_race(u)) { + const race *rcfailure = rc_find("smurf"); + if (!rcfailure) { + rcfailure = rc_find("toad"); + } + if (rcfailure) { + trigger *trestore = trigger_changerace(u, u_race(u), irace); + if (trestore) { + int duration = 2 + rng_int() % 8; + + add_trigger(&u->attribs, "timer", trigger_timeout(duration, + trestore)); + u->irace = NULL; + u_setrace(u, rcfailure); + } + } + } + } + use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, + amount); + usetpotionuse(u, itype->rtype->ptype); + + ADDMSG(&u->faction->msgs, msg_message("usepotion", + "unit potion", u, itype->rtype)); + return 0; +} + +static int heal(unit * user, int effect) +{ + int req = unit_max_hp(user) * user->number - user->hp; + if (req > 0) { + req = MIN(req, effect); + effect -= req; + user->hp += req; + } + return effect; +} + +static int +use_healingpotion(struct unit *user, const struct item_type *itype, int amount, +struct order *ord) +{ + int effect = amount * 400; + unit *u = user->region->units; + effect = heal(user, effect); + while (effect > 0 && u != NULL) { + if (u->faction == user->faction) { + effect = heal(u, effect); + } + u = u->next; + } + use_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, + amount); + usetpotionuse(user, itype->rtype->ptype); + + ADDMSG(&user->faction->msgs, msg_message("usepotion", + "unit potion", user, itype->rtype)); + return 0; +} + void register_itemfunctions(void) { register_demonseye(); @@ -274,4 +394,10 @@ void register_itemfunctions(void) register_item_use(use_instantartacademy, "use_instantartacademy"); register_item_use(use_bagpipeoffear, "use_bagpipeoffear"); register_item_use(use_aurapotion50, "use_aurapotion50"); + + /* have tests: */ + register_item_use(use_birthdayamulet, "use_aoc"); + register_item_use(use_foolpotion, "use_p7"); + register_item_use(use_bloodpotion, "use_peasantblood"); + register_item_use(use_healingpotion, "use_ointment"); } diff --git a/src/kernel/item.c b/src/kernel/item.c index e0f8f64cc..ecad829ca 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -34,23 +34,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "terrain.h" #include "unit.h" -/* triggers includes */ -#include -#include - /* util includes */ #include #include -#include -#include #include #include #include #include #include -#include #include +#include +#include #include /* libc includes */ @@ -675,27 +670,6 @@ int set_item(unit * u, const item_type *itype, int value) return value; } -static int -use_birthdayamulet(unit * u, const struct item_type *itype, int amount, -struct order *ord) -{ - direction_t d; - message *msg = msg_message("meow", ""); - - UNUSED_ARG(ord); - UNUSED_ARG(amount); - UNUSED_ARG(itype); - - add_message(&u->region->msgs, msg); - for (d = 0; d < MAXDIRECTIONS; d++) { - region *tr = rconnect(u->region, d); - if (tr) - add_message(&tr->msgs, msg); - } - msg_release(msg); - return 0; -} - /* t_item::flags */ #define FL_ITEM_CURSED (1<<0) #define FL_ITEM_NOTLOST (1<<1) @@ -766,17 +740,6 @@ mod_dwarves_only(const unit * u, const region * r, skill_t sk, int value) return -118; } -static int heal(unit * user, int effect) -{ - int req = unit_max_hp(user) * user->number - user->hp; - if (req > 0) { - req = MIN(req, effect); - effect -= req; - user->hp += req; - } - return effect; -} - void register_item_give(int(*foo) (struct unit *, struct unit *, const struct item_type *, int, struct order *), const char *name) @@ -791,35 +754,6 @@ struct order *), const char *name) register_function((pf_generic)foo, name); } -void -register_item_useonother(int(*foo) (struct unit *, int, -const struct item_type *, int, struct order *), const char *name) -{ - register_function((pf_generic)foo, name); -} - -static int -use_healingpotion(struct unit *user, const struct item_type *itype, int amount, -struct order *ord) -{ - int effect = amount * 400; - unit *u = user->region->units; - effect = heal(user, effect); - while (effect > 0 && u != NULL) { - if (u->faction == user->faction) { - effect = heal(u, effect); - } - u = u->next; - } - use_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, - amount); - usetpotionuse(user, itype->rtype->ptype); - - ADDMSG(&user->faction->msgs, msg_message("usepotion", - "unit potion", user, itype->rtype)); - return 0; -} - static int use_warmthpotion(unit *u, const item_type *itype, int amount, struct order *ord) { @@ -840,64 +774,6 @@ static int use_warmthpotion(unit *u, const item_type *itype, return 0; } -static int use_foolpotion(unit *u, const item_type *itype, int amount, - struct order *ord) -{ - int targetno = read_unitid(u->faction, u->region); - unit *target = findunit(targetno); - if (target == NULL || u->region != target->region) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", - "")); - return ECUSTOM; - } - if (effskill(u, SK_STEALTH, 0) <= effskill(target, SK_PERCEPTION, 0)) { - cmistake(u, ord, 64, MSG_EVENT); - return ECUSTOM; - } - ADDMSG(&u->faction->msgs, msg_message("givedumb", - "unit recipient amount", u, target, amount)); - - change_effect(target, itype->rtype->ptype, amount); - use_pooled(u, itype->rtype, GET_DEFAULT, amount); - return 0; -} - -static int -use_bloodpotion(struct unit *u, const struct item_type *itype, int amount, -struct order *ord) -{ - if (u->number == 0 || u_race(u) == get_race(RC_DAEMON)) { - change_effect(u, itype->rtype->ptype, 100 * amount); - } - else { - const race *irace = u_irace(u); - if (irace == u_race(u)) { - const race *rcfailure = rc_find("smurf"); - if (!rcfailure) { - rcfailure = rc_find("toad"); - } - if (rcfailure) { - trigger *trestore = trigger_changerace(u, u_race(u), irace); - if (trestore) { - int duration = 2 + rng_int() % 8; - - add_trigger(&u->attribs, "timer", trigger_timeout(duration, - trestore)); - u->irace = NULL; - u_setrace(u, rcfailure); - } - } - } - } - use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, - amount); - usetpotionuse(u, itype->rtype->ptype); - - ADDMSG(&u->faction->msgs, msg_message("usepotion", - "unit potion", u, itype->rtype)); - return 0; -} - #include static int use_mistletoe(struct unit *user, const struct item_type *itype, int amount, @@ -1288,12 +1164,8 @@ void register_resources(void) register_function((pf_generic)res_changeaura, "changeaura"); register_item_use(use_potion_delayed, "use_p2"); - register_item_use(use_tacticcrystal, "use_tacticcrystal"); - register_item_use(use_birthdayamulet, "use_aoc"); register_item_use(use_warmthpotion, "use_nestwarmth"); - register_item_use(use_bloodpotion, "use_peasantblood"); - register_item_use(use_healingpotion, "use_ointment"); - register_item_use(use_foolpotion, "use_p7"); + register_item_use(use_tacticcrystal, "use_tacticcrystal"); register_item_use(use_mistletoe, "usemistletoe"); register_item_use(use_magicboost, "usemagicboost"); register_item_use(use_snowball, "usesnowball"); From db0cbf34c713a25ff2c8743ad808a5a94577c2a6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 14:17:38 +0100 Subject: [PATCH 024/218] test for aurapotion --- scripts/tests/e2/e2features.lua | 17 +++++++++++++++++ src/items.c | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index 5af956980..59e93f86b 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -242,6 +242,23 @@ function test_meow() assert_equal(1, r:count_msg_type('meow')) end +function test_aurapotion50() + eressea.settings.set("magic.regeneration.enable", "0") + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("aurapotion50", 1) + u:set_skill('magic', 10); + u.magic = 'gwyrrd' + u.aura = 0 + u:clear_orders() + u:add_order("BENUTZEN 1 Auratrank") + process_orders() + assert_equal(0, u:get_item("aurapotion50")) + assert_equal(1, f:count_msg_type('aurapotion50')) + assert_equal(50, u.aura) +end + function test_ointment() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") diff --git a/src/items.c b/src/items.c index cae5ea642..75cb79b68 100644 --- a/src/items.c +++ b/src/items.c @@ -393,9 +393,9 @@ void register_itemfunctions(void) register_item_use(use_speedsail, "use_speedsail"); register_item_use(use_instantartacademy, "use_instantartacademy"); register_item_use(use_bagpipeoffear, "use_bagpipeoffear"); - register_item_use(use_aurapotion50, "use_aurapotion50"); /* have tests: */ + register_item_use(use_aurapotion50, "use_aurapotion50"); register_item_use(use_birthdayamulet, "use_aoc"); register_item_use(use_foolpotion, "use_p7"); register_item_use(use_bloodpotion, "use_peasantblood"); From 3d4860c0337933841b39820edeba3b3d1657bbc7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 14:19:25 +0100 Subject: [PATCH 025/218] remove more of the artrewards --- src/items.c | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/src/items.c b/src/items.c index 75cb79b68..b01fe21db 100644 --- a/src/items.c +++ b/src/items.c @@ -179,50 +179,6 @@ struct order *ord) return 0; } -static int -use_instantartsculpture(struct unit *u, const struct item_type *itype, -int amount, struct order *ord) -{ - building *b; - - if (u->region->land == NULL) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", "")); - return -1; - } - - b = new_building(bt_find("artsculpture"), u->region, u->faction->locale); - b->size = 100; - - ADDMSG(&u->region->msgs, msg_message("artsculpture_create", "unit region", - u, u->region)); - - use_pooled(u, itype->rtype, GET_DEFAULT, 1); - - return 0; -} - -static int -use_instantartacademy(struct unit *u, const struct item_type *itype, -int amount, struct order *ord) -{ - building *b; - - if (u->region->land == NULL) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", "")); - return -1; - } - - b = new_building(bt_find("artacademy"), u->region, u->faction->locale); - b->size = 100; - - ADDMSG(&u->region->msgs, msg_message("artacademy_create", "unit region", u, - u->region)); - - use_pooled(u, itype->rtype, GET_DEFAULT, 1); - - return 0; -} - #define BAGPIPEFRACTION dice_rand("2d4+2") #define BAGPIPEDURATION dice_rand("2d10+4") @@ -388,10 +344,8 @@ void register_itemfunctions(void) { register_demonseye(); register_item_use(use_antimagiccrystal, "use_antimagiccrystal"); - register_item_use(use_instantartsculpture, "use_instantartsculpture"); register_item_use(use_studypotion, "use_studypotion"); register_item_use(use_speedsail, "use_speedsail"); - register_item_use(use_instantartacademy, "use_instantartacademy"); register_item_use(use_bagpipeoffear, "use_bagpipeoffear"); /* have tests: */ From 108501e398a29106d1ba6a86e2730210d0ee5cdc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 15:14:52 +0100 Subject: [PATCH 026/218] tests for more items --- res/core/common/items.xml | 4 +-- scripts/tests/e2/e2features.lua | 52 +++++++++++++++++++++++++++++++++ src/items.c | 7 +++-- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/res/core/common/items.xml b/res/core/common/items.xml index 8745b6e59..30926a844 100644 --- a/res/core/common/items.xml +++ b/res/core/common/items.xml @@ -128,9 +128,7 @@ - - - + diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index 59e93f86b..a942480a9 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -259,6 +259,58 @@ function test_aurapotion50() assert_equal(50, u.aura) end +function test_bagpipe() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("bagpipeoffear", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Dudelsack") + process_orders() + assert_equal(1, u:get_item("bagpipeoffear")) + assert_equal(1, f:count_msg_type('bagpipeoffear_faction')) + assert_equal(1, r:count_msg_type('bagpipeoffear_region')) +end + +function test_speedsail() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u.ship = ship.create(r, "boat") + u:add_item("speedsail", 2) + u:clear_orders() + u:add_order("BENUTZEN 1 Sonnensegel") + process_orders() + assert_equal(1, u:get_item("speedsail")) + assert_equal(1, f:count_msg_type('use_speedsail')) +end + +--[[ +function test_studypotion() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("studypotion", 2) + u:clear_orders() + u:add_order("LERNE Unterhaltung") + u:add_order("BENUTZEN 1 Lerntrank") + process_orders() + assert_equal(1, u:get_item("studypotion")) +end +]]-- + +function test_antimagic() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("antimagic", 2) + u:clear_orders() + u:add_order("BENUTZEN 1 Antimagiekristall") + process_orders() + assert_equal(1, r:count_msg_type('use_antimagiccrystal')) + assert_equal(1, u:get_item("antimagic")) +end + function test_ointment() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") diff --git a/src/items.c b/src/items.c index b01fe21db..9833ac6f7 100644 --- a/src/items.c +++ b/src/items.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -343,12 +344,12 @@ struct order *ord) void register_itemfunctions(void) { register_demonseye(); - register_item_use(use_antimagiccrystal, "use_antimagiccrystal"); register_item_use(use_studypotion, "use_studypotion"); - register_item_use(use_speedsail, "use_speedsail"); - register_item_use(use_bagpipeoffear, "use_bagpipeoffear"); /* have tests: */ + register_item_use(use_antimagiccrystal, "use_antimagic"); + register_item_use(use_speedsail, "use_speedsail"); + register_item_use(use_bagpipeoffear, "use_bagpipeoffear"); register_item_use(use_aurapotion50, "use_aurapotion50"); register_item_use(use_birthdayamulet, "use_aoc"); register_item_use(use_foolpotion, "use_p7"); From 1a0992e37b1385ba91b633a58d7d7e982a3ebc63 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 18:21:41 +0100 Subject: [PATCH 027/218] =?UTF-8?q?remove=20remainders=20of=20the=20arena.?= =?UTF-8?q?=20Auge=20des=20Drachens=20haben=20noch=20einige=20Spieler,=20d?= =?UTF-8?q?arf=20nicht=20gel=C3=B6scht=20werden.=20move=20item=20tests=20t?= =?UTF-8?q?o=20tests/items.lua?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...txt => gprof-v3.10.0-163-gdfab45d.profile} | 0 res/core/common/items.xml | 5 + res/eressea/items.xml | 20 +- res/eressea/strings.xml | 35 --- scripts/tests/e2/e2features.lua | 165 ------------ scripts/tests/e2/init.lua | 1 + scripts/tests/items.lua | 186 +++++++++++++ src/attributes/attributes.c | 1 + src/eressea.c | 6 - src/gmtool.c | 3 - src/items.c | 9 +- src/modules/CMakeLists.txt | 1 - src/modules/arena.c | 255 ------------------ src/modules/arena.h | 39 --- src/settings.h | 1 - 15 files changed, 198 insertions(+), 529 deletions(-) rename doc/{gprof-v3.10.0-163-gdfab45d.txt => gprof-v3.10.0-163-gdfab45d.profile} (100%) create mode 100644 scripts/tests/items.lua delete mode 100644 src/modules/arena.c delete mode 100644 src/modules/arena.h diff --git a/doc/gprof-v3.10.0-163-gdfab45d.txt b/doc/gprof-v3.10.0-163-gdfab45d.profile similarity index 100% rename from doc/gprof-v3.10.0-163-gdfab45d.txt rename to doc/gprof-v3.10.0-163-gdfab45d.profile diff --git a/res/core/common/items.xml b/res/core/common/items.xml index 30926a844..63a07d88f 100644 --- a/res/core/common/items.xml +++ b/res/core/common/items.xml @@ -98,6 +98,11 @@ + + + + + diff --git a/res/eressea/items.xml b/res/eressea/items.xml index c0b8b5126..007f0277c 100644 --- a/res/eressea/items.xml +++ b/res/eressea/items.xml @@ -86,27 +86,9 @@ - - - - - - - - - - - - - - - - - - - + diff --git a/res/eressea/strings.xml b/res/eressea/strings.xml index f7497b810..4869014c5 100644 --- a/res/eressea/strings.xml +++ b/res/eressea/strings.xml @@ -116,18 +116,6 @@ Eine Geburtstagstorte mit 10 Kerzen. Herzlichen Glückwunsch, Eressea! A birthday cake with 10 candles. Happy Birthday, Eressea! - - Dieses Fluggerät aus der Schmiede der Zwerge von Celeband galt wie die - 'Ebene der Herausforderung' seit Urzeiten als verschollen, ja man - zweifelte seine Existenz an. Die Sage überliefert, das derjenige, der - sie auf der Spitze des Turmes seiner Gesinnung benutzt, als einziger - die 'Ebene der Herausforderungen' verlassen kann. - - - Glückwunsch, mein Kind. Du bist im Besitz des mächtigsten - Artefaktes Eresseas. Ein Fluch, sagt man, liege auf ihm, denn - niemand hat es bisher lange sein Eigen genannt... - Kleines trockenes Dauergebäck, m od. s; - u. -es, - u. -e @@ -374,29 +362,6 @@ - - - Auge des Dämon - eye of the demon - oeil du démon - - - Augen des Dämon - eyes of the demon - oeil du démon - - - Schwinge des Greifen - wing of the gryphon - aile du griffon - - - Schwingen des Greifen - wings of the gryphon - ailes du griffon - - - Adamantium adamantium diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index a942480a9..da2a98d55 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -230,171 +230,6 @@ function test_no_uruk() assert_equal(f1.race, "orc") end -function test_meow() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("aoc", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Katzenamulett") - process_orders() - assert_equal(1, u:get_item("aoc")) - assert_equal(1, r:count_msg_type('meow')) -end - -function test_aurapotion50() - eressea.settings.set("magic.regeneration.enable", "0") - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("aurapotion50", 1) - u:set_skill('magic', 10); - u.magic = 'gwyrrd' - u.aura = 0 - u:clear_orders() - u:add_order("BENUTZEN 1 Auratrank") - process_orders() - assert_equal(0, u:get_item("aurapotion50")) - assert_equal(1, f:count_msg_type('aurapotion50')) - assert_equal(50, u.aura) -end - -function test_bagpipe() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("bagpipeoffear", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Dudelsack") - process_orders() - assert_equal(1, u:get_item("bagpipeoffear")) - assert_equal(1, f:count_msg_type('bagpipeoffear_faction')) - assert_equal(1, r:count_msg_type('bagpipeoffear_region')) -end - -function test_speedsail() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u.ship = ship.create(r, "boat") - u:add_item("speedsail", 2) - u:clear_orders() - u:add_order("BENUTZEN 1 Sonnensegel") - process_orders() - assert_equal(1, u:get_item("speedsail")) - assert_equal(1, f:count_msg_type('use_speedsail')) -end - ---[[ -function test_studypotion() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("studypotion", 2) - u:clear_orders() - u:add_order("LERNE Unterhaltung") - u:add_order("BENUTZEN 1 Lerntrank") - process_orders() - assert_equal(1, u:get_item("studypotion")) -end -]]-- - -function test_antimagic() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("antimagic", 2) - u:clear_orders() - u:add_order("BENUTZEN 1 Antimagiekristall") - process_orders() - assert_equal(1, r:count_msg_type('use_antimagiccrystal')) - assert_equal(1, u:get_item("antimagic")) -end - -function test_ointment() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - local hp = u.hp - u.hp = 1 - u:add_item("ointment", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Wundsalbe") - process_orders() - assert_equal(0, u:get_item("ointment")) - assert_equal(1, f:count_msg_type('usepotion')) - assert_equal(hp, u.hp) -end - -function test_bloodpotion_demon() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "demon", "de") - local u = unit.create(f, r, 1) - u:add_item("peasantblood", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Bauernblut") - process_orders() - assert_equal(0, u:get_item("peasantblood")) - assert_equal(1, f:count_msg_type('usepotion')) - assert_equal("demon", u.race) -end - -function test_bloodpotion_other() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("peasantblood", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Bauernblut") - process_orders() - assert_equal(0, u:get_item("peasantblood")) - assert_equal(1, f:count_msg_type('usepotion')) - assert_equal("smurf", u.race) -end - -function test_foolpotion() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("p7", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242") - process_orders() - assert_equal(1, u:get_item("p7")) - assert_equal(1, f:count_msg_type('feedback_unit_not_found')) - local u2 = unit.create(f, r, 1) - - u:clear_orders() - u:add_order("BENUTZEN 1 Dumpfbackenbrot " .. itoa36(u2.id)) - process_orders() - assert_equal(1, u:get_item("p7")) - assert_equal(1, f:count_msg_type('error64')) - - u:set_skill("stealth", 1); - process_orders() - assert_equal(0, u:get_item("p7")) - assert_equal(1, f:count_msg_type('givedumb')) -end - -function test_snowman() - local r = region.create(0, 0, "glacier") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("snowman", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Schneemann") - process_orders() - for u2 in r.units do - if u2.id~=u.id then - assert_equal("snowman", u2.race) - assert_equal(1000, u2.hp) - u = nil - break - end - end - assert_equal(nil, u) -end - function test_block_movement() eressea.settings.set("rules.guard.base_stop_prob", "0.3") eressea.settings.set("rules.guard.amulet_stop_prob", "0.0") diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index afaac7209..4d916d1a9 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -8,6 +8,7 @@ require 'tests.e2.destroy' require 'tests.e2.guard' require 'tests.e2.spells' require 'tests.e2.stealth' +require 'tests.items' require 'tests.orders' require 'tests.common' require 'tests.report' diff --git a/scripts/tests/items.lua b/scripts/tests/items.lua new file mode 100644 index 000000000..15d638a63 --- /dev/null +++ b/scripts/tests/items.lua @@ -0,0 +1,186 @@ +require "lunit" + +module("tests.items", package.seeall, lunit.testcase ) + +function setup() + eressea.free_game() + eressea.settings.set("nmr.timeout", "0") + eressea.settings.set("rules.food.flags", "4") + eressea.settings.set("rules.ship.storms", "0") + eressea.settings.set("rules.encounters", "0") +end + +function test_meow() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("aoc", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Katzenamulett") + process_orders() + assert_equal(1, u:get_item("aoc")) + assert_equal(1, r:count_msg_type('meow')) +end + +function test_aurapotion50() + eressea.settings.set("magic.regeneration.enable", "0") + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("aurapotion50", 1) + u:set_skill('magic', 10); + u.magic = 'gwyrrd' + u.aura = 0 + u:clear_orders() + u:add_order("BENUTZEN 1 Auratrank") + process_orders() + assert_equal(0, u:get_item("aurapotion50")) + assert_equal(1, f:count_msg_type('aurapotion50')) + assert_equal(50, u.aura) +end + +function test_bagpipe() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("bagpipeoffear", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Dudelsack") + process_orders() + assert_equal(1, u:get_item("bagpipeoffear")) + assert_equal(1, f:count_msg_type('bagpipeoffear_faction')) + assert_equal(1, r:count_msg_type('bagpipeoffear_region')) +end + +function test_speedsail() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u.ship = ship.create(r, "boat") + u:add_item("speedsail", 2) + u:clear_orders() + u:add_order("BENUTZEN 1 Sonnensegel") + process_orders() + assert_equal(1, u:get_item("speedsail")) + assert_equal(1, f:count_msg_type('use_speedsail')) +end + +function test_skillpotion() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("skillpotion", 2) + u:clear_orders() + u:add_order("BENUTZEN 1 Talenttrunk") + process_orders() + assert_equal(1, u:get_item("skillpotion")) + assert_equal(1, f:count_msg_type('skillpotion_use')) +end + +function test_studypotion() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("studypotion", 2) + u:clear_orders() + u:add_order("LERNE Unterhaltung") + u:add_order("BENUTZEN 1 Lerntrank") + process_orders() + assert_equal(1, u:get_item("studypotion")) +end + +function test_antimagic() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("antimagic", 2) + u:clear_orders() + u:add_order("BENUTZEN 1 Antimagiekristall") + process_orders() + assert_equal(1, r:count_msg_type('use_antimagiccrystal')) + assert_equal(1, u:get_item("antimagic")) +end + +function test_ointment() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + local hp = u.hp + u.hp = 1 + u:add_item("ointment", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Wundsalbe") + process_orders() + assert_equal(0, u:get_item("ointment")) + assert_equal(1, f:count_msg_type('usepotion')) + assert_equal(hp, u.hp) +end + +function test_bloodpotion_demon() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "demon", "de") + local u = unit.create(f, r, 1) + u:add_item("peasantblood", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Bauernblut") + process_orders() + assert_equal(0, u:get_item("peasantblood")) + assert_equal(1, f:count_msg_type('usepotion')) + assert_equal("demon", u.race) +end + +function test_bloodpotion_other() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("peasantblood", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Bauernblut") + process_orders() + assert_equal(0, u:get_item("peasantblood")) + assert_equal(1, f:count_msg_type('usepotion')) + assert_equal("smurf", u.race) +end + +function test_foolpotion() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("p7", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242") + process_orders() + assert_equal(1, u:get_item("p7")) + assert_equal(1, f:count_msg_type('feedback_unit_not_found')) + local u2 = unit.create(f, r, 1) + + u:clear_orders() + u:add_order("BENUTZEN 1 Dumpfbackenbrot " .. itoa36(u2.id)) + process_orders() + assert_equal(1, u:get_item("p7")) + assert_equal(1, f:count_msg_type('error64')) + + u:set_skill("stealth", 1); + process_orders() + assert_equal(0, u:get_item("p7")) + assert_equal(1, f:count_msg_type('givedumb')) +end + +function test_snowman() + local r = region.create(0, 0, "glacier") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("snowman", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Schneemann") + process_orders() + for u2 in r.units do + if u2.id~=u.id then + assert_equal("snowman", u2.race) + assert_equal(1000, u2.hp) + u = nil + break + end + end + assert_equal(nil, u) +end diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index 42f5247fe..ae6869df8 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -112,6 +112,7 @@ void register_attributes(void) at_register(&at_germs); + at_deprecate("hurting", a_readint); /* an old arena attribute */ at_deprecate("xontormiaexpress", a_readint); /* required for old datafiles */ at_deprecate("orcification", a_readint); /* required for old datafiles */ at_deprecate("lua", read_ext); /* required for old datafiles */ diff --git a/src/eressea.c b/src/eressea.c index 8001355f1..2d53c2511 100755 --- a/src/eressea.c +++ b/src/eressea.c @@ -8,9 +8,6 @@ #if MUSEUM_MODULE #include #endif -#if ARENA_MODULE -#include -#endif #include #include #include @@ -77,9 +74,6 @@ void game_init(void) register_itemfunctions(); #if MUSEUM_MODULE register_museum(); -#endif -#if ARENA_MODULE - register_arena(); #endif wormholes_register(); diff --git a/src/gmtool.c b/src/gmtool.c index 3551c3436..148aafe6d 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -26,9 +26,6 @@ #if MUSEUM_MODULE #include #endif -#if ARENA_MODULE -#include -#endif #include #include diff --git a/src/items.c b/src/items.c index 9833ac6f7..197240d3e 100644 --- a/src/items.c +++ b/src/items.c @@ -70,9 +70,9 @@ struct order *ord) if (amount > MAXGAIN) { amount = MAXGAIN; } - teach->value += amount * 30; - if (teach->value > MAXGAIN * 30) { - teach->value = MAXGAIN * 30; + teach->value += amount * STUDYDAYS; + if (teach->value > MAXGAIN * STUDYDAYS) { + teach->value = MAXGAIN * STUDYDAYS; } i_change(&u->items, itype, -amount); return 0; @@ -80,7 +80,6 @@ struct order *ord) } return EUNUSABLE; } - /* END studypotion */ /* BEGIN speedsail */ @@ -344,9 +343,9 @@ struct order *ord) void register_itemfunctions(void) { register_demonseye(); - register_item_use(use_studypotion, "use_studypotion"); /* have tests: */ + register_item_use(use_studypotion, "use_studypotion"); register_item_use(use_antimagiccrystal, "use_antimagic"); register_item_use(use_speedsail, "use_speedsail"); register_item_use(use_bagpipeoffear, "use_bagpipeoffear"); diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 633c486f5..82dee9ec4 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -1,6 +1,5 @@ PROJECT(modules C) SET(_FILES -arena.c autoseed.c gmcmd.c museum.c diff --git a/src/modules/arena.c b/src/modules/arena.c deleted file mode 100644 index fbc3f0673..000000000 --- a/src/modules/arena.c +++ /dev/null @@ -1,255 +0,0 @@ -/* -Copyright (c) 1998-2015, Enno Rehling -Katja Zedel - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -**/ - -#include -#include - -#if ARENA_MODULE -#include "arena.h" - -/* modules include */ -#include "score.h" - -/* items include */ -#include - -/* kernel includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* util include */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* libc include */ -#include -#include -#include -#include - -/* exports: */ -plane *arena = NULL; - -/* local vars */ -#define CENTRAL_VOLCANO 1 - -static region *tower_region[6]; -static region *start_region[6]; - -static region *arena_region(int school) -{ - return tower_region[school]; -} - -static building *arena_tower(int school) -{ - return arena_region(school)->buildings; -} - -static int leave_fail(unit * u) -{ - ADDMSG(&u->faction->msgs, msg_message("arena_leave_fail", "unit", u)); - return 1; -} - -static int -leave_arena(struct unit *u, const struct item_type *itype, int amount, -order * ord) -{ - if (!u->building && leave_fail(u)) { - return -1; - } - if (u->building != arena_tower(u->faction->magiegebiet) && leave_fail(u)) { - return -1; - } - UNUSED_ARG(amount); - UNUSED_ARG(ord); - UNUSED_ARG(itype); - assert(!"not implemented"); - return 0; -} - -static int enter_fail(unit * u) -{ - ADDMSG(&u->faction->msgs, msg_message("arena_enter_fail", "region unit", - u->region, u)); - return 1; -} - -static int -enter_arena(unit * u, const item_type * itype, int amount, order * ord) -{ - skill_t sk; - region *r = u->region; - unit *u2; - int fee = 2000; - UNUSED_ARG(ord); - UNUSED_ARG(amount); - UNUSED_ARG(itype); - if (u->faction->score > fee * 5) { - score_t score = u->faction->score / 5; - if (score < INT_MAX) { - fee = (int)score; - } - else { - fee = INT_MAX; - } - } - if (getplane(r) == arena) - return -1; - if (u->number != 1 && enter_fail(u)) - return -1; - if (get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, fee) < fee - && enter_fail(u)) - return -1; - for (sk = 0; sk != MAXSKILLS; ++sk) { - if (get_level(u, sk) > 1 && enter_fail(u)) - return -1; - } - for (u2 = r->units; u2; u2 = u2->next) - if (u2->faction == u->faction) - break; - - assert(!"not implemented"); - /* - for (res=0;res!=MAXRESOURCES;++res) if (res!=R_SILVER && res!=R_ARENA_GATE && (is_item(res) || is_herb(res) || is_potion(res))) { - int x = get_resource(u, res); - if (x) { - if (u2) { - change_resource(u2, res, x); - change_resource(u, res, -x); - } - else if (enter_fail(u)) return -1; - } - } - */ - if (get_money(u) > fee) { - if (u2) - change_money(u2, get_money(u) - fee); - else if (enter_fail(u)) - return -1; - } - ADDMSG(&u->faction->msgs, msg_message("arena_enter_fail", "region unit", - u->region, u)); - use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE, 1); - use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, fee); - set_money(u, 109); - fset(u, UFL_ANON_FACTION); - move_unit(u, start_region[rng_int() % 6], NULL); - return 0; -} -#ifdef CENTRAL_VOLCANO - -static int caldera_handle(trigger * t, void *data) -{ - /* call an event handler on caldera. - * data.v -> ( variant event, int timer ) - */ - building *b = (building *)t->data.v; - if (b != NULL) { - unit **up = &b->region->units; - while (*up) { - unit *u = *up; - if (u->building == b) { - message *msg; - if (u->items) { - item **ip = &u->items; - msg = msg_message("caldera_handle_1", "unit items", u, u->items); - while (*ip) { - item *i = *ip; - i_remove(ip, i); - if (*ip == i) - ip = &i->next; - } - } - else { - msg = msg_message("caldera_handle_0", "unit", u); - } - add_message(&u->region->msgs, msg); - set_number(u, 0); - } - if (*up == u) - up = &u->next; - } - } - else { - log_error("could not perform caldera::handle()\n"); - } - UNUSED_ARG(data); - return 0; -} - -static void caldera_write(const trigger * t, struct storage *store) -{ - building *b = (building *)t->data.v; - write_building_reference(b, store); -} - -static int caldera_read(trigger * t, struct gamedata *data) -{ - int rb = - read_reference(&t->data.v, data, read_building_reference, - resolve_building); - if (rb == 0 && !t->data.v) { - return AT_READ_FAIL; - } - return AT_READ_OK; -} - -struct trigger_type tt_caldera = { - "caldera", - NULL, - NULL, - caldera_handle, - caldera_write, - caldera_read -}; - -#endif - -void register_arena(void) -{ - at_deprecate("hurting", a_readint); - register_function((pf_generic)enter_arena, "enter_arena"); - register_function((pf_generic)leave_arena, "leave_arena"); - tt_register(&tt_caldera); -} - -#endif /* def ARENA_MODULE */ diff --git a/src/modules/arena.h b/src/modules/arena.h deleted file mode 100644 index 64bfc7e87..000000000 --- a/src/modules/arena.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (c) 1998-2015, Enno Rehling -Katja Zedel - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -**/ - -#ifndef ARENA_H -#define ARENA_H -#ifdef __cplusplus -extern "C" { -#endif - -#if ARENA_MODULE == 0 -#error "must define ARENA_MODULE to use this module" -#endif - /* exports: */ - extern struct plane *arena; - - extern void register_arena(void); -#ifdef ARENA_CREATION - extern void create_arena(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/settings.h b/src/settings.h index b77e4687a..e7ec39305 100644 --- a/src/settings.h +++ b/src/settings.h @@ -31,7 +31,6 @@ * or both. We don't want separate binaries for different games */ #define MUSEUM_MODULE 1 -#define ARENA_MODULE 1 #undef REGIONOWNERS /* (WIP) region-owner uses HELP_TRAVEL to control entry to region */ From 1b93c148065a6353eb648a0223f778a69cf09517 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 18:50:48 +0100 Subject: [PATCH 028/218] Test E2 items in E2 only. Remove eye of demon (broken item). --- res/core/common/items.xml | 16 +----- res/core/de/strings.xml | 6 -- res/core/en/strings.xml | 6 -- res/core/fr/strings.xml | 6 -- res/eressea/items.xml | 4 ++ res/eressea/strings.xml | 11 +++- scripts/tests/e2/init.lua | 1 + scripts/tests/e2/items.lua | 109 +++++++++++++++++++++++++++++++++++ scripts/tests/e3/init.lua | 1 + scripts/tests/items.lua | 115 ++++++++----------------------------- src/items.c | 33 +++++++++-- src/items/CMakeLists.txt | 1 - src/items/demonseye.c | 65 --------------------- src/items/demonseye.h | 30 ---------- src/kernel/item.c | 29 ---------- src/modules/gmcmd.c | 1 - 16 files changed, 180 insertions(+), 254 deletions(-) create mode 100644 scripts/tests/e2/items.lua delete mode 100644 src/items/demonseye.c delete mode 100644 src/items/demonseye.h diff --git a/res/core/common/items.xml b/res/core/common/items.xml index 63a07d88f..0e1505205 100644 --- a/res/core/common/items.xml +++ b/res/core/common/items.xml @@ -61,14 +61,8 @@ - - - - - - - + @@ -105,16 +99,12 @@ - - - + - - - + diff --git a/res/core/de/strings.xml b/res/core/de/strings.xml index 26e8cc862..46d5605b1 100644 --- a/res/core/de/strings.xml +++ b/res/core/de/strings.xml @@ -1458,12 +1458,6 @@ Amulette des wahren Sehens - - Katzenamulett - - - Katzenamulette - Ring der Unsichtbarkeit diff --git a/res/core/en/strings.xml b/res/core/en/strings.xml index 063194c5d..14b2b817d 100644 --- a/res/core/en/strings.xml +++ b/res/core/en/strings.xml @@ -444,12 +444,6 @@ amulets of chastity - - amulet of the kitten - - - amulets of the kitten - amulet of darkness diff --git a/res/core/fr/strings.xml b/res/core/fr/strings.xml index c69bb5b75..13e6beb25 100644 --- a/res/core/fr/strings.xml +++ b/res/core/fr/strings.xml @@ -458,12 +458,6 @@ amulettes de chasteté - - amulette du chaton - - - amulettes du chaton - amulette de ténčbres diff --git a/res/eressea/items.xml b/res/eressea/items.xml index 007f0277c..a785691fe 100644 --- a/res/eressea/items.xml +++ b/res/eressea/items.xml @@ -86,6 +86,10 @@ + + + + diff --git a/res/eressea/strings.xml b/res/eressea/strings.xml index 4869014c5..8afeabbca 100644 --- a/res/eressea/strings.xml +++ b/res/eressea/strings.xml @@ -392,5 +392,14 @@ Adamantiumrüstungen adamantium plates - + + Katzenamulett + amulet of the kitten + amulette du chaton + + + amulets of the kitten + Katzenamulette + amulettes du chaton + diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index 4d916d1a9..5f81933d7 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -8,6 +8,7 @@ require 'tests.e2.destroy' require 'tests.e2.guard' require 'tests.e2.spells' require 'tests.e2.stealth' +require 'tests.e2.items' require 'tests.items' require 'tests.orders' require 'tests.common' diff --git a/scripts/tests/e2/items.lua b/scripts/tests/e2/items.lua new file mode 100644 index 000000000..da72bdbbc --- /dev/null +++ b/scripts/tests/e2/items.lua @@ -0,0 +1,109 @@ +require "lunit" + +module("tests.items", package.seeall, lunit.testcase ) + +function setup() + eressea.free_game() + eressea.settings.set("nmr.timeout", "0") + eressea.settings.set("rules.food.flags", "4") + eressea.settings.set("rules.ship.storms", "0") + eressea.settings.set("rules.encounters", "0") + eressea.settings.set("magic.regeneration.enable", "0") +end + +function test_meow() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("aoc", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Katzenamulett") + process_orders() + assert_equal(1, u:get_item("aoc")) + assert_equal(1, r:count_msg_type('meow')) +end + +function test_aurapotion50() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("aurapotion50", 1) + u:set_skill('magic', 10); + u.magic = 'gwyrrd' + u.aura = 0 + u:clear_orders() + u:add_order("BENUTZEN 1 Auratrank") + process_orders() + assert_equal(0, u:get_item("aurapotion50")) + assert_equal(1, f:count_msg_type('aurapotion50')) + assert_equal(50, u.aura) +end + +function test_bagpipe() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("bagpipeoffear", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Dudelsack") + process_orders() + assert_equal(1, u:get_item("bagpipeoffear")) + assert_equal(1, f:count_msg_type('bagpipeoffear_faction')) + assert_equal(1, r:count_msg_type('bagpipeoffear_region')) +end + +function test_speedsail() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u.ship = ship.create(r, "boat") + u:add_item("speedsail", 2) + u:clear_orders() + u:add_order("BENUTZEN 1 Sonnensegel") + process_orders() + assert_equal(1, u:get_item("speedsail")) + assert_equal(1, f:count_msg_type('use_speedsail')) +end + +function test_foolpotion() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("p7", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242") + process_orders() + assert_equal(1, u:get_item("p7")) + assert_equal(1, f:count_msg_type('feedback_unit_not_found')) + local u2 = unit.create(f, r, 1) + + u:clear_orders() + u:add_order("BENUTZEN 1 Dumpfbackenbrot " .. itoa36(u2.id)) + process_orders() + assert_equal(1, u:get_item("p7")) + assert_equal(1, f:count_msg_type('error64')) + + u:set_skill("stealth", 1); + process_orders() + assert_equal(0, u:get_item("p7")) + assert_equal(1, f:count_msg_type('givedumb')) +end + +function test_snowman() + local r = region.create(0, 0, "glacier") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("snowman", 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Schneemann") + process_orders() + for u2 in r.units do + if u2.id~=u.id then + assert_equal("snowman", u2.race) + assert_equal(1000, u2.hp) + u = nil + break + end + end + assert_equal(nil, u) +end diff --git a/scripts/tests/e3/init.lua b/scripts/tests/e3/init.lua index 4655fdcef..95df86c4c 100644 --- a/scripts/tests/e3/init.lua +++ b/scripts/tests/e3/init.lua @@ -6,6 +6,7 @@ require 'tests.e3.parser' require 'tests.e3.morale' require 'tests.orders' require 'tests.common' +require 'tests.items' -- require 'tests.report' require 'tests.magicbag' require 'tests.process' diff --git a/scripts/tests/items.lua b/scripts/tests/items.lua index 15d638a63..ff292b4cb 100644 --- a/scripts/tests/items.lua +++ b/scripts/tests/items.lua @@ -8,61 +8,35 @@ function setup() eressea.settings.set("rules.food.flags", "4") eressea.settings.set("rules.ship.storms", "0") eressea.settings.set("rules.encounters", "0") -end - -function test_meow() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("aoc", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Katzenamulett") - process_orders() - assert_equal(1, u:get_item("aoc")) - assert_equal(1, r:count_msg_type('meow')) -end - -function test_aurapotion50() eressea.settings.set("magic.regeneration.enable", "0") +end + +function test_dreameye() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) - u:add_item("aurapotion50", 1) - u:set_skill('magic', 10); - u.magic = 'gwyrrd' + u:add_item("dreameye", 2) + u:clear_orders() + u:add_order("BENUTZEN 1 Traumauge") + process_orders() + assert_equal(1, u:get_item("dreameye")) + assert_equal(1, f:count_msg_type('use_tacticcrystal')) +end + +function test_manacrystal() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("manacrystal", 2) + u:clear_orders() + u.magic = "gwyrrd" + u:set_skill('magic', 1) u.aura = 0 - u:clear_orders() - u:add_order("BENUTZEN 1 Auratrank") + u:add_order("BENUTZEN 1 Astralkristall") process_orders() - assert_equal(0, u:get_item("aurapotion50")) - assert_equal(1, f:count_msg_type('aurapotion50')) - assert_equal(50, u.aura) -end - -function test_bagpipe() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("bagpipeoffear", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Dudelsack") - process_orders() - assert_equal(1, u:get_item("bagpipeoffear")) - assert_equal(1, f:count_msg_type('bagpipeoffear_faction')) - assert_equal(1, r:count_msg_type('bagpipeoffear_region')) -end - -function test_speedsail() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u.ship = ship.create(r, "boat") - u:add_item("speedsail", 2) - u:clear_orders() - u:add_order("BENUTZEN 1 Sonnensegel") - process_orders() - assert_equal(1, u:get_item("speedsail")) - assert_equal(1, f:count_msg_type('use_speedsail')) + assert_equal(1, u:get_item("manacrystal")) + assert_equal(25, u.aura) + assert_equal(1, f:count_msg_type('manacrystal_use')) end function test_skillpotion() @@ -141,46 +115,3 @@ function test_bloodpotion_other() assert_equal(1, f:count_msg_type('usepotion')) assert_equal("smurf", u.race) end - -function test_foolpotion() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("p7", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242") - process_orders() - assert_equal(1, u:get_item("p7")) - assert_equal(1, f:count_msg_type('feedback_unit_not_found')) - local u2 = unit.create(f, r, 1) - - u:clear_orders() - u:add_order("BENUTZEN 1 Dumpfbackenbrot " .. itoa36(u2.id)) - process_orders() - assert_equal(1, u:get_item("p7")) - assert_equal(1, f:count_msg_type('error64')) - - u:set_skill("stealth", 1); - process_orders() - assert_equal(0, u:get_item("p7")) - assert_equal(1, f:count_msg_type('givedumb')) -end - -function test_snowman() - local r = region.create(0, 0, "glacier") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("snowman", 1) - u:clear_orders() - u:add_order("BENUTZEN 1 Schneemann") - process_orders() - for u2 in r.units do - if u2.id~=u.id then - assert_equal("snowman", u2.race) - assert_equal(1000, u2.hp) - u = nil - break - end - end - assert_equal(nil, u) -end diff --git a/src/items.c b/src/items.c index 197240d3e..ccba7ae7f 100644 --- a/src/items.c +++ b/src/items.c @@ -21,8 +21,6 @@ #include #include -#include - /* triggers includes */ #include #include @@ -340,11 +338,38 @@ struct order *ord) return 0; } +/* ------------------------------------------------------------- */ +/* Kann auch von Nichtmagier benutzt werden, modifiziert Taktik fuer diese +* Runde um -1 - 4 Punkte. */ +static int +use_tacticcrystal(unit * u, const struct item_type *itype, int amount, + struct order *ord) +{ + int i; + for (i = 0; i != amount; ++i) { + int duration = 1; /* wirkt nur eine Runde */ + curse *c; + float effect; + float power = 5; /* Widerstand gegen Antimagiesprueche, ist in diesem + Fall egal, da der curse fuer den Kampf gelten soll, + der vor den Antimagiezaubern passiert */ + + effect = (float)(rng_int() % 6 - 1); + c = create_curse(u, &u->attribs, ct_find("skillmod"), power, + duration, effect, u->number); + c->data.i = SK_TACTICS; + UNUSED_ARG(ord); + } + use_pooled(u, itype->rtype, GET_DEFAULT, amount); + ADDMSG(&u->faction->msgs, msg_message("use_tacticcrystal", + "unit region", u, u->region)); + return 0; +} + void register_itemfunctions(void) { - register_demonseye(); - /* have tests: */ + register_item_use(use_tacticcrystal, "use_dreameye"); register_item_use(use_studypotion, "use_studypotion"); register_item_use(use_antimagiccrystal, "use_antimagic"); register_item_use(use_speedsail, "use_speedsail"); diff --git a/src/items/CMakeLists.txt b/src/items/CMakeLists.txt index bbf192a66..37777f9e4 100644 --- a/src/items/CMakeLists.txt +++ b/src/items/CMakeLists.txt @@ -5,7 +5,6 @@ xerewards.test.c ) SET(_FILES -demonseye.c speedsail.c weapons.c xerewards.c diff --git a/src/items/demonseye.c b/src/items/demonseye.c deleted file mode 100644 index 563a16047..000000000 --- a/src/items/demonseye.c +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright (c) 1998-2015, Enno Rehling -Katja Zedel - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -**/ - -#include -#include "demonseye.h" - -/* kernel includes */ -#include -#include -#include -#include -#include -#include - -/* util includes */ -#include - -/* libc includes */ -#include - -static int -summon_igjarjuk(struct unit *u, const struct item_type *itype, int amount, -struct order *ord) -{ - struct plane *p = rplane(u->region); - UNUSED_ARG(amount); - UNUSED_ARG(itype); - if (p != NULL) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "use_realworld_only", "")); - return EUNUSABLE; - } - else { - assert(!"not implemented"); - return EUNUSABLE; - } -} - -static int -give_igjarjuk(struct unit *src, struct unit *d, const struct item_type *itype, -int n, struct order *ord) -{ - ADDMSG(&src->faction->msgs, msg_feedback(src, ord, "error_giveeye", "")); - return 0; -} - -void register_demonseye(void) -{ - register_item_use(summon_igjarjuk, "useigjarjuk"); - register_item_give(give_igjarjuk, "giveigjarjuk"); -} diff --git a/src/items/demonseye.h b/src/items/demonseye.h deleted file mode 100644 index 8d878a174..000000000 --- a/src/items/demonseye.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright (c) 1998-2015, Enno Rehling -Katja Zedel - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -**/ - -#ifndef H_ITM_DEMONSEYE -#define H_ITM_DEMONSEYE -#ifdef __cplusplus -extern "C" { -#endif - - void register_demonseye(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/kernel/item.c b/src/kernel/item.c index ecad829ca..adfddf6f4 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -677,34 +677,6 @@ int set_item(unit * u, const item_type *itype, int value) #define FL_ITEM_ANIMAL (1<<3) /* ist ein Tier */ #define FL_ITEM_MOUNT ((1<<4) | FL_ITEM_ANIMAL) /* ist ein Reittier */ -/* ------------------------------------------------------------- */ -/* Kann auch von Nichtmagier benutzt werden, modifiziert Taktik fuer diese - * Runde um -1 - 4 Punkte. */ -static int -use_tacticcrystal(unit * u, const struct item_type *itype, int amount, -struct order *ord) -{ - int i; - for (i = 0; i != amount; ++i) { - int duration = 1; /* wirkt nur eine Runde */ - curse *c; - float effect; - float power = 5; /* Widerstand gegen Antimagiesprueche, ist in diesem - Fall egal, da der curse fuer den Kampf gelten soll, - der vor den Antimagiezaubern passiert */ - - effect = (float)(rng_int() % 6 - 1); - c = create_curse(u, &u->attribs, ct_find("skillmod"), power, - duration, effect, u->number); - c->data.i = SK_TACTICS; - UNUSED_ARG(ord); - } - use_pooled(u, itype->rtype, GET_DEFAULT, amount); - ADDMSG(&u->faction->msgs, msg_message("use_tacticcrystal", - "unit region", u, u->region)); - return 0; -} - typedef struct t_item { const char *name; /* [0]: Einzahl fuer eigene; [1]: Mehrzahl fuer eigene; @@ -1165,7 +1137,6 @@ void register_resources(void) register_item_use(use_potion_delayed, "use_p2"); register_item_use(use_warmthpotion, "use_nestwarmth"); - register_item_use(use_tacticcrystal, "use_tacticcrystal"); register_item_use(use_mistletoe, "usemistletoe"); register_item_use(use_magicboost, "usemagicboost"); register_item_use(use_snowball, "usesnowball"); diff --git a/src/modules/gmcmd.c b/src/modules/gmcmd.c index 9a4e7ac47..c911e3de4 100644 --- a/src/modules/gmcmd.c +++ b/src/modules/gmcmd.c @@ -16,7 +16,6 @@ #include /* misc includes */ -#include #include #include From 9d09574d5e10c8ec30e6ae8c564030e872ba0e20 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 19:35:14 +0100 Subject: [PATCH 029/218] enable process_orders to be done in steps. by checking before turn_end(), we can sense temporary attributes and curses on a unit before they age away. --- res/core/common/items.xml | 10 +++---- res/eressea/artrewards.xml | 8 ++---- scripts/tests/e2/items.lua | 18 ++++++++----- scripts/tests/items.lua | 27 +++++++++++++++++-- src/bind_unit.c | 19 ++++++++++++++ src/bindings.c | 53 +++++++++++++++----------------------- src/items.c | 27 ++++++++++++++++++- src/kernel/item.c | 24 ----------------- src/laws.c | 49 +++++++++++++++++++++++++++++++++-- src/laws.h | 4 ++- src/util/attrib.c | 16 +++++++++--- src/util/attrib.h | 18 ++++++------- 12 files changed, 180 insertions(+), 93 deletions(-) diff --git a/res/core/common/items.xml b/res/core/common/items.xml index 0e1505205..8f2bbabf8 100644 --- a/res/core/common/items.xml +++ b/res/core/common/items.xml @@ -110,20 +110,16 @@ - - - + - - - + - + diff --git a/res/eressea/artrewards.xml b/res/eressea/artrewards.xml index 2a3c09950..b18fd5b20 100644 --- a/res/eressea/artrewards.xml +++ b/res/eressea/artrewards.xml @@ -3,16 +3,12 @@ - - - + - - - + diff --git a/scripts/tests/e2/items.lua b/scripts/tests/e2/items.lua index da72bdbbc..9bc747650 100644 --- a/scripts/tests/e2/items.lua +++ b/scripts/tests/e2/items.lua @@ -1,6 +1,6 @@ require "lunit" -module("tests.items", package.seeall, lunit.testcase ) +module("tests.e2.items", package.seeall, lunit.testcase ) function setup() eressea.free_game() @@ -18,9 +18,11 @@ function test_meow() u:add_item("aoc", 1) u:clear_orders() u:add_order("BENUTZEN 1 Katzenamulett") - process_orders() + turn_begin() + turn_process() assert_equal(1, u:get_item("aoc")) assert_equal(1, r:count_msg_type('meow')) + turn_end() end function test_aurapotion50() @@ -33,10 +35,12 @@ function test_aurapotion50() u.aura = 0 u:clear_orders() u:add_order("BENUTZEN 1 Auratrank") - process_orders() + turn_begin() + turn_process() assert_equal(0, u:get_item("aurapotion50")) assert_equal(1, f:count_msg_type('aurapotion50')) assert_equal(50, u.aura) + turn_end() end function test_bagpipe() @@ -69,24 +73,26 @@ function test_foolpotion() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + turn_begin() u:add_item("p7", 1) u:clear_orders() u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242") - process_orders() + turn_process() assert_equal(1, u:get_item("p7")) assert_equal(1, f:count_msg_type('feedback_unit_not_found')) local u2 = unit.create(f, r, 1) u:clear_orders() u:add_order("BENUTZEN 1 Dumpfbackenbrot " .. itoa36(u2.id)) - process_orders() + turn_process() assert_equal(1, u:get_item("p7")) assert_equal(1, f:count_msg_type('error64')) u:set_skill("stealth", 1); - process_orders() + turn_process() assert_equal(0, u:get_item("p7")) assert_equal(1, f:count_msg_type('givedumb')) + turn_end() end function test_snowman() diff --git a/scripts/tests/items.lua b/scripts/tests/items.lua index ff292b4cb..48f466409 100644 --- a/scripts/tests/items.lua +++ b/scripts/tests/items.lua @@ -11,6 +11,22 @@ function setup() eressea.settings.set("magic.regeneration.enable", "0") end +function test_mistletoe() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item('mistletoe', 2) + u:clear_orders() + u:add_order("BENUTZEN 1 Mistelzweig") + process_orders() + assert_equal(1, u:get_item('mistletoe')) + assert_equal(1, f:count_msg_type('use_item')) + u.number = 2 + process_orders() + assert_equal(1, u:get_item('mistletoe')) + assert_equal(1, f:count_msg_type('use_singleperson')) +end + function test_dreameye() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") @@ -18,9 +34,14 @@ function test_dreameye() u:add_item("dreameye", 2) u:clear_orders() u:add_order("BENUTZEN 1 Traumauge") - process_orders() + assert_false(u:is_cursed('skillmod')) + turn_begin() + turn_process() + assert_true(u:is_cursed('skillmod')) assert_equal(1, u:get_item("dreameye")) assert_equal(1, f:count_msg_type('use_tacticcrystal')) + turn_end() + assert_false(u:is_cursed('skillmod')) end function test_manacrystal() @@ -33,10 +54,12 @@ function test_manacrystal() u:set_skill('magic', 1) u.aura = 0 u:add_order("BENUTZEN 1 Astralkristall") - process_orders() + turn_begin() + turn_process() assert_equal(1, u:get_item("manacrystal")) assert_equal(25, u.aura) assert_equal(1, f:count_msg_type('manacrystal_use')) + turn_end() end function test_skillpotion() diff --git a/src/bind_unit.c b/src/bind_unit.c index c8ac2b362..0358e1938 100755 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -26,6 +26,7 @@ without prior permission by the authors of Eressea. /* kernel includes */ #include #include +#include #include #include #include @@ -770,6 +771,21 @@ static int tolua_unit_get_orders(lua_State * L) return 1; } +static int tolua_unit_is_cursed(lua_State *L) { + unit *self = (unit *)tolua_tousertype(L, 1, 0); + const char *name = tolua_tostring(L, 2, 0); + lua_pushboolean(L, self->attribs && curse_active(get_curse(self->attribs, ct_find(name)))); + return 1; +} + +static int tolua_unit_has_attrib(lua_State *L) { + unit *self = (unit *)tolua_tousertype(L, 1, 0); + const char *name = tolua_tostring(L, 2, 0); + attrib * a = a_find(self->attribs, at_find(name)); + lua_pushboolean(L, a != NULL); + return 1; +} + static int tolua_unit_get_flag(lua_State * L) { unit *self = (unit *)tolua_tousertype(L, 1, 0); @@ -956,6 +972,9 @@ void tolua_unit_open(lua_State * L) tolua_function(L, TOLUA_CAST "clear_orders", &tolua_unit_clear_orders); tolua_variable(L, TOLUA_CAST "orders", &tolua_unit_get_orders, 0); + tolua_function(L, TOLUA_CAST "is_cursed", &tolua_unit_is_cursed); + tolua_function(L, TOLUA_CAST "has_attrib", &tolua_unit_has_attrib); + /* key-attributes for named flags: */ tolua_function(L, TOLUA_CAST "set_flag", &tolua_unit_set_flag); tolua_function(L, TOLUA_CAST "get_flag", &tolua_unit_get_flag); diff --git a/src/bindings.c b/src/bindings.c index 18261a507..1d6270b35 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -480,44 +480,30 @@ static int tolua_write_reports(lua_State * L) return 1; } -static void reset_game(void) -{ - region *r; - faction *f; - for (r = regions; r; r = r->next) { - unit *u; - building *b; - r->flags &= RF_SAVEMASK; - for (u = r->units; u; u = u->next) { - u->flags &= UFL_SAVEMASK; - } - for (b = r->buildings; b; b = b->next) { - b->flags &= BLD_SAVEMASK; - } - if (r->land && r->land->ownership && r->land->ownership->owner) { - faction *owner = r->land->ownership->owner; - if (owner == get_monsters()) { - /* some compat-fix, i believe. */ - owner = update_owners(r); - } - if (owner) { - fset(r, RF_GUARDED); - } - } - } - for (f = factions; f; f = f->next) { - f->flags &= FFL_SAVEMASK; - } -} - static int tolua_process_orders(lua_State * L) { - ++turn; - reset_game(); processorders(); return 0; } +static int tolua_turn_begin(lua_State * L) +{ + turn_begin(); + return 0; +} + +static int tolua_turn_process(lua_State * L) +{ + turn_process(); + return 0; +} + +static int tolua_turn_end(lua_State * L) +{ + turn_end(); + return 0; +} + static int tolua_write_passwords(lua_State * L) { int result = writepasswd(); @@ -1063,6 +1049,9 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile) tolua_function(L, TOLUA_CAST "factions", tolua_get_factions); tolua_function(L, TOLUA_CAST "regions", tolua_get_regions); tolua_function(L, TOLUA_CAST "read_turn", tolua_read_turn); + tolua_function(L, TOLUA_CAST "turn_begin", tolua_turn_begin); + tolua_function(L, TOLUA_CAST "turn_process", tolua_turn_process); + tolua_function(L, TOLUA_CAST "turn_end", tolua_turn_end); tolua_function(L, TOLUA_CAST "process_orders", tolua_process_orders); tolua_function(L, TOLUA_CAST "init_reports", tolua_init_reports); tolua_function(L, TOLUA_CAST "write_reports", tolua_write_reports); diff --git a/src/items.c b/src/items.c index ccba7ae7f..192bb111d 100644 --- a/src/items.c +++ b/src/items.c @@ -21,6 +21,8 @@ #include #include +#include + /* triggers includes */ #include #include @@ -347,7 +349,7 @@ use_tacticcrystal(unit * u, const struct item_type *itype, int amount, { int i; for (i = 0; i != amount; ++i) { - int duration = 1; /* wirkt nur eine Runde */ + int duration = 1; /* wirkt nur in dieser Runde */ curse *c; float effect; float power = 5; /* Widerstand gegen Antimagiesprueche, ist in diesem @@ -366,9 +368,32 @@ use_tacticcrystal(unit * u, const struct item_type *itype, int amount, return 0; } +static int +use_mistletoe(struct unit *user, const struct item_type *itype, int amount, + struct order *ord) +{ + int mtoes = + get_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, + user->number); + + if (user->number > mtoes) { + ADDMSG(&user->faction->msgs, msg_message("use_singleperson", + "unit item region command", user, itype->rtype, user->region, ord)); + return -1; + } + use_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, + user->number); + a_add(&user->attribs, make_fleechance((float)1.0)); + ADDMSG(&user->faction->msgs, + msg_message("use_item", "unit item", user, itype->rtype)); + + return 0; +} + void register_itemfunctions(void) { /* have tests: */ + register_item_use(use_mistletoe, "use_mistletoe"); register_item_use(use_tacticcrystal, "use_dreameye"); register_item_use(use_studypotion, "use_studypotion"); register_item_use(use_antimagiccrystal, "use_antimagic"); diff --git a/src/kernel/item.c b/src/kernel/item.c index adfddf6f4..1692ed706 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -746,29 +746,6 @@ static int use_warmthpotion(unit *u, const item_type *itype, return 0; } -#include -static int -use_mistletoe(struct unit *user, const struct item_type *itype, int amount, -struct order *ord) -{ - int mtoes = - get_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, - user->number); - - if (user->number > mtoes) { - ADDMSG(&user->faction->msgs, msg_message("use_singleperson", - "unit item region command", user, itype->rtype, user->region, ord)); - return -1; - } - use_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, - user->number); - a_add(&user->attribs, make_fleechance((float)1.0)); - ADDMSG(&user->faction->msgs, - msg_message("use_item", "unit item", user, itype->rtype)); - - return 0; -} - static int use_magicboost(struct unit *user, const struct item_type *itype, int amount, struct order *ord) @@ -1137,7 +1114,6 @@ void register_resources(void) register_item_use(use_potion_delayed, "use_p2"); register_item_use(use_warmthpotion, "use_nestwarmth"); - register_item_use(use_mistletoe, "usemistletoe"); register_item_use(use_magicboost, "usemagicboost"); register_item_use(use_snowball, "usesnowball"); diff --git a/src/laws.c b/src/laws.c index 0d0e53110..cc10baeb5 100644 --- a/src/laws.c +++ b/src/laws.c @@ -4186,16 +4186,54 @@ void init_processor(void) } } -void processorders(void) +static void reset_game(void) +{ + region *r; + faction *f; + for (r = regions; r; r = r->next) { + unit *u; + building *b; + r->flags &= RF_SAVEMASK; + for (u = r->units; u; u = u->next) { + u->flags &= UFL_SAVEMASK; + } + for (b = r->buildings; b; b = b->next) { + b->flags &= BLD_SAVEMASK; + } + if (r->land && r->land->ownership && r->land->ownership->owner) { + faction *owner = r->land->ownership->owner; + if (owner == get_monsters()) { + /* some compat-fix, i believe. */ + owner = update_owners(r); + } + if (owner) { + fset(r, RF_GUARDED); + } + } + } + for (f = factions; f; f = f->next) { + f->flags &= FFL_SAVEMASK; + } +} + +void turn_begin(void) +{ + ++turn; + reset_game(); +} + +void turn_process(void) { init_processor(); process(); - /*************************************************/ if (config_get_int("modules.markets", 0)) { do_markets(); } +} +void turn_end(void) +{ log_info(" - Attribute altern"); ageing(); remove_empty_units(); @@ -4210,6 +4248,13 @@ void processorders(void) update_spells(); } +void processorders(void) +{ + turn_begin(); + turn_process(); + turn_end(); +} + void update_subscriptions(void) { FILE *F; diff --git a/src/laws.h b/src/laws.h index f05c11ab4..090d2b978 100755 --- a/src/laws.h +++ b/src/laws.h @@ -53,8 +53,10 @@ extern "C" { int enter_building(struct unit *u, struct order *ord, int id, bool report); int enter_ship(struct unit *u, struct order *ord, int id, bool report); - /* eressea-specific. put somewhere else, please. */ void processorders(void); + void turn_begin(void); + void turn_process(void); + void turn_end(void); void new_units(void); void defaultorders(void); diff --git a/src/util/attrib.c b/src/util/attrib.c index fda143168..993f634d2 100644 --- a/src/util/attrib.c +++ b/src/util/attrib.c @@ -179,7 +179,17 @@ void at_register(attrib_type * at) at_hash[at->hashkey % MAXATHASH] = at; } -static attrib_type *at_find(unsigned int hk) +struct attrib_type *at_find(const char *name) { + attrib_type *find; + unsigned int hash = __at_hashkey(name); + find = at_hash[hash % MAXATHASH]; + while (find && hash != find->hashkey) { + find = find->nexthash; + } + return find; +} + +static attrib_type *at_find_key(unsigned int hk) { const char *translate[3][2] = { { "zielregion", "targetregion" }, /* remapping: from 'zielregion, heute targetregion */ @@ -193,7 +203,7 @@ static attrib_type *at_find(unsigned int hk) int i = 0; while (translate[i][0]) { if (__at_hashkey(translate[i][0]) == hk) - return at_find(__at_hashkey(translate[i][1])); + return at_find_key(__at_hashkey(translate[i][1])); ++i; } } @@ -408,7 +418,7 @@ void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamed static int a_read_i(gamedata *data, attrib ** attribs, void *owner, unsigned int key) { int retval = AT_READ_OK; int(*reader)(attrib *, void *, struct gamedata *) = 0; - attrib_type *at = at_find(key); + attrib_type *at = at_find_key(key); attrib * na = 0; if (at) { diff --git a/src/util/attrib.h b/src/util/attrib.h index 601a6f32a..6043a960f 100644 --- a/src/util/attrib.h +++ b/src/util/attrib.h @@ -65,19 +65,19 @@ extern "C" { unsigned int hashkey; } attrib_type; - extern void at_register(attrib_type * at); - extern void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamedata *)); + void at_register(attrib_type * at); + void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamedata *)); + struct attrib_type *at_find(const char *name); void write_attribs(struct storage *store, struct attrib *alist, const void *owner); int read_attribs(struct gamedata *store, struct attrib **alist, void *owner); - extern attrib *a_select(attrib * a, const void *data, - bool(*compare) (const attrib *, const void *)); - extern attrib *a_find(attrib * a, const attrib_type * at); - extern attrib *a_add(attrib ** pa, attrib * at); - extern int a_remove(attrib ** pa, attrib * at); - extern void a_removeall(attrib ** a, const attrib_type * at); - extern attrib *a_new(const attrib_type * at); + attrib *a_select(attrib * a, const void *data, bool(*compare) (const attrib *, const void *)); + attrib *a_find(attrib * a, const attrib_type * at); + attrib *a_add(attrib ** pa, attrib * at); + int a_remove(attrib ** pa, attrib * at); + void a_removeall(attrib ** a, const attrib_type * at); + attrib *a_new(const attrib_type * at); int a_age(attrib ** attribs, void *owner); int a_read_orig(struct gamedata *data, attrib ** attribs, void *owner); From 462d0118e30f13f4b9b936c32abd2b32977ea4c2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 20:16:50 +0100 Subject: [PATCH 030/218] better testing for some items. --- scripts/tests/e2/items.lua | 16 +++++++++++-- scripts/tests/items.lua | 45 ++++++++++++++++++++++++++++++------- src/attributes/attributes.c | 3 +++ src/attributes/fleechance.c | 5 ----- src/attributes/fleechance.h | 1 - src/bind_region.c | 24 ++++++++++++++++++++ src/bind_ship.c | 27 ++++++++++++++++++++++ src/bind_unit.c | 16 ++++++++----- src/items.c | 7 +++--- src/util/attrib.c | 16 +++++-------- 10 files changed, 125 insertions(+), 35 deletions(-) diff --git a/scripts/tests/e2/items.lua b/scripts/tests/e2/items.lua index 9bc747650..93c88790f 100644 --- a/scripts/tests/e2/items.lua +++ b/scripts/tests/e2/items.lua @@ -47,26 +47,38 @@ function test_bagpipe() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + turn_begin() u:add_item("bagpipeoffear", 1) u:clear_orders() u:add_order("BENUTZEN 1 Dudelsack") - process_orders() + assert_equal(nil, r:get_curse('depression')) + turn_process() + assert_equal(0, r:get_curse('depression')) assert_equal(1, u:get_item("bagpipeoffear")) assert_equal(1, f:count_msg_type('bagpipeoffear_faction')) assert_equal(1, r:count_msg_type('bagpipeoffear_region')) + turn_end() + -- duration is variable, but at least 4 + assert_equal(0, r:get_curse('depression')) end function test_speedsail() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + + turn_begin() u.ship = ship.create(r, "boat") u:add_item("speedsail", 2) u:clear_orders() u:add_order("BENUTZEN 1 Sonnensegel") - process_orders() + assert_equal(nil, u.ship:get_curse('shipspeed')) + turn_process() + assert_equal(1, u.ship:get_curse('shipspeed')) assert_equal(1, u:get_item("speedsail")) assert_equal(1, f:count_msg_type('use_speedsail')) + turn_end() + assert_equal(1, u.ship:get_curse('shipspeed')) -- effect stays forever end function test_foolpotion() diff --git a/scripts/tests/items.lua b/scripts/tests/items.lua index 48f466409..f82aa9e7b 100644 --- a/scripts/tests/items.lua +++ b/scripts/tests/items.lua @@ -11,20 +11,37 @@ function setup() eressea.settings.set("magic.regeneration.enable", "0") end -function test_mistletoe() +function test_mistletoe_okay() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + turn_begin() u:add_item('mistletoe', 2) u:clear_orders() u:add_order("BENUTZEN 1 Mistelzweig") - process_orders() + assert_false(u:has_attrib('fleechance')) + turn_process() + assert_true(u:has_attrib('fleechance')) assert_equal(1, u:get_item('mistletoe')) assert_equal(1, f:count_msg_type('use_item')) + turn_end() +end + +function test_mistletoe_fail() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + turn_begin() + u:add_item('mistletoe', 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Mistelzweig") + assert_false(u:has_attrib('fleechance')) u.number = 2 - process_orders() + turn_process() + assert_false(u:has_attrib('fleechance')) assert_equal(1, u:get_item('mistletoe')) assert_equal(1, f:count_msg_type('use_singleperson')) + turn_end() end function test_dreameye() @@ -34,14 +51,14 @@ function test_dreameye() u:add_item("dreameye", 2) u:clear_orders() u:add_order("BENUTZEN 1 Traumauge") - assert_false(u:is_cursed('skillmod')) + assert_nil(u:get_curse('skillmod')) turn_begin() turn_process() - assert_true(u:is_cursed('skillmod')) + assert_not_nil(u:get_curse('skillmod')) assert_equal(1, u:get_item("dreameye")) assert_equal(1, f:count_msg_type('use_tacticcrystal')) turn_end() - assert_false(u:is_cursed('skillmod')) + assert_equal(nil, u:get_curse('skillmod')) end function test_manacrystal() @@ -78,24 +95,36 @@ function test_studypotion() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + turn_begin() u:add_item("studypotion", 2) u:clear_orders() u:add_order("LERNE Unterhaltung") u:add_order("BENUTZEN 1 Lerntrank") - process_orders() + turn_process() + -- cannot sense the "learning" attribute, because study_cmd + -- removes it during processing :( assert_equal(1, u:get_item("studypotion")) + turn_end() end function test_antimagic() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + + turn_begin() u:add_item("antimagic", 2) u:clear_orders() u:add_order("BENUTZEN 1 Antimagiekristall") - process_orders() + assert_equal(nil, r:get_curse('antimagiczone')) + turn_process() + assert_equal(5, r:get_curse('antimagiczone')) assert_equal(1, r:count_msg_type('use_antimagiccrystal')) assert_equal(1, u:get_item("antimagic")) + turn_end() + assert_equal(5, r:get_curse('antimagiczone')) -- haelt zwei wochen + turn_end() -- hack: age the curse again + assert_equal(nil, r:get_curse('antimagiczone')) end function test_ointment() diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index ae6869df8..0fe42a92e 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -25,6 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* attributes includes */ #include "follow.h" +#include "fleechance.h" #include "hate.h" #include "iceberg.h" #include "key.h" @@ -58,6 +59,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include + attrib_type at_unitdissolve = { "unitdissolve", NULL, NULL, NULL, a_writechars, a_readchars }; @@ -92,6 +94,7 @@ void register_attributes(void) at_register(&at_woodcount); /* neue UNIT-Attribute */ + at_register(&at_fleechance); at_register(&at_siege); at_register(&at_effect); at_register(&at_private); diff --git a/src/attributes/fleechance.c b/src/attributes/fleechance.c index afba2d301..b8012fba5 100644 --- a/src/attributes/fleechance.c +++ b/src/attributes/fleechance.c @@ -38,8 +38,3 @@ attrib *make_fleechance(float fleechance) a->data.flt = fleechance; return a; } - -void init_fleechance(void) -{ - at_register(&at_fleechance); -} diff --git a/src/attributes/fleechance.h b/src/attributes/fleechance.h index b2f75671c..d5817b8b7 100644 --- a/src/attributes/fleechance.h +++ b/src/attributes/fleechance.h @@ -25,7 +25,6 @@ extern "C" { extern struct attrib_type at_fleechance; struct attrib *make_fleechance(float fleechance); - void init_fleechance(void); #ifdef __cplusplus } diff --git a/src/bind_region.c b/src/bind_region.c index 05c0e3842..fdab4a10f 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -19,6 +19,7 @@ without prior permission by the authors of Eressea. #include "chaos.h" #include +#include #include #include #include @@ -670,6 +671,27 @@ static int tolua_distance(lua_State * L) return 1; } +static int tolua_region_get_curse(lua_State *L) { + region *self = (region *)tolua_tousertype(L, 1, 0); + const char *name = tolua_tostring(L, 2, 0); + if (self->attribs) { + curse * c = get_curse(self->attribs, ct_find(name)); + if (c) { + lua_pushnumber(L, curse_geteffect(c)); + return 1; + } + } + return 0; +} + +static int tolua_region_has_attrib(lua_State *L) { + region *self = (region *)tolua_tousertype(L, 1, 0); + const char *name = tolua_tostring(L, 2, 0); + attrib * a = a_find(self->attribs, at_find(name)); + lua_pushboolean(L, a != NULL); + return 1; +} + void tolua_region_open(lua_State * L) { /* register user types */ @@ -691,6 +713,8 @@ void tolua_region_open(lua_State * L) tolua_function(L, TOLUA_CAST "count_msg_type", tolua_region_count_msg_type); + tolua_function(L, TOLUA_CAST "get_curse", &tolua_region_get_curse); + tolua_function(L, TOLUA_CAST "has_attrib", &tolua_region_has_attrib); /* flags */ tolua_variable(L, TOLUA_CAST "blocked", tolua_region_get_blocked, tolua_region_set_blocked); diff --git a/src/bind_ship.c b/src/bind_ship.c index 515fa8de3..c5e0735ed 100644 --- a/src/bind_ship.c +++ b/src/bind_ship.c @@ -16,11 +16,13 @@ without prior permission by the authors of Eressea. #include "move.h" +#include #include #include #include #include +#include #include #include @@ -198,6 +200,27 @@ static int tolua_ship_set_damage(lua_State * L) return 0; } +static int tolua_ship_get_curse(lua_State *L) { + ship *self = (ship *)tolua_tousertype(L, 1, 0); + const char *name = tolua_tostring(L, 2, 0); + if (self->attribs) { + curse * c = get_curse(self->attribs, ct_find(name)); + if (c) { + lua_pushnumber(L, curse_geteffect(c)); + return 1; + } + } + return 0; +} + +static int tolua_ship_has_attrib(lua_State *L) { + ship *self = (ship *)tolua_tousertype(L, 1, 0); + const char *name = tolua_tostring(L, 2, 0); + attrib * a = a_find(self->attribs, at_find(name)); + lua_pushboolean(L, a != NULL); + return 1; +} + void tolua_ship_open(lua_State * L) { /* register user types */ @@ -225,6 +248,10 @@ void tolua_ship_open(lua_State * L) tolua_variable(L, TOLUA_CAST "type", tolua_ship_get_type, 0); tolua_variable(L, TOLUA_CAST "damage", tolua_ship_get_damage, tolua_ship_set_damage); + + tolua_function(L, TOLUA_CAST "get_curse", &tolua_ship_get_curse); + tolua_function(L, TOLUA_CAST "has_attrib", &tolua_ship_has_attrib); + tolua_function(L, TOLUA_CAST "create", tolua_ship_create); } tolua_endmodule(L); diff --git a/src/bind_unit.c b/src/bind_unit.c index 0358e1938..8247e13d5 100755 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -771,17 +771,23 @@ static int tolua_unit_get_orders(lua_State * L) return 1; } -static int tolua_unit_is_cursed(lua_State *L) { +static int tolua_unit_get_curse(lua_State *L) { unit *self = (unit *)tolua_tousertype(L, 1, 0); const char *name = tolua_tostring(L, 2, 0); - lua_pushboolean(L, self->attribs && curse_active(get_curse(self->attribs, ct_find(name)))); - return 1; + if (self->attribs) { + curse * c = get_curse(self->attribs, ct_find(name)); + if (c) { + lua_pushnumber(L, curse_geteffect(c)); + return 1; + } + } + return 0; } static int tolua_unit_has_attrib(lua_State *L) { unit *self = (unit *)tolua_tousertype(L, 1, 0); const char *name = tolua_tostring(L, 2, 0); - attrib * a = a_find(self->attribs, at_find(name)); + attrib * a = self->attribs ? a_find(self->attribs, at_find(name)) : NULL; lua_pushboolean(L, a != NULL); return 1; } @@ -972,7 +978,7 @@ void tolua_unit_open(lua_State * L) tolua_function(L, TOLUA_CAST "clear_orders", &tolua_unit_clear_orders); tolua_variable(L, TOLUA_CAST "orders", &tolua_unit_get_orders, 0); - tolua_function(L, TOLUA_CAST "is_cursed", &tolua_unit_is_cursed); + tolua_function(L, TOLUA_CAST "get_curse", &tolua_unit_get_curse); tolua_function(L, TOLUA_CAST "has_attrib", &tolua_unit_has_attrib); /* key-attributes for named flags: */ diff --git a/src/items.c b/src/items.c index 192bb111d..f8739cb73 100644 --- a/src/items.c +++ b/src/items.c @@ -43,7 +43,7 @@ static int use_studypotion(struct unit *u, const struct item_type *itype, int amount, struct order *ord) { - if (init_order(u->thisorder) == K_STUDY) { + if (u->thisorder && init_order(u->thisorder) == K_STUDY) { char token[128]; skill_t sk = NOSKILL; skill *sv = 0; @@ -97,9 +97,8 @@ struct order *ord) } effect = SPEEDSAIL_EFFECT; - c = - create_curse(u, &sh->attribs, ct_find("shipspeedup"), 20, INT_MAX, effect, - 0); + c = create_curse(u, &sh->attribs, ct_find("shipspeedup"), 20, INT_MAX, + effect, 0); c_setflag(c, CURSE_NOAGE); ADDMSG(&u->faction->msgs, msg_message("use_speedsail", "unit speed", u, diff --git a/src/util/attrib.c b/src/util/attrib.c index 993f634d2..b3b9c0a6e 100644 --- a/src/util/attrib.c +++ b/src/util/attrib.c @@ -179,16 +179,6 @@ void at_register(attrib_type * at) at_hash[at->hashkey % MAXATHASH] = at; } -struct attrib_type *at_find(const char *name) { - attrib_type *find; - unsigned int hash = __at_hashkey(name); - find = at_hash[hash % MAXATHASH]; - while (find && hash != find->hashkey) { - find = find->nexthash; - } - return find; -} - static attrib_type *at_find_key(unsigned int hk) { const char *translate[3][2] = { @@ -210,6 +200,11 @@ static attrib_type *at_find_key(unsigned int hk) return find; } +struct attrib_type *at_find(const char *name) { + unsigned int hash = __at_hashkey(name); + return at_find_key(hash); +} + attrib *a_select(attrib * a, const void *data, bool(*compare) (const attrib *, const void *)) { @@ -220,6 +215,7 @@ attrib *a_select(attrib * a, const void *data, attrib *a_find(attrib * a, const attrib_type * at) { + assert(at); while (a && a->type != at) a = a->nexttype; return a; From 9e239c88f486218739d5052aafde7b2a43407e69 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 20:26:48 +0100 Subject: [PATCH 031/218] testing insect warmth potion --- scripts/tests/e2/items.lua | 32 ++++++++++++++++++++++++++++++++ scripts/tests/items.lua | 2 +- src/items.c | 21 +++++++++++++++++++++ src/kernel/item.c | 29 ----------------------------- 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/scripts/tests/e2/items.lua b/scripts/tests/e2/items.lua index 93c88790f..24f27f4b2 100644 --- a/scripts/tests/e2/items.lua +++ b/scripts/tests/e2/items.lua @@ -11,6 +11,38 @@ function setup() eressea.settings.set("magic.regeneration.enable", "0") end +function test_nestwarmth_insect() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "insect", "de") + local u = unit.create(f, r, 1) + local flags = u.flags + u:add_item("nestwarmth", 2) + u:clear_orders() + u:add_order("BENUTZEN 1 Nestwaerme") + turn_begin() + turn_process() + assert_equal(flags+64, u.flags) -- UFL_WARMTH + assert_equal(1, u:get_item("nestwarmth")) + assert_equal(1, f:count_msg_type('usepotion')) + turn_end() +end + +function test_nestwarmth_other() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + local flags = u.flags + u:add_item("nestwarmth", 2) + u:clear_orders() + u:add_order("BENUTZEN 1 Nestwaerme") + turn_begin() + turn_process() + assert_equal(flags, u.flags) -- nothing happens + assert_equal(2, u:get_item("nestwarmth")) + assert_equal(1, f:count_msg_type('error163')) + turn_end() +end + function test_meow() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") diff --git a/scripts/tests/items.lua b/scripts/tests/items.lua index f82aa9e7b..aad52c2b2 100644 --- a/scripts/tests/items.lua +++ b/scripts/tests/items.lua @@ -58,7 +58,7 @@ function test_dreameye() assert_equal(1, u:get_item("dreameye")) assert_equal(1, f:count_msg_type('use_tacticcrystal')) turn_end() - assert_equal(nil, u:get_curse('skillmod')) + assert_nil(u:get_curse('skillmod')) end function test_manacrystal() diff --git a/src/items.c b/src/items.c index f8739cb73..51a4b2970 100644 --- a/src/items.c +++ b/src/items.c @@ -389,6 +389,26 @@ use_mistletoe(struct unit *user, const struct item_type *itype, int amount, return 0; } +static int use_warmthpotion(unit *u, const item_type *itype, + int amount, struct order *ord) +{ + if (u->faction->race == get_race(RC_INSECT)) { + u->flags |= UFL_WARMTH; + } + else { + /* nur fuer insekten: */ + cmistake(u, ord, 163, MSG_EVENT); + return ECUSTOM; + } + use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, + amount); + usetpotionuse(u, itype->rtype->ptype); + + ADDMSG(&u->faction->msgs, msg_message("usepotion", + "unit potion", u, itype->rtype)); + return 0; +} + void register_itemfunctions(void) { /* have tests: */ @@ -403,4 +423,5 @@ void register_itemfunctions(void) register_item_use(use_foolpotion, "use_p7"); register_item_use(use_bloodpotion, "use_peasantblood"); register_item_use(use_healingpotion, "use_ointment"); + register_item_use(use_warmthpotion, "use_nestwarmth"); } diff --git a/src/kernel/item.c b/src/kernel/item.c index 1692ed706..8d5224d79 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -726,26 +726,6 @@ struct order *), const char *name) register_function((pf_generic)foo, name); } -static int use_warmthpotion(unit *u, const item_type *itype, - int amount, struct order *ord) -{ - if (u->faction->race == get_race(RC_INSECT)) { - fset(u, UFL_WARMTH); - } - else { - /* nur fuer insekten: */ - cmistake(u, ord, 163, MSG_EVENT); - return ECUSTOM; - } - use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, - amount); - usetpotionuse(u, itype->rtype->ptype); - - ADDMSG(&u->faction->msgs, msg_message("usepotion", - "unit potion", u, itype->rtype)); - return 0; -} - static int use_magicboost(struct unit *user, const struct item_type *itype, int amount, struct order *ord) @@ -775,13 +755,6 @@ struct order *ord) return 0; } -static int -use_snowball(struct unit *user, const struct item_type *itype, int amount, -struct order *ord) -{ - return 0; -} - static void init_oldpotions(void) { const char *potionnames[MAX_POTIONS] = { @@ -1113,9 +1086,7 @@ void register_resources(void) register_function((pf_generic)res_changeaura, "changeaura"); register_item_use(use_potion_delayed, "use_p2"); - register_item_use(use_warmthpotion, "use_nestwarmth"); register_item_use(use_magicboost, "usemagicboost"); - register_item_use(use_snowball, "usesnowball"); register_item_give(give_horses, "givehorses"); } From 49d8a03eca1e5752fc9c7546e53a8b9376653d75 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 20:41:05 +0100 Subject: [PATCH 032/218] remote the item_type.use funpointer. --- res/eressea/items.xml | 16 ++++------------ src/helpers.c | 3 --- src/kernel/item.h | 4 ---- src/kernel/xmlreader.c | 7 ------- src/modules/museum.c | 5 +++-- 5 files changed, 7 insertions(+), 28 deletions(-) diff --git a/res/eressea/items.xml b/res/eressea/items.xml index a785691fe..3f5cc3d17 100644 --- a/res/eressea/items.xml +++ b/res/eressea/items.xml @@ -54,30 +54,22 @@ - - - + - - - + - - - + - - - + diff --git a/src/helpers.c b/src/helpers.c index 5124ca0ae..e8e6521c4 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -529,9 +529,6 @@ use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord) } else { log_error("no such callout: %s", fname); } - if (itype->use) { - return itype->use(u, itype, amount, ord); - } log_error("use(%s) calling '%s': not a function.\n", unitname(u), fname); lua_pop(L, 1); diff --git a/src/kernel/item.h b/src/kernel/item.h index b0bc10cd8..14196ab37 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -126,8 +126,6 @@ extern "C" { /* --- functions --- */ bool(*canuse) (const struct unit * user, const struct item_type * itype); - int(*use) (struct unit * user, const struct item_type * itype, int amount, - struct order * ord); int(*give) (struct unit * src, struct unit * dest, const struct item_type * itm, int number, struct order * ord); int score; @@ -310,8 +308,6 @@ extern "C" { const struct item_type *, int, struct order *), const char *name); void register_item_use(int(*foo) (struct unit *, const struct item_type *, int, struct order *), const char *name); - void register_item_useonother(int(*foo) (struct unit *, int, - const struct item_type *, int, struct order *), const char *name); void free_resources(void); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 69e9c22d0..af0a9dd23 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -854,13 +854,6 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) (int(*)(struct unit *, struct unit *, const struct item_type *, int, struct order *))fun; } - else if (strcmp((const char *)propValue, "use") == 0) { - log_error("%s has a use function", rtype->_name); - itype->flags |= ITF_CANUSE; - itype->use = - (int(*)(struct unit *, const struct item_type *, int, - struct order *))fun; - } else if (strcmp((const char *)propValue, "canuse") == 0) { itype->canuse = (bool(*)(const struct unit *, const struct item_type *))fun; diff --git a/src/modules/museum.c b/src/modules/museum.c index af37019d0..1eee3529f 100644 --- a/src/modules/museum.c +++ b/src/modules/museum.c @@ -497,9 +497,10 @@ void register_museum(void) at_register(&at_museumgivebackcookie); at_register(&at_museumgiveback); - register_item_use(use_museumticket, "use_museumticket"); - register_item_use(use_museumkey, "use_museumkey"); register_item_use(use_museumexitticket, "use_museumexitticket"); + register_item_use(use_museumticket, "use_museumticket"); + register_item_use(use_museumkey, "use_questkey1"); + register_item_use(use_museumkey, "use_questkey2"); } #endif From 69e28034b458ad1afd34cb51e49ec088710a111a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 21:00:15 +0100 Subject: [PATCH 033/218] Kill unused "magicboost" function. I have no idea why this exists. --- src/items.c | 3 +++ src/kernel/item.c | 32 -------------------------------- 2 files changed, 3 insertions(+), 32 deletions(-) diff --git a/src/items.c b/src/items.c index 51a4b2970..78f6e3188 100644 --- a/src/items.c +++ b/src/items.c @@ -424,4 +424,7 @@ void register_itemfunctions(void) register_item_use(use_bloodpotion, "use_peasantblood"); register_item_use(use_healingpotion, "use_ointment"); register_item_use(use_warmthpotion, "use_nestwarmth"); + + /* ungetestet: Wasser des Lebens */ + register_item_use(use_potion_delayed, "use_p2"); } diff --git a/src/kernel/item.c b/src/kernel/item.c index 8d5224d79..6bd97e6dd 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -726,35 +726,6 @@ struct order *), const char *name) register_function((pf_generic)foo, name); } -static int -use_magicboost(struct unit *user, const struct item_type *itype, int amount, -struct order *ord) -{ - int mtoes = - get_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, - user->number); - faction *f = user->faction; - if (user->number > mtoes) { - ADDMSG(&user->faction->msgs, msg_message("use_singleperson", - "unit item region command", user, itype->rtype, user->region, ord)); - return -1; - } - if (!is_mage(user) || key_get(f->attribs, atoi36("mbst"))) { - cmistake(user, user->thisorder, 214, MSG_EVENT); - return -1; - } - use_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, - user->number); - - key_set(&f->attribs, atoi36("mbst"), turn); - set_level(user, SK_MAGIC, 3); - - ADDMSG(&user->faction->msgs, msg_message("use_item", - "unit item", user, itype->rtype)); - - return 0; -} - static void init_oldpotions(void) { const char *potionnames[MAX_POTIONS] = { @@ -1085,8 +1056,5 @@ void register_resources(void) register_function((pf_generic)res_changehp, "changehp"); register_function((pf_generic)res_changeaura, "changeaura"); - register_item_use(use_potion_delayed, "use_p2"); - register_item_use(use_magicboost, "usemagicboost"); - register_item_give(give_horses, "givehorses"); } From 75ce6fd23a4d965d3f531a1764bb866cf3598c43 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Feb 2017 03:48:41 +0100 Subject: [PATCH 034/218] regaura=1 is default --- clibs | 2 +- res/races/goblin-2.xml | 2 +- res/races/goblin-3.xml | 2 +- res/races/goblin.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clibs b/clibs index 27c8b3202..b91413316 160000 --- a/clibs +++ b/clibs @@ -1 +1 @@ -Subproject commit 27c8b3202b52766465743c3324fc0b52c5ba4b11 +Subproject commit b91413316ce13044c555084a9f605983586107b4 diff --git a/res/races/goblin-2.xml b/res/races/goblin-2.xml index f26fa780e..b092dfaaa 100644 --- a/res/races/goblin-2.xml +++ b/res/races/goblin-2.xml @@ -1,5 +1,5 @@ - - Date: Tue, 28 Feb 2017 04:03:36 +0100 Subject: [PATCH 035/218] remove unused files --- res/races.xml | 14 -------------- res/races/goblin-2.xml | 24 ------------------------ 2 files changed, 38 deletions(-) delete mode 100644 res/races.xml delete mode 100644 res/races/goblin-2.xml diff --git a/res/races.xml b/res/races.xml deleted file mode 100644 index fcfc1742b..000000000 --- a/res/races.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/res/races/goblin-2.xml b/res/races/goblin-2.xml deleted file mode 100644 index b092dfaaa..000000000 --- a/res/races/goblin-2.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - From 5a01eae522bf025b4a681aeb13033f2d4a0b8cbe Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Feb 2017 10:48:27 +0100 Subject: [PATCH 036/218] make item_use function crash if new and old rules do not agree add a 'test' function to E3 that exercises all those items --- scripts/tests/e3/init.lua | 1 + scripts/tests/e3/items.lua | 35 ++++++++++++++++++++++++ src/battle.c | 6 +++-- src/kernel/item.h | 2 ++ src/kernel/race.c | 13 +++++++++ src/kernel/race.h | 4 +++ src/kernel/race.test.c | 54 +++++++++++++++++++++++++++++++++++++- 7 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 scripts/tests/e3/items.lua diff --git a/scripts/tests/e3/init.lua b/scripts/tests/e3/init.lua index 95df86c4c..28a2cf6e5 100644 --- a/scripts/tests/e3/init.lua +++ b/scripts/tests/e3/init.lua @@ -4,6 +4,7 @@ require 'tests.e3.spells' require 'tests.e3.rules' require 'tests.e3.parser' require 'tests.e3.morale' +require 'tests.e3.items' require 'tests.orders' require 'tests.common' require 'tests.items' diff --git a/scripts/tests/e3/items.lua b/scripts/tests/e3/items.lua new file mode 100644 index 000000000..9c6035bf7 --- /dev/null +++ b/scripts/tests/e3/items.lua @@ -0,0 +1,35 @@ +require "lunit" + +module("tests.e3.items", package.seeall, lunit.testcase ) + +function setup() + eressea.game.reset() + eressea.settings.set("rules.food.flags", "4") -- food is free + eressea.settings.set("NewbieImmunity", "0") +end + +function test_goblins() + local r = region.create(0, 0, "plain") + assert(r) + local f1 = faction.create("goblin@eressea.de", "goblin", "de") + local f2 = faction.create("dwarf@eressea.de", "dwarf", "de") + local f3 = faction.create("elf@eressea.de", "elf", "de") + local u1 = unit.create(f1, r, 1) + local u2 = unit.create(f2, r, 1) + local u3 = unit.create(f3, r, 1) + + local restricted = { + "towershield", "rep_crossbow", "plate", "lance", + "mllornlance", "greatbow", "greataxe", "axe", "scale", + "plate", "rustyhalberd", "halberd", "greatsword" + } + for k, v in ipairs(restricted) do + u1:add_item(v, 1) + u2:add_item(v, 1) + u2:add_item(v, 1) + end + + u1:add_order("ATTACKIERE " .. itoa36(u2.id)) + u1:add_order("ATTACKIERE " .. itoa36(u3.id)) + process_orders() +end diff --git a/src/battle.c b/src/battle.c index 9864adc41..9e2958242 100644 --- a/src/battle.c +++ b/src/battle.c @@ -576,10 +576,12 @@ static weapon *select_weapon(const troop t, bool attacking, static bool i_canuse(const unit * u, const item_type * itype) { + bool result = true; if (itype->canuse) { - return itype->canuse(u, itype); + result = itype->canuse(u, itype); } - return true; + assert(result==rc_can_use(u_race(u), itype)); + return result; } static int diff --git a/src/kernel/item.h b/src/kernel/item.h index 14196ab37..d38a21340 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -121,6 +121,8 @@ extern "C" { unsigned int flags; int weight; int capacity; + int mask_allow; + int mask_deny; struct construction *construction; char *_appearance[2]; /* wie es f�r andere aussieht */ /* --- functions --- */ diff --git a/src/kernel/race.c b/src/kernel/race.c index d159fd6d8..efe38dcfe 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -54,6 +54,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* libc includes */ #include #include +#include #include #include #include @@ -94,6 +95,7 @@ enum { RCO_TRADEHERB }; + static void rc_setoption(race *rc, int k, const char *value) { unsigned char key = (unsigned char)k; int i; @@ -323,6 +325,17 @@ bool rc_changed(int *cache) { return false; } +bool rc_can_use(const struct race *rc, const struct item_type *itype) +{ + if (itype->mask_allow) { + return (rc->mask_item==0 || (itype->mask_allow & rc->mask_item) != 0); + } + if (itype->mask_deny) { + return (itype->mask_deny & rc->mask_item) == 0; + } + return true; +} + race *rc_create(const char *zName) { race *rc; diff --git a/src/kernel/race.h b/src/kernel/race.h index f14b8e54f..fcd78ae19 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -48,6 +48,7 @@ extern "C" { struct spellref; struct locale; struct rcoption; + struct item_type; extern int num_races; @@ -140,6 +141,7 @@ extern "C" { int flags; int battle_flags; int ec_flags; + int mask_item; struct att attack[RACE_ATTACKS]; signed char bonus[MAXSKILLS]; @@ -174,6 +176,8 @@ extern "C" { const race *rc_find(const char *); void free_races(void); + bool rc_can_use(const struct race *rc, const struct item_type *itype); + typedef enum name_t { NAME_SINGULAR, NAME_PLURAL, NAME_DEFINITIVE, NAME_CATEGORY } name_t; const char * rc_name_s(const race *rc, name_t n); const char * rc_name(const race *rc, name_t n, char *name, size_t size); diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index 07ecbdd45..b292a825e 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -1,10 +1,13 @@ #include #include #include "race.h" -#include +#include "item.h" + #include +#include #include +#include #include static void test_rc_name(CuTest *tc) { @@ -100,6 +103,54 @@ static void test_rc_set_param(CuTest *tc) { test_cleanup(); } +static void test_rc_can_use(CuTest *tc) { + race *rc; + item_type *itype; + + test_setup(); + rc = test_create_race("goblin"); + itype = test_create_itemtype("plate"); + CuAssertTrue(tc, rc_can_use(rc, itype)); + + /* default case. all items and races in E2 */ + itype->mask_deny = 0; + rc->mask_item = 0; + CuAssertTrue(tc, rc_can_use(rc, itype)); + + /* some race is forbidden from using this item. */ + itype->mask_deny = 1; + + /* we are not that race. */ + rc->mask_item = 2; + CuAssertTrue(tc, rc_can_use(rc, itype)); + + /* we are that race */ + rc->mask_item = 1; + CuAssertTrue(tc, ! rc_can_use(rc, itype)); + + /* we are not a special race at all */ + rc->mask_item = 0; + CuAssertTrue(tc, rc_can_use(rc, itype)); + + /* only one race is allowed to use this item */ + itype->mask_deny = 0; + itype->mask_allow = 1; + + /* we are not that race */ + rc->mask_item = 2; + CuAssertTrue(tc, ! rc_can_use(rc, itype)); + + /* we are that race */ + rc->mask_item = 1; + CuAssertTrue(tc, rc_can_use(rc, itype)); + + /* we are not special */ + rc->mask_item = 0; + CuAssertTrue(tc, rc_can_use(rc, itype)); + + test_cleanup(); +} + CuSuite *get_race_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -109,6 +160,7 @@ CuSuite *get_race_suite(void) SUITE_ADD_TEST(suite, test_rc_defaults); SUITE_ADD_TEST(suite, test_rc_find); SUITE_ADD_TEST(suite, test_rc_set_param); + SUITE_ADD_TEST(suite, test_rc_can_use); return suite; } From c276b5a43ca2e1471d9aa33d3451a30f42930342 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Feb 2017 10:58:09 +0100 Subject: [PATCH 037/218] generate error, not crash. todo: fix items --- scripts/tests/e3/items.lua | 2 +- src/battle.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/tests/e3/items.lua b/scripts/tests/e3/items.lua index 9c6035bf7..b2100f5ed 100644 --- a/scripts/tests/e3/items.lua +++ b/scripts/tests/e3/items.lua @@ -26,7 +26,7 @@ function test_goblins() for k, v in ipairs(restricted) do u1:add_item(v, 1) u2:add_item(v, 1) - u2:add_item(v, 1) + u3:add_item(v, 1) end u1:add_order("ATTACKIERE " .. itoa36(u2.id)) diff --git a/src/battle.c b/src/battle.c index 9e2958242..fa5725c50 100644 --- a/src/battle.c +++ b/src/battle.c @@ -580,7 +580,12 @@ static bool i_canuse(const unit * u, const item_type * itype) if (itype->canuse) { result = itype->canuse(u, itype); } - assert(result==rc_can_use(u_race(u), itype)); + if (result!=rc_can_use(u_race(u), itype)) { + log_error("conversion error: %s should be %s to use %s", + u->_race->_name, + result ? "allowed" : "forbidden", + itype->rtype->_name); + } return result; } From 2eb88c472cbf9cb40def53514c24b0cba5412a05 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Feb 2017 11:07:32 +0100 Subject: [PATCH 038/218] have I bollocksed up the deny/allow rules? looks like it --- res/e3a/armor/towershield.xml | 2 +- res/e3a/races.xml | 18 +++++++++++++++--- res/races/goblin-3.xml | 2 +- scripts/tests/e3/items.lua | 13 +++++++++---- src/kernel/xmlreader.c | 3 +++ 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/res/e3a/armor/towershield.xml b/res/e3a/armor/towershield.xml index e80c03523..dcd2858cf 100644 --- a/res/e3a/armor/towershield.xml +++ b/res/e3a/armor/towershield.xml @@ -1,6 +1,6 @@ - + diff --git a/res/e3a/races.xml b/res/e3a/races.xml index 2e5a81aee..fc16645c6 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -71,7 +71,11 @@ - + @@ -116,7 +120,11 @@ - + @@ -156,7 +164,11 @@ - + diff --git a/res/races/goblin-3.xml b/res/races/goblin-3.xml index a65d4c99a..8deb33f5e 100644 --- a/res/races/goblin-3.xml +++ b/res/races/goblin-3.xml @@ -3,7 +3,7 @@ recruitcost="60" maintenance="6" weight="600" capacity="440" speed="1.0" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" -getitem="yes" equipment="yes" healing="2.0"> +getitem="yes" equipment="yes" healing="2.0" items="4"> diff --git a/scripts/tests/e3/items.lua b/scripts/tests/e3/items.lua index b2100f5ed..5594eed67 100644 --- a/scripts/tests/e3/items.lua +++ b/scripts/tests/e3/items.lua @@ -14,7 +14,9 @@ function test_goblins() local f1 = faction.create("goblin@eressea.de", "goblin", "de") local f2 = faction.create("dwarf@eressea.de", "dwarf", "de") local f3 = faction.create("elf@eressea.de", "elf", "de") - local u1 = unit.create(f1, r, 1) + local ud = unit.create(f1, r, 1) + local uh = unit.create(f1, r, 1) + uh.race = "halfling" local u2 = unit.create(f2, r, 1) local u3 = unit.create(f3, r, 1) @@ -24,12 +26,15 @@ function test_goblins() "plate", "rustyhalberd", "halberd", "greatsword" } for k, v in ipairs(restricted) do - u1:add_item(v, 1) + ud:add_item(v, 1) + uh:add_item(v, 1) u2:add_item(v, 1) u3:add_item(v, 1) end - u1:add_order("ATTACKIERE " .. itoa36(u2.id)) - u1:add_order("ATTACKIERE " .. itoa36(u3.id)) + uh:add_order("ATTACKIERE " .. itoa36(u2.id)) + uh:add_order("ATTACKIERE " .. itoa36(u3.id)) + ud:add_order("ATTACKIERE " .. itoa36(u2.id)) + ud:add_order("ATTACKIERE " .. itoa36(u3.id)) process_orders() end diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index af0a9dd23..3a6ba6d81 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -782,6 +782,8 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) itype = rtype->itype ? rtype->itype : it_get_or_create(rtype); itype->weight = xml_ivalue(node, "weight", 0); itype->capacity = xml_ivalue(node, "capacity", 0); + itype->mask_allow = xml_ivalue(node, "allow", 0); + itype->mask_deny = xml_ivalue(node, "deny", 0); itype->flags |= flags; /* reading item/construction */ @@ -1575,6 +1577,7 @@ static int parse_races(xmlDocPtr doc) rc->speed = (float)xml_fvalue(node, "speed", rc->speed); rc->hitpoints = xml_ivalue(node, "hp", rc->hitpoints); rc->armor = (char)xml_ivalue(node, "ac", rc->armor); + rc->mask_item = (char)xml_ivalue(node, "items", rc->mask_item); study_speed_base = xml_ivalue(node, "studyspeed", 0); rc->at_default = (char)xml_ivalue(node, "unarmedattack", -2); From 6e8e16309989bbfc7251ca77e7c805de5e8c5d11 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Mar 2017 09:56:27 +0100 Subject: [PATCH 039/218] make item allow/deny XML easier to read, fix code --- res/core/weapons/greatbow.xml | 2 +- res/core/weapons/rep_crossbow.xml | 2 +- res/e3a/armor/plate.xml | 2 +- res/e3a/armor/scale.xml | 2 +- res/e3a/armor/towershield.xml | 2 +- res/e3a/races.xml | 6 +++--- res/e3a/weapons.xml | 4 ++-- res/e3a/weapons/greatbow.xml | 2 +- res/e3a/weapons/halberd.xml | 2 +- res/e3a/weapons/mallornlance.xml | 2 +- res/e3a/weapons/rustyhalberd.xml | 2 +- res/races/goblin-3.xml | 2 +- scripts/tests/e3/items.lua | 4 ++-- src/kernel/race.c | 2 +- src/kernel/race.test.c | 2 +- src/kernel/xmlreader.c | 26 +++++++++++++++++++++++--- 16 files changed, 42 insertions(+), 22 deletions(-) diff --git a/res/core/weapons/greatbow.xml b/res/core/weapons/greatbow.xml index 10b270e55..14734a129 100644 --- a/res/core/weapons/greatbow.xml +++ b/res/core/weapons/greatbow.xml @@ -1,6 +1,6 @@ - + diff --git a/res/core/weapons/rep_crossbow.xml b/res/core/weapons/rep_crossbow.xml index 66e3f9fc2..d6f869046 100644 --- a/res/core/weapons/rep_crossbow.xml +++ b/res/core/weapons/rep_crossbow.xml @@ -1,6 +1,6 @@ - + diff --git a/res/e3a/armor/plate.xml b/res/e3a/armor/plate.xml index 29cabbf1a..9aeafc3c1 100644 --- a/res/e3a/armor/plate.xml +++ b/res/e3a/armor/plate.xml @@ -1,6 +1,6 @@ - + diff --git a/res/e3a/armor/scale.xml b/res/e3a/armor/scale.xml index 7039b4008..691ce5ba7 100644 --- a/res/e3a/armor/scale.xml +++ b/res/e3a/armor/scale.xml @@ -1,6 +1,6 @@ - + diff --git a/res/e3a/armor/towershield.xml b/res/e3a/armor/towershield.xml index dcd2858cf..78e113e2a 100644 --- a/res/e3a/armor/towershield.xml +++ b/res/e3a/armor/towershield.xml @@ -1,6 +1,6 @@ - + diff --git a/res/e3a/races.xml b/res/e3a/races.xml index fc16645c6..8b0cfae6d 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -75,7 +75,7 @@ regaura="1.0" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" - giveunit="yes" getitem="yes" equipment="yes" items="8"> + giveunit="yes" getitem="yes" equipment="yes"> @@ -124,7 +124,7 @@ recruitcost="200" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" - giveunit="yes" getitem="yes" equipment="yes" items="2"> + giveunit="yes" getitem="yes" equipment="yes" > @@ -168,7 +168,7 @@ recruitcost="240" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" - giveunit="yes" getitem="yes" equipment="yes" items="1"> + giveunit="yes" getitem="yes" equipment="yes"> diff --git a/res/e3a/weapons.xml b/res/e3a/weapons.xml index 052266a02..96a987b28 100644 --- a/res/e3a/weapons.xml +++ b/res/e3a/weapons.xml @@ -1,9 +1,7 @@ - - @@ -13,6 +11,8 @@ + + diff --git a/res/e3a/weapons/greatbow.xml b/res/e3a/weapons/greatbow.xml index 7f08427c8..b488a011c 100644 --- a/res/e3a/weapons/greatbow.xml +++ b/res/e3a/weapons/greatbow.xml @@ -4,7 +4,7 @@ * has lower damage --> - + diff --git a/res/e3a/weapons/halberd.xml b/res/e3a/weapons/halberd.xml index 2c11b62fc..c07cbfd4d 100644 --- a/res/e3a/weapons/halberd.xml +++ b/res/e3a/weapons/halberd.xml @@ -3,7 +3,7 @@ 1. you cannt use this with cavalry --> - + diff --git a/res/e3a/weapons/mallornlance.xml b/res/e3a/weapons/mallornlance.xml index 1fcad08c8..d2aacaea7 100644 --- a/res/e3a/weapons/mallornlance.xml +++ b/res/e3a/weapons/mallornlance.xml @@ -1,6 +1,6 @@ - + diff --git a/res/e3a/weapons/rustyhalberd.xml b/res/e3a/weapons/rustyhalberd.xml index ed25d5db7..32c0d4497 100644 --- a/res/e3a/weapons/rustyhalberd.xml +++ b/res/e3a/weapons/rustyhalberd.xml @@ -3,7 +3,7 @@ 1. you cannot use this with cavalry --> - + diff --git a/res/races/goblin-3.xml b/res/races/goblin-3.xml index 8deb33f5e..a65d4c99a 100644 --- a/res/races/goblin-3.xml +++ b/res/races/goblin-3.xml @@ -3,7 +3,7 @@ recruitcost="60" maintenance="6" weight="600" capacity="440" speed="1.0" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" -getitem="yes" equipment="yes" healing="2.0" items="4"> +getitem="yes" equipment="yes" healing="2.0"> diff --git a/scripts/tests/e3/items.lua b/scripts/tests/e3/items.lua index 5594eed67..349e12b2a 100644 --- a/scripts/tests/e3/items.lua +++ b/scripts/tests/e3/items.lua @@ -22,8 +22,8 @@ function test_goblins() local restricted = { "towershield", "rep_crossbow", "plate", "lance", - "mllornlance", "greatbow", "greataxe", "axe", "scale", - "plate", "rustyhalberd", "halberd", "greatsword" + "mallornlance", "greatbow", "greataxe", "axe", "scale", + "plate", "halberd", "greatsword", "rustyhalberd" } for k, v in ipairs(restricted) do ud:add_item(v, 1) diff --git a/src/kernel/race.c b/src/kernel/race.c index efe38dcfe..8a8cc906e 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -328,7 +328,7 @@ bool rc_changed(int *cache) { bool rc_can_use(const struct race *rc, const struct item_type *itype) { if (itype->mask_allow) { - return (rc->mask_item==0 || (itype->mask_allow & rc->mask_item) != 0); + return (itype->mask_allow & rc->mask_item) != 0; } if (itype->mask_deny) { return (itype->mask_deny & rc->mask_item) == 0; diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index b292a825e..2db76a6fd 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -146,7 +146,7 @@ static void test_rc_can_use(CuTest *tc) { /* we are not special */ rc->mask_item = 0; - CuAssertTrue(tc, rc_can_use(rc, itype)); + CuAssertTrue(tc, ! rc_can_use(rc, itype)); test_cleanup(); } diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 3a6ba6d81..208a586a7 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -757,6 +757,27 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) return wtype; } +static int race_mask = 1; + +static void mask_races(xmlNodePtr node, const char *key, int *maskp) { + xmlChar *propValue = xmlGetProp(node, BAD_CAST key); + char *tok; + int mask = 0; + assert(maskp); + tok = strtok((char *)propValue, " ,"); + while (tok) { + race * rc = rc_get_or_create(tok); + if (!rc->mask_item) { + rc->mask_item = race_mask; + race_mask = race_mask << 1; + } + mask |= rc->mask_item; + tok = strtok(NULL, " ,"); + } + *maskp = mask; + xmlFree(propValue); +} + static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) { xmlNodePtr node = xpath->node; @@ -782,8 +803,8 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) itype = rtype->itype ? rtype->itype : it_get_or_create(rtype); itype->weight = xml_ivalue(node, "weight", 0); itype->capacity = xml_ivalue(node, "capacity", 0); - itype->mask_allow = xml_ivalue(node, "allow", 0); - itype->mask_deny = xml_ivalue(node, "deny", 0); + mask_races(node, "allow", &itype->mask_allow); + mask_races(node, "deny", &itype->mask_deny); itype->flags |= flags; /* reading item/construction */ @@ -1577,7 +1598,6 @@ static int parse_races(xmlDocPtr doc) rc->speed = (float)xml_fvalue(node, "speed", rc->speed); rc->hitpoints = xml_ivalue(node, "hp", rc->hitpoints); rc->armor = (char)xml_ivalue(node, "ac", rc->armor); - rc->mask_item = (char)xml_ivalue(node, "items", rc->mask_item); study_speed_base = xml_ivalue(node, "studyspeed", 0); rc->at_default = (char)xml_ivalue(node, "unarmedattack", -2); From 5b1e786fb262090c63e3d7490dd357e4c5d60018 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Mar 2017 10:35:34 +0100 Subject: [PATCH 040/218] fix bad strtok call --- src/kernel/xmlreader.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 208a586a7..d6397edf5 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -761,21 +761,22 @@ static int race_mask = 1; static void mask_races(xmlNodePtr node, const char *key, int *maskp) { xmlChar *propValue = xmlGetProp(node, BAD_CAST key); - char *tok; int mask = 0; assert(maskp); - tok = strtok((char *)propValue, " ,"); - while (tok) { - race * rc = rc_get_or_create(tok); - if (!rc->mask_item) { - rc->mask_item = race_mask; - race_mask = race_mask << 1; + if (propValue) { + char * tok = strtok((char *)propValue, " ,"); + while (tok) { + race * rc = rc_get_or_create(tok); + if (!rc->mask_item) { + rc->mask_item = race_mask; + race_mask = race_mask << 1; + } + mask |= rc->mask_item; + tok = strtok(NULL, " ,"); } - mask |= rc->mask_item; - tok = strtok(NULL, " ,"); + xmlFree(propValue); } *maskp = mask; - xmlFree(propValue); } static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) From 591a5b67d3ee9af6aa9b2325c8ed5764c1201c67 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Mar 2017 16:38:28 +0100 Subject: [PATCH 041/218] add missing files --- res/e3a/weapons/axe.xml | 14 ++++++++++++++ res/e3a/weapons/lance.xml | 13 +++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 res/e3a/weapons/axe.xml create mode 100644 res/e3a/weapons/lance.xml diff --git a/res/e3a/weapons/axe.xml b/res/e3a/weapons/axe.xml new file mode 100644 index 000000000..991a2b504 --- /dev/null +++ b/res/e3a/weapons/axe.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/res/e3a/weapons/lance.xml b/res/e3a/weapons/lance.xml new file mode 100644 index 000000000..a3f641833 --- /dev/null +++ b/res/e3a/weapons/lance.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + From 259d7d9e804f6169c85250688a801a82ddae9654 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Mar 2017 16:50:43 +0100 Subject: [PATCH 042/218] add a test for giving horses to 0. should add those horses to the region. remove horses from test that is about 50% silver. --- scripts/tests/common.lua | 13 +++++++++++++ scripts/tests/e3/items.lua | 13 +++++++++++++ scripts/tests/e3/rules.lua | 6 +----- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 03ae5db85..317380417 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1028,3 +1028,16 @@ function test_recruit() assert_equal(6, u.number) end end + +function test_give_horses() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + + r:set_resource("horse", 0) + u:add_item("horse", 20) + u:add_order("GIB 0 10 PFERDE") + process_orders() + assert_equal(10, r:get_resource("horse")) + assert_equal(10, u:get_item("horse")) +end diff --git a/scripts/tests/e3/items.lua b/scripts/tests/e3/items.lua index 349e12b2a..d916be744 100644 --- a/scripts/tests/e3/items.lua +++ b/scripts/tests/e3/items.lua @@ -8,6 +8,19 @@ function setup() eressea.settings.set("NewbieImmunity", "0") end +function test_give_horses() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + + r:set_resource("horse", 0) + u:add_item("charger", 20) + u:add_order("GIB 0 10 Streitross") + process_orders() + assert_equal(10, r:get_resource("horse")) + assert_equal(10, u:get_item("charger")) +end + function test_goblins() local r = region.create(0, 0, "plain") assert(r) diff --git a/scripts/tests/e3/rules.lua b/scripts/tests/e3/rules.lua index 2cba83f21..2ecdf1ff7 100644 --- a/scripts/tests/e3/rules.lua +++ b/scripts/tests/e3/rules.lua @@ -626,11 +626,7 @@ function test_give_50_percent_of_money() u1:add_order("GIB " .. itoa36(u2.id) .. " 221 Silber") u2:clear_orders() u2:add_order("HELFEN " .. itoa36(u1.faction.id) .. " GIB") - u2:add_item("horse", 100) - u2:add_order("GIB 0 ALLES PFERD") - local h = r:get_resource("horse") process_orders() - assert_true(r:get_resource("horse")>=h+100) assert_equal(m1-221, u1:get_item("money")) assert_equal(m2+110, u2:get_item("money")) end @@ -990,4 +986,4 @@ function test_bug2187() -- write_report(f) set_rule("rules.food.flags", "4") -end \ No newline at end of file +end From 681a4bdaa8333d5b4e808760a0faf221ed3ae481 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Mar 2017 17:27:51 +0100 Subject: [PATCH 043/218] dolphins are animals, but not horses. --- scripts/tests/common.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 317380417..fa2fd9f35 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1036,8 +1036,11 @@ function test_give_horses() r:set_resource("horse", 0) u:add_item("horse", 20) - u:add_order("GIB 0 10 PFERDE") + u:add_item("dolphin", 10) + u:add_order("GIB 0 10 PFERD") + u:add_order("GIB 0 5 DELPHIN") process_orders() assert_equal(10, r:get_resource("horse")) + assert_equal(5, u:get_item("dolphin")) assert_equal(10, u:get_item("horse")) end From a265bc9cdb1abc59f9c4145da5317d406602e77b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Mar 2017 18:02:43 +0100 Subject: [PATCH 044/218] test giving stuff to 0. --- scripts/tests/e3/items.lua | 25 ++++++++++++++++++++++++- src/laws.c | 13 +++++++++---- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/scripts/tests/e3/items.lua b/scripts/tests/e3/items.lua index d916be744..caf566468 100644 --- a/scripts/tests/e3/items.lua +++ b/scripts/tests/e3/items.lua @@ -23,7 +23,6 @@ end function test_goblins() local r = region.create(0, 0, "plain") - assert(r) local f1 = faction.create("goblin@eressea.de", "goblin", "de") local f2 = faction.create("dwarf@eressea.de", "dwarf", "de") local f3 = faction.create("elf@eressea.de", "elf", "de") @@ -51,3 +50,27 @@ function test_goblins() ud:add_order("ATTACKIERE " .. itoa36(u3.id)) process_orders() end + +function test_make_horse() + eressea.settings.set("rules.horses.growth", "0") + local r = region.create(0, 0, "plain") + local f = faction.create("horses@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:set_skill("training", 4) + r:set_resource("horse", 100) + u:add_order("MACHE 1 PFERD") + process_orders() + assert_equal(1, u:get_item("horse")) + assert_equal(99, r:get_resource("horse")) + + u:clear_orders() + u:add_order("MACHE 1 STREITROSS") + u:add_item("money", 200) + u:add_item("iron", 1) + process_orders() + assert_equal(1, u:get_item("charger")) + assert_equal(0, u:get_item("horse")) + assert_equal(0, u:get_item("iron")) + assert_equal(0, u:get_item("money")) + assert_equal(99, r:get_resource("horse")) +end diff --git a/src/laws.c b/src/laws.c index cc10baeb5..b8291440f 100644 --- a/src/laws.c +++ b/src/laws.c @@ -333,7 +333,7 @@ int peasant_luck_effect(int peasants, int luck, int maxp, double variance) #endif -static void peasants(region * r) +static void peasants(region * r, int rule) { int peasants = rpeasants(r); int money = rmoney(r); @@ -341,7 +341,7 @@ static void peasants(region * r) int n, satiated; int dead = 0; - if (peasants > 0 && config_get_int("rules.peasants.growth", 1)) { + if (peasants > 0 && rule > 0) { int luck = 0; double fraction = peasants * peasant_growth_factor(); int births = RAND_ROUND(fraction); @@ -812,6 +812,8 @@ void demographics(void) static int last_weeks_season = -1; static int current_season = -1; int plant_rules = config_get_int("rules.grow.formula", 2); + int horse_rules = config_get_int("rules.horses.growth", 1); + int peasant_rules = config_get_int("rules.peasants.growth", 1); const struct building_type *bt_harbour = bt_find("harbour"); if (current_season < 0) { @@ -843,7 +845,8 @@ void demographics(void) * und gewandert sind */ calculate_emigration(r); - peasants(r); + peasants(r, peasant_rules); + if (r->age > 20) { double mwp = MAX(region_maxworkers(r), 1); double prob = @@ -854,7 +857,9 @@ void demographics(void) plagues(r); } } - horses(r); + if (horse_rules > 0) { + horses(r); + } if (plant_rules == 2) { /* E2 */ growing_trees(r, current_season, last_weeks_season); growing_herbs(r, current_season, last_weeks_season); From af28da365da44af452b50cf8790575e0483482bf Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Mar 2017 18:53:39 +0100 Subject: [PATCH 045/218] test giving silber to peasants. --- scripts/tests/common.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index fa2fd9f35..c3e2472c4 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1044,3 +1044,18 @@ function test_give_horses() assert_equal(5, u:get_item("dolphin")) assert_equal(10, u:get_item("horse")) end + +function test_give_silver() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + + r:set_resource("peasant", 0) + r:set_resource("money", 11) + u:clear_orders() + u:add_item("money", 20) + u:add_order("GIB 0 10 SILBER") + process_orders() + assert_equal(21, r:get_resource("money")) + assert_equal(10, u:get_item("money")) +end From d976ee6f67663c1f0d92bbee458ee8cae009f647 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Mar 2017 19:17:20 +0100 Subject: [PATCH 046/218] special cases, not callbacks, for money and horses. --- res/core/common/items.xml | 4 +-- res/core/resources/horse.xml | 3 +- res/e3a/items.xml | 3 +- scripts/tests/common.lua | 8 ++--- src/give.c | 57 +++++++++++++++++++++++++++++++----- src/kernel/item.c | 43 --------------------------- src/kernel/item.h | 2 -- src/kernel/item.test.c | 1 - src/kernel/xmlreader.c | 7 +---- 9 files changed, 57 insertions(+), 71 deletions(-) diff --git a/res/core/common/items.xml b/res/core/common/items.xml index 8f2bbabf8..35f9af2c5 100644 --- a/res/core/common/items.xml +++ b/res/core/common/items.xml @@ -70,9 +70,7 @@ - - - + diff --git a/res/core/resources/horse.xml b/res/core/resources/horse.xml index 243b547db..608fca20a 100644 --- a/res/core/resources/horse.xml +++ b/res/core/resources/horse.xml @@ -1,7 +1,6 @@ - - + diff --git a/res/e3a/items.xml b/res/e3a/items.xml index 9e928837e..0399043e5 100644 --- a/res/e3a/items.xml +++ b/res/e3a/items.xml @@ -62,13 +62,12 @@ - + - diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index c3e2472c4..4f6ed9cbb 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1035,14 +1035,14 @@ function test_give_horses() local u = unit.create(f, r, 1) r:set_resource("horse", 0) - u:add_item("horse", 20) + u:add_item("horse", 21) u:add_item("dolphin", 10) - u:add_order("GIB 0 10 PFERD") + u:add_order("GIB 0 7 PFERD") u:add_order("GIB 0 5 DELPHIN") process_orders() - assert_equal(10, r:get_resource("horse")) + assert_equal(7, r:get_resource("horse")) assert_equal(5, u:get_item("dolphin")) - assert_equal(10, u:get_item("horse")) + assert_equal(14, u:get_item("horse")) end function test_give_silver() diff --git a/src/give.c b/src/give.c index 5abb950a6..884c55283 100644 --- a/src/give.c +++ b/src/give.c @@ -19,6 +19,7 @@ /* kernel includes */ #include +#include #include #include #include @@ -147,17 +148,45 @@ int give_quota(const unit * src, const unit * dst, const item_type * type, return n; } +static int +give_horses(unit * s, unit * d, const item_type * itype, int n, + struct order *ord) +{ + if (d == NULL) { + region *r = s->region; + if (r->land) { + rsethorses(r, rhorses(r) + n); + } + return 0; + } + return -1; /* use the mechanism */ +} + +static int +give_money(unit * s, unit * d, const item_type * itype, int n, + struct order *ord) +{ + if (d == NULL) { + region *r = s->region; + if (r->land) { + rsetmoney(r, rmoney(r) + n); + } + return 0; + } + return -1; /* use the mechanism */ +} + int give_item(int want, const item_type * itype, unit * src, unit * dest, struct order *ord) { short error = 0; - int n, r; + int n, delta; assert(itype != NULL); n = get_pooled(src, item2resource(itype), GET_SLACK | GET_POOLED_SLACK, want); n = MIN(want, n); - r = n; + delta = n; if (dest && src->faction != dest->faction && src->faction->age < GiveRestriction()) { if (ord != NULL) { @@ -178,18 +207,19 @@ struct order *ord) else if (itype->flags & ITF_CURSED) { error = 25; } - else if (itype->give == NULL || itype->give(src, dest, itype, n, ord) != 0) { + else { int use = use_pooled(src, item2resource(itype), GET_SLACK, n); + if (use < n) use += use_pooled(src, item2resource(itype), GET_POOLED_SLACK, n - use); if (dest) { - r = give_quota(src, dest, itype, n); - i_change(&dest->items, itype, r); + delta = give_quota(src, dest, itype, n); + i_change(&dest->items, itype, delta); #ifdef RESERVE_GIVE #ifdef RESERVE_DONATIONS - change_reservation(dest, itype, r); + change_reservation(dest, itype, delta); #else if (src->faction == dest->faction) { change_reservation(dest, item2resource(itype), r); @@ -199,14 +229,25 @@ struct order *ord) #if MUSEUM_MODULE && defined(TODO) /* TODO: use a trigger for the museum warden! */ if (a_find(dest->attribs, &at_warden)) { - warden_add_give(src, dest, itype, r); + warden_add_give(src, dest, itype, delta); } #endif handle_event(dest->attribs, "receive", src); } + else { + /* return horses to the region */ + if (itype->construction && itype->flags & ITF_ANIMAL) { + if (itype->construction->skill == SK_HORSE_TRAINING) { + give_horses(src, dest, itype, n, ord); + } + } + else if (itype->rtype == get_resourcetype(R_SILVER)) { + give_money(src, dest, itype, n, ord); + } + } handle_event(src->attribs, "give", dest); } - add_give(src, dest, n, r, item2resource(itype), ord, error); + add_give(src, dest, n, delta, item2resource(itype), ord, error); if (error) return -1; return 0; diff --git a/src/kernel/item.c b/src/kernel/item.c index 6bd97e6dd..1197e7ce5 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -565,46 +565,6 @@ item *i_new(const item_type * itype, int size) #include "region.h" -static int -give_horses(unit * s, unit * d, const item_type * itype, int n, -struct order *ord) -{ - if (d == NULL) { - int use = use_pooled(s, item2resource(itype), GET_SLACK, n); - region *r = s->region; - if (use < n) { - use += - use_pooled(s, item2resource(itype), GET_RESERVE | GET_POOLED_SLACK, - n - use); - } - if (r->land) { - rsethorses(r, rhorses(r) + use); - } - return 0; - } - return -1; /* use the mechanism */ -} - -static int -give_money(unit * s, unit * d, const item_type * itype, int n, -struct order *ord) -{ - if (d == NULL) { - int use = use_pooled(s, item2resource(itype), GET_SLACK, n); - region *r = s->region; - if (use < n) { - use += - use_pooled(s, item2resource(itype), GET_RESERVE | GET_POOLED_SLACK, - n - use); - } - if (r->land) { - rsetmoney(r, rmoney(r) + use); - } - return 0; - } - return -1; /* use the mechanism */ -} - #define R_MINOTHER R_SILVER #define R_MINHERB R_PLAIN_1 #define R_MINPOTION R_FAST @@ -755,7 +715,6 @@ void init_resources(void) rtype->flags |= RTF_ITEM | RTF_POOLED; rtype->uchange = res_changeitem; rtype->itype = it_get_or_create(rtype); - rtype->itype->give = give_money; rtype = rt_get_or_create(resourcenames[R_PERMAURA]); rtype->uchange = res_changepermaura; @@ -1055,6 +1014,4 @@ void register_resources(void) register_function((pf_generic)res_changepermaura, "changepermaura"); register_function((pf_generic)res_changehp, "changehp"); register_function((pf_generic)res_changeaura, "changeaura"); - - register_item_give(give_horses, "givehorses"); } diff --git a/src/kernel/item.h b/src/kernel/item.h index d38a21340..5f8d879f9 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -128,8 +128,6 @@ extern "C" { /* --- functions --- */ bool(*canuse) (const struct unit * user, const struct item_type * itype); - int(*give) (struct unit * src, struct unit * dest, - const struct item_type * itm, int number, struct order * ord); int score; } item_type; diff --git a/src/kernel/item.test.c b/src/kernel/item.test.c index 52e7d9917..e8b8d79e3 100644 --- a/src/kernel/item.test.c +++ b/src/kernel/item.test.c @@ -162,7 +162,6 @@ static void test_core_resources(CuTest *tc) { CuAssertPtrNotNull(tc, rtype = rt_find("money")); CuAssertPtrNotNull(tc, rtype->itype); CuAssertPtrNotNull(tc, rtype->uchange); - CuAssertPtrNotNull(tc, rtype->itype->give); CuAssertPtrNotNull(tc, rtype = rt_find("peasant")); CuAssertPtrEquals(tc, 0, rtype->itype); CuAssertPtrNotNull(tc, rtype = rt_find("person")); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index d6397edf5..edbaa37f4 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -873,12 +873,7 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) continue; } assert(propValue != NULL); - if (strcmp((const char *)propValue, "give") == 0) { - itype->give = - (int(*)(struct unit *, struct unit *, const struct item_type *, int, - struct order *))fun; - } - else if (strcmp((const char *)propValue, "canuse") == 0) { + if (strcmp((const char *)propValue, "canuse") == 0) { itype->canuse = (bool(*)(const struct unit *, const struct item_type *))fun; } From d9d542cfeebf4019f95761c0f7713a83724b1250 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Mar 2017 19:19:33 +0100 Subject: [PATCH 047/218] we only call these when target is 0, anyway. --- src/give.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/give.c b/src/give.c index 884c55283..5cd19710e 100644 --- a/src/give.c +++ b/src/give.c @@ -148,32 +148,22 @@ int give_quota(const unit * src, const unit * dst, const item_type * type, return n; } -static int -give_horses(unit * s, unit * d, const item_type * itype, int n, - struct order *ord) +static void +give_horses(unit * s, const item_type * itype, int n) { - if (d == NULL) { - region *r = s->region; - if (r->land) { - rsethorses(r, rhorses(r) + n); - } - return 0; + region *r = s->region; + if (r->land) { + rsethorses(r, rhorses(r) + n); } - return -1; /* use the mechanism */ } -static int -give_money(unit * s, unit * d, const item_type * itype, int n, - struct order *ord) +static void +give_money(unit * s, const item_type * itype, int n) { - if (d == NULL) { - region *r = s->region; - if (r->land) { - rsetmoney(r, rmoney(r) + n); - } - return 0; + region *r = s->region; + if (r->land) { + rsetmoney(r, rmoney(r) + n); } - return -1; /* use the mechanism */ } int @@ -238,11 +228,11 @@ struct order *ord) /* return horses to the region */ if (itype->construction && itype->flags & ITF_ANIMAL) { if (itype->construction->skill == SK_HORSE_TRAINING) { - give_horses(src, dest, itype, n, ord); + give_horses(src, itype, n); } } else if (itype->rtype == get_resourcetype(R_SILVER)) { - give_money(src, dest, itype, n, ord); + give_money(src, itype, n); } } handle_event(src->attribs, "give", dest); From 50bdc71c1b9f359dc2b8bbbfb5d0840be4e05c06 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 4 Mar 2017 17:27:13 +0100 Subject: [PATCH 048/218] kill lua_canuse_item and itype->canuse --- res/core/armor/plate.xml | 1 - res/core/weapons/axe.xml | 1 - res/core/weapons/greatbow.xml | 3 +-- res/core/weapons/greatsword.xml | 1 - res/core/weapons/halberd.xml | 1 - res/core/weapons/lance.xml | 1 - res/core/weapons/mallornlance.xml | 1 - res/core/weapons/rep_crossbow.xml | 16 ---------------- res/core/weapons/rustyaxe.xml | 1 - res/core/weapons/rustyhalberd.xml | 1 - res/e3a/armor/plate.xml | 1 - res/e3a/armor/scale.xml | 1 - res/e3a/armor/towershield.xml | 1 - res/e3a/weapons/axe.xml | 1 - res/e3a/weapons/greatbow.xml | 1 - res/e3a/weapons/halberd.xml | 1 - res/e3a/weapons/lance.xml | 1 - res/e3a/weapons/mallornlance.xml | 1 - res/e3a/weapons/rustyhalberd.xml | 1 - scripts/eressea/e3/rules.lua | 28 ---------------------------- scripts/eressea/resources.lua | 7 ------- src/battle.c | 12 +----------- src/helpers.c | 30 ------------------------------ src/kernel/item.h | 3 --- src/kernel/xmlreader.c | 8 +------- 25 files changed, 3 insertions(+), 121 deletions(-) delete mode 100644 res/core/weapons/rep_crossbow.xml diff --git a/res/core/armor/plate.xml b/res/core/armor/plate.xml index a22064e90..97d855a73 100644 --- a/res/core/armor/plate.xml +++ b/res/core/armor/plate.xml @@ -1,7 +1,6 @@ - diff --git a/res/core/weapons/axe.xml b/res/core/weapons/axe.xml index 80a872ad7..3f97a5b8a 100644 --- a/res/core/weapons/axe.xml +++ b/res/core/weapons/axe.xml @@ -1,7 +1,6 @@ - diff --git a/res/core/weapons/greatbow.xml b/res/core/weapons/greatbow.xml index 14734a129..32f07a41e 100644 --- a/res/core/weapons/greatbow.xml +++ b/res/core/weapons/greatbow.xml @@ -1,7 +1,6 @@ - - + diff --git a/res/core/weapons/greatsword.xml b/res/core/weapons/greatsword.xml index cd48b8296..56285f6af 100644 --- a/res/core/weapons/greatsword.xml +++ b/res/core/weapons/greatsword.xml @@ -1,7 +1,6 @@ - diff --git a/res/core/weapons/halberd.xml b/res/core/weapons/halberd.xml index 5025f4793..7abc86902 100644 --- a/res/core/weapons/halberd.xml +++ b/res/core/weapons/halberd.xml @@ -1,7 +1,6 @@ - diff --git a/res/core/weapons/lance.xml b/res/core/weapons/lance.xml index abbb7f31f..4a02bc06f 100644 --- a/res/core/weapons/lance.xml +++ b/res/core/weapons/lance.xml @@ -1,7 +1,6 @@ - diff --git a/res/core/weapons/mallornlance.xml b/res/core/weapons/mallornlance.xml index 0186143e4..c67390d52 100644 --- a/res/core/weapons/mallornlance.xml +++ b/res/core/weapons/mallornlance.xml @@ -1,7 +1,6 @@ - diff --git a/res/core/weapons/rep_crossbow.xml b/res/core/weapons/rep_crossbow.xml deleted file mode 100644 index d6f869046..000000000 --- a/res/core/weapons/rep_crossbow.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/res/core/weapons/rustyaxe.xml b/res/core/weapons/rustyaxe.xml index 2ff19570c..fea6b8642 100644 --- a/res/core/weapons/rustyaxe.xml +++ b/res/core/weapons/rustyaxe.xml @@ -1,7 +1,6 @@ - diff --git a/res/core/weapons/rustyhalberd.xml b/res/core/weapons/rustyhalberd.xml index c1b1f69a9..3f0bd93b7 100644 --- a/res/core/weapons/rustyhalberd.xml +++ b/res/core/weapons/rustyhalberd.xml @@ -1,7 +1,6 @@ - diff --git a/res/e3a/armor/plate.xml b/res/e3a/armor/plate.xml index 9aeafc3c1..79391fbcb 100644 --- a/res/e3a/armor/plate.xml +++ b/res/e3a/armor/plate.xml @@ -1,7 +1,6 @@ - diff --git a/res/e3a/armor/scale.xml b/res/e3a/armor/scale.xml index 691ce5ba7..1038f4d6c 100644 --- a/res/e3a/armor/scale.xml +++ b/res/e3a/armor/scale.xml @@ -1,7 +1,6 @@ - diff --git a/res/e3a/armor/towershield.xml b/res/e3a/armor/towershield.xml index 78e113e2a..38e4f0928 100644 --- a/res/e3a/armor/towershield.xml +++ b/res/e3a/armor/towershield.xml @@ -1,7 +1,6 @@ - diff --git a/res/e3a/weapons/axe.xml b/res/e3a/weapons/axe.xml index 991a2b504..6066c4cfc 100644 --- a/res/e3a/weapons/axe.xml +++ b/res/e3a/weapons/axe.xml @@ -1,7 +1,6 @@ - diff --git a/res/e3a/weapons/greatbow.xml b/res/e3a/weapons/greatbow.xml index b488a011c..745d1793d 100644 --- a/res/e3a/weapons/greatbow.xml +++ b/res/e3a/weapons/greatbow.xml @@ -5,7 +5,6 @@ --> - diff --git a/res/e3a/weapons/halberd.xml b/res/e3a/weapons/halberd.xml index c07cbfd4d..c22e020b4 100644 --- a/res/e3a/weapons/halberd.xml +++ b/res/e3a/weapons/halberd.xml @@ -4,7 +4,6 @@ --> - diff --git a/res/e3a/weapons/lance.xml b/res/e3a/weapons/lance.xml index a3f641833..285862484 100644 --- a/res/e3a/weapons/lance.xml +++ b/res/e3a/weapons/lance.xml @@ -1,7 +1,6 @@ - diff --git a/res/e3a/weapons/mallornlance.xml b/res/e3a/weapons/mallornlance.xml index d2aacaea7..8eb25ceb4 100644 --- a/res/e3a/weapons/mallornlance.xml +++ b/res/e3a/weapons/mallornlance.xml @@ -1,7 +1,6 @@ - diff --git a/res/e3a/weapons/rustyhalberd.xml b/res/e3a/weapons/rustyhalberd.xml index 32c0d4497..a53aec515 100644 --- a/res/e3a/weapons/rustyhalberd.xml +++ b/res/e3a/weapons/rustyhalberd.xml @@ -4,7 +4,6 @@ --> - diff --git a/scripts/eressea/e3/rules.lua b/scripts/eressea/e3/rules.lua index c0ac8978a..e7a54ff41 100644 --- a/scripts/eressea/e3/rules.lua +++ b/scripts/eressea/e3/rules.lua @@ -1,31 +1,3 @@ --- when appending to this, make sure the item has a canuse-function! -local goblin_denied = " plate lance mallornlance greatbow axe greatsword halberd rustyaxe rustyhalberd towershield scale " -function item_canuse(u, iname) - local race = u.race - if race=="goblin" then - if string.find(goblin_denied, " " .. iname .. " ") then - return false - end - end - if iname=="rep_crossbow" then - -- only dwarves and halflings allowed to use repeating crossbow - return race=="dwarf" or race=="halfling" - end - if iname=="scale" then - -- only dwarves and halflings can use scale - return race=="dwarf" or race=="halfling" - end - if iname=="towershield" then - -- only dwarves allowed to use towershield - return race=="dwarf" - end - if iname=="greatbow" then - -- only elves use greatbow - return race=="elf" - end - return true -end - function building_taxes(b, blevel) btype = b.type if btype=="castle" then diff --git a/scripts/eressea/resources.lua b/scripts/eressea/resources.lua index 2829d00c7..588620aa4 100644 --- a/scripts/eressea/resources.lua +++ b/scripts/eressea/resources.lua @@ -1,12 +1,5 @@ -- global functions used in items.xml -if not item_canuse then - -- define a default, everyone can use everything - function item_canuse(u, iname) - return true - end -end - function peasant_getresource(u) return u.region:get_resource("peasant") end diff --git a/src/battle.c b/src/battle.c index fa5725c50..e8eb426e3 100644 --- a/src/battle.c +++ b/src/battle.c @@ -576,17 +576,7 @@ static weapon *select_weapon(const troop t, bool attacking, static bool i_canuse(const unit * u, const item_type * itype) { - bool result = true; - if (itype->canuse) { - result = itype->canuse(u, itype); - } - if (result!=rc_can_use(u_race(u), itype)) { - log_error("conversion error: %s should be %s to use %s", - u->_race->_name, - result ? "allowed" : "forbidden", - itype->rtype->_name); - } - return result; + return rc_can_use(u_race(u), itype); } static int diff --git a/src/helpers.c b/src/helpers.c index e8e6521c4..a4746461b 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -320,34 +320,6 @@ static int lua_getresource(unit * u, const struct resource_type *rtype) return result; } -static bool lua_canuse_item(const unit * u, const struct item_type *itype) -{ - bool result = true; - lua_State *L = (lua_State *)global.vm_state; - const char *fname = "item_canuse"; - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); - tolua_pushstring(L, itype->rtype->_name); - - if (lua_pcall(L, 2, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error); - lua_pop(L, 1); - } - else { - result = lua_toboolean(L, -1); - lua_pop(L, 1); - } - } - else { - log_error("use(%s) calling '%s': not a function.\n", unitname(u), fname); - lua_pop(L, 1); - } - return result; -} - static int lua_wage(const region * r, const faction * f, const race * rc, int in_turn) { @@ -563,8 +535,6 @@ void register_tolua_helpers(void) TOLUA_CAST "lua_initfamiliar"); register_function((pf_generic)lua_getresource, TOLUA_CAST "lua_getresource"); - register_function((pf_generic)lua_canuse_item, - TOLUA_CAST "lua_canuse_item"); register_function((pf_generic)lua_changeresource, TOLUA_CAST "lua_changeresource"); register_function((pf_generic)lua_equipmentcallback, diff --git a/src/kernel/item.h b/src/kernel/item.h index 5f8d879f9..dda0cf3e4 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -125,9 +125,6 @@ extern "C" { int mask_deny; struct construction *construction; char *_appearance[2]; /* wie es f�r andere aussieht */ - /* --- functions --- */ - bool(*canuse) (const struct unit * user, - const struct item_type * itype); int score; } item_type; diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index edbaa37f4..aabab91d6 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -873,13 +873,7 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) continue; } assert(propValue != NULL); - if (strcmp((const char *)propValue, "canuse") == 0) { - itype->canuse = - (bool(*)(const struct unit *, const struct item_type *))fun; - } - else { - log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, rtype->_name); - } + log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, rtype->_name); xmlFree(propValue); } itype->score = xml_ivalue(node, "score", 0); From acfb6665390df3a85ad17eb803717d5d31b26421 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 4 Mar 2017 20:59:43 +0100 Subject: [PATCH 049/218] remove rtype->uget funpointer, and lua callbacks. fix a missing lua_pop that trashed the heap. --- res/core/resources/hp.xml | 1 - res/core/resources/peasant.xml | 1 - res/e3a/weapons.xml | 2 +- res/e3a/weapons/rep_crossbow.xml | 15 +++++++++++++++ scripts/eressea/resources.lua | 8 -------- src/helpers.c | 2 +- src/kernel/item.h | 3 --- src/kernel/pool.c | 14 ++++++-------- src/kernel/region.c | 3 +++ src/kernel/save.c | 2 ++ src/kernel/xmlreader.c | 3 --- 11 files changed, 28 insertions(+), 26 deletions(-) create mode 100644 res/e3a/weapons/rep_crossbow.xml diff --git a/res/core/resources/hp.xml b/res/core/resources/hp.xml index fb1b6e32f..aa0ad4d29 100644 --- a/res/core/resources/hp.xml +++ b/res/core/resources/hp.xml @@ -1,5 +1,4 @@ - diff --git a/res/core/resources/peasant.xml b/res/core/resources/peasant.xml index 32e1e1ca1..bce23430c 100644 --- a/res/core/resources/peasant.xml +++ b/res/core/resources/peasant.xml @@ -1,5 +1,4 @@ - diff --git a/res/e3a/weapons.xml b/res/e3a/weapons.xml index 96a987b28..fdc8f1f3a 100644 --- a/res/e3a/weapons.xml +++ b/res/e3a/weapons.xml @@ -4,13 +4,13 @@ - + diff --git a/res/e3a/weapons/rep_crossbow.xml b/res/e3a/weapons/rep_crossbow.xml new file mode 100644 index 000000000..02f0d865f --- /dev/null +++ b/res/e3a/weapons/rep_crossbow.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/scripts/eressea/resources.lua b/scripts/eressea/resources.lua index 588620aa4..fa6e1c4da 100644 --- a/scripts/eressea/resources.lua +++ b/scripts/eressea/resources.lua @@ -1,9 +1,5 @@ -- global functions used in items.xml -function peasant_getresource(u) - return u.region:get_resource("peasant") -end - function peasant_changeresource(u, delta) local p = u.region:get_resource("peasant") p = p + delta @@ -14,10 +10,6 @@ function peasant_changeresource(u, delta) return p end -function hp_getresource(u) - return u.hp -end - function hp_changeresource(u, delta) local hp = u.hp + delta diff --git a/src/helpers.c b/src/helpers.c index a4746461b..402ecdd48 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -496,13 +496,13 @@ use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord) } return result; } + lua_pop(L, 1); if (itype->rtype->ptype) { return use_potion(u, itype, amount, ord); } else { log_error("no such callout: %s", fname); } log_error("use(%s) calling '%s': not a function.\n", unitname(u), fname); - lua_pop(L, 1); return result; } diff --git a/src/kernel/item.h b/src/kernel/item.h index dda0cf3e4..77fe1a9c2 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -68,8 +68,6 @@ extern "C" { typedef int(*rtype_uchange) (struct unit * user, const struct resource_type * rtype, int delta); - typedef int(*rtype_uget) (const struct unit * user, - const struct resource_type * rtype); typedef char *(*rtype_name) (const struct resource_type * rtype, int flags); typedef struct resource_type { /* --- constants --- */ @@ -77,7 +75,6 @@ extern "C" { unsigned int flags; /* --- functions --- */ rtype_uchange uchange; - rtype_uget uget; rtype_name name; struct rawmaterial_type *raw; struct resource_mod *modifiers; diff --git a/src/kernel/pool.c b/src/kernel/pool.c index 702f86e0f..8dfd589c3 100644 --- a/src/kernel/pool.c +++ b/src/kernel/pool.c @@ -40,11 +40,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. int get_resource(const unit * u, const resource_type * rtype) { assert(rtype); - if (rtype->uget) { - /* this resource is probably special */ - int i = rtype->uget(u, rtype); - if (i >= 0) - return i; + if (rtype == get_resourcetype(R_PEASANT)) { + return u->region->land ? u->region->land->peasants : 0; + } + else if (rtype == rt_find("hp")) { + return u->hp; } else if (rtype->uchange) { /* this resource is probably special */ @@ -176,7 +176,7 @@ int count) } if (rtype->flags & RTF_POOLED && mode & ~(GET_SLACK | GET_RESERVE)) { for (v = r->units; v && use < count; v = v->next) - if (u != v && (v->items || rtype->uget)) { + if (u != v) { int mask; if ((u_race(v)->ec_flags & ECF_KEEP_ITEM)) @@ -234,8 +234,6 @@ use_pooled(unit * u, const resource_type * rtype, unsigned int mode, int count) int mask; if ((u_race(v)->ec_flags & ECF_KEEP_ITEM)) continue; - if (v->items == NULL && rtype->uget == NULL) - continue; if (v->faction == f) { mask = (mode >> 3) & (GET_SLACK | GET_RESERVE); diff --git a/src/kernel/region.c b/src/kernel/region.c index aefffa875..e4f33db33 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -38,6 +38,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "unit.h" /* util includes */ +#include #include #include #include @@ -697,6 +698,7 @@ void r_setdemand(region * r, const luxury_type * ltype, int value) d = *dp; if (!d) { d = *dp = malloc(sizeof(struct demand)); + assert_alloc(d); d->next = NULL; d->type = ltype; } @@ -768,6 +770,7 @@ region *new_region(int x, int y, struct plane *pl, int uid) return r; } r = calloc(1, sizeof(region)); + assert_alloc(r); r->x = x; r->y = y; r->uid = uid; diff --git a/src/kernel/save.c b/src/kernel/save.c index 8316121f3..e487737f9 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -52,6 +52,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ +#include #include #include #include @@ -646,6 +647,7 @@ unit *read_unit(struct gamedata *data) } else { u = calloc(sizeof(unit), 1); + assert_alloc(u); u->no = n; uhash(u); } diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index aabab91d6..4db528853 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -972,9 +972,6 @@ static int parse_resources(xmlDocPtr doc) if (strcmp((const char *)propValue, "change") == 0) { rtype->uchange = (rtype_uchange)fun; } - else if (strcmp((const char *)propValue, "get") == 0) { - rtype->uget = (rtype_uget)fun; - } else if (strcmp((const char *)propValue, "name") == 0) { rtype->name = (rtype_name)fun; } From ae6a4ca3392ee3ebbd6e80774de538a4a8dc322d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 11:42:11 +0100 Subject: [PATCH 050/218] new clibs submodule --- clibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clibs b/clibs index b91413316..d286006a2 160000 --- a/clibs +++ b/clibs @@ -1 +1 @@ -Subproject commit b91413316ce13044c555084a9f605983586107b4 +Subproject commit d286006a28c8aa7cd70ed7fd4cd172b50ade9727 From f4eda9f59ecfca40f1f8ff2fb86515f135a56f96 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 6 Mar 2017 06:28:12 +0100 Subject: [PATCH 051/218] prefer dice to dice_rand --- src/items.c | 4 ++-- src/kernel/region.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/items.c b/src/items.c index 78f6e3188..0f97ea675 100644 --- a/src/items.c +++ b/src/items.c @@ -178,8 +178,8 @@ struct order *ord) return 0; } -#define BAGPIPEFRACTION dice_rand("2d4+2") -#define BAGPIPEDURATION dice_rand("2d10+4") +#define BAGPIPEFRACTION (dice(2,4)+2) +#define BAGPIPEDURATION (dice(2,10)+4) static int use_bagpipeoffear(struct unit *u, const struct item_type *itype, diff --git a/src/kernel/region.c b/src/kernel/region.c index e4f33db33..48256fb60 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -1217,7 +1217,7 @@ void terraform_region(region * r, const terrain_type * terrain) if (!fval(r, RF_CHAOTIC)) { int peasants; - peasants = (region_maxworkers(r) * (20 + dice_rand("6d10"))) / 100; + 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)); From 40e0a9a65f956c037cff8dba0a4e0030c24ede44 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 6 Mar 2017 22:21:27 +0100 Subject: [PATCH 052/218] merge bugs --- src/kernel/item.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/src/kernel/item.c b/src/kernel/item.c index d9a466543..97ae92174 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -565,46 +565,6 @@ item *i_new(const item_type * itype, int size) #include "region.h" -static int -give_horses(unit * s, unit * d, const item_type * itype, int n, -struct order *ord) -{ - if (d == NULL) { - int use = use_pooled(s, item2resource(itype), GET_SLACK, n); - region *r = s->region; - if (use < n) { - use += - use_pooled(s, item2resource(itype), GET_RESERVE | GET_POOLED_SLACK, - n - use); - } - if (r->land) { - rsethorses(r, rhorses(r) + use); - } - return 0; - } - return -1; /* use the mechanism */ -} - -static int -give_money(unit * s, unit * d, const item_type * itype, int n, -struct order *ord) -{ - if (d == NULL) { - int use = use_pooled(s, item2resource(itype), GET_SLACK, n); - region *r = s->region; - if (use < n) { - use += - use_pooled(s, item2resource(itype), GET_RESERVE | GET_POOLED_SLACK, - n - use); - } - if (r->land) { - rsetmoney(r, rmoney(r) + use); - } - return 0; - } - return -1; /* use the mechanism */ -} - const potion_type *oldpotiontype[MAX_POTIONS + 1]; /*** alte items ***/ From 2b4d2db112555ecfa8f7704644b36d27f0b2a145 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 11 Mar 2017 16:23:33 +0100 Subject: [PATCH 053/218] VS 15 not yet supported. --- tests/runtests.bat | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/runtests.bat b/tests/runtests.bat index 7a58e5762..41b5f8056 100644 --- a/tests/runtests.bat +++ b/tests/runtests.bat @@ -3,7 +3,6 @@ IF EXIST ..\build-vs10 SET BUILD=..\build-vs10\eressea\Debug IF EXIST ..\build-vs11 SET BUILD=..\build-vs11\eressea\Debug IF EXIST ..\build-vs12 SET BUILD=..\build-vs12\eressea\Debug IF EXIST ..\build-vs14 SET BUILD=..\build-vs14\eressea\Debug -IF EXIST ..\build-vs15 SET BUILD=..\build-vs15\eressea\Debug SET SERVER=%BUILD%\eressea.exe %BUILD%\test_eressea.exe %SERVER% ..\scripts\run-tests.lua From 858074501e9eea34089896cb53526cdfdfdf8dce Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 26 Sep 2016 20:30:52 +0200 Subject: [PATCH 054/218] additional comments --- src/laws.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/laws.c b/src/laws.c index 5b4c5971b..2554d0e23 100644 --- a/src/laws.c +++ b/src/laws.c @@ -4285,12 +4285,18 @@ void update_subscriptions(void) fclose(F); } -bool -cansee(const faction * f, const region * r, const unit * u, int modifier) -/* r kann != u->region sein, wenn es um Durchreisen geht, +/** determine if unit can be seen by faction + * @param f -- the observiong faction + * @param u -- the unit that is observed + * @param r -- the region that u is obesrved in (see below) + * @param m -- terrain modifier to stealth + * + * r kann != u->region sein, wenn es um Durchreisen geht, * oder Zauber (sp_generous, sp_fetchastral). * Es muss auch niemand aus f in der region sein, wenn sie vom Turm * erblickt wird */ +bool +cansee(const faction * f, const region * r, const unit * u, int modifier) { int stealth, rings; unit *u2 = r->units; From 0f2744fcf37fa2593ecea327cd6a95ea46051d1d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 11 Mar 2017 18:10:23 +0100 Subject: [PATCH 055/218] BUG 2285: remove factions' wealthfrom statistics. --- src/kernel/faction.h | 1 - src/laws.c | 4 ++-- src/summary.c | 10 ++++------ 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 0a0ac39d6..80248210a 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -83,7 +83,6 @@ extern "C" { struct ally *allies; /* alliedgroup and others should check sf.faction.alive before using a faction from f.allies */ struct group *groups; /* alliedgroup and others should check sf.faction.alive before using a faction from f.groups */ int nregions; - int money; score_t score; struct alliance *alliance; int alliance_joindate; /* the turn on which the faction joined its current alliance (or left the last one) */ diff --git a/src/laws.c b/src/laws.c index 2554d0e23..d66cf496b 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1279,8 +1279,8 @@ static void remove_idle_players(void) } else if (turn != f->lastorders) { char info[256]; - sprintf(info, "%d Einheiten, %d Personen, %d Silber", - f->no_units, f->num_total, f->money); + sprintf(info, "%d Einheiten, %d Personen", + f->no_units, f->num_total); } fp = &f->next; } diff --git a/src/summary.c b/src/summary.c index 32416a263..86273e67d 100644 --- a/src/summary.c +++ b/src/summary.c @@ -129,15 +129,15 @@ static char *rcomp(int i, int j) static void out_faction(FILE * file, const struct faction *f) { if (alliances != NULL) { - fprintf(file, "%s (%s/%d) (%.3s/%.3s), %d Einh., %d Pers., $%d, %d NMR\n", + fprintf(file, "%s (%s/%d) (%.3s/%.3s), %d Einh., %d Pers., %d NMR\n", f->name, itoa36(f->no), f_get_alliance(f) ? f->alliance->id : 0, LOC(default_locale, rc_name_s(f->race, NAME_SINGULAR)), magic_school[f->magiegebiet], - count_units(f), f->num_total, f->money, turn - f->lastorders); + count_units(f), f->num_total, turn - f->lastorders); } else { - fprintf(file, "%s (%.3s/%.3s), %d Einh., %d Pers., $%d, %d NMR\n", + fprintf(file, "%s (%.3s/%.3s), %d Einh., %d Pers., %d NMR\n", factionname(f), LOC(default_locale, rc_name_s(f->race, NAME_SINGULAR)), - magic_school[f->magiegebiet], count_units(f), f->num_total, f->money, + magic_school[f->magiegebiet], count_units(f), f->num_total, turn - f->lastorders); } } @@ -395,7 +395,6 @@ summary *make_summary(void) ++plang->number; f->nregions = 0; f->num_total = 0; - f->money = 0; if (f->units) { s->factions++; /* Problem mit Monsterpartei ... */ @@ -478,7 +477,6 @@ summary *make_summary(void) } f->num_total += u->number; - f->money += get_money(u); orace = (int)old_race(u_race(u)); if (orace >= 0) { s->poprace[orace] += u->number; From d633c2a9fbeb74764eeaf36c73f3cc7f9874f7bd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 11 Mar 2017 19:36:26 +0100 Subject: [PATCH 056/218] BUG 2310: counting units and people. reduce number of count_all loops made, make f->num_units and f->num_people be correct. --- src/creport.c | 2 +- src/kernel/faction.c | 14 ++------------ src/kernel/faction.h | 7 +------ src/kernel/save.c | 5 +---- src/kernel/unit.c | 6 +++--- src/laws.c | 9 ++++----- src/modules/score.c | 4 ++-- src/report.c | 10 ++-------- src/summary.c | 8 ++++---- 9 files changed, 20 insertions(+), 45 deletions(-) diff --git a/src/creport.c b/src/creport.c index d16f87f22..fd307c5ec 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1558,7 +1558,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom) translate(prefix, LOC(f->locale, prefix))); } fprintf(F, "%d;Rekrutierungskosten\n", f->race->recruitcost); - fprintf(F, "%d;Anzahl Personen\n", count_all(f)); + fprintf(F, "%d;Anzahl Personen\n", f->num_people); fprintf(F, "\"%s\";Magiegebiet\n", magic_school[f->magiegebiet]); if (rc_changed(&rc_cache)) { diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 139474048..03cea282f 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -712,7 +712,7 @@ int count_faction(const faction * f, int flags) int n = 0; for (u = f->units; u; u = u->nextF) { const race *rc = u_race(u); - int x = (flags&COUNT_UNITS) ? 1 : u->number; + int x = u->number; if (f->race != rc) { if (!playerrace(rc)) { if (flags&COUNT_MONSTERS) { @@ -732,16 +732,6 @@ int count_faction(const faction * f, int flags) return n; } -int count_units(const faction * f) -{ - return count_faction(f, COUNT_ALL | COUNT_UNITS); -} - -int count_all(const faction * f) -{ - return count_faction(f, COUNT_ALL); -} - int count_migrants(const faction * f) { return count_faction(f, COUNT_MIGRANTS); @@ -752,7 +742,7 @@ int count_maxmigrants(const faction * f) int formula = rc_migrants_formula(f->race); if (formula == MIGRANTS_LOG10) { - int nsize = count_all(f); + int nsize = f->num_people; if (nsize > 0) { int x = (int)(log10(nsize / 50.0) * 20); if (x < 0) x = 0; diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 80248210a..9b290e5da 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -77,9 +77,8 @@ extern "C" { magic_t magiegebiet; int newbies; int num_people; /* Anzahl Personen ohne Monster */ - int num_total; /* Anzahl Personen mit Monstern */ + int num_units; int options; - int no_units; struct ally *allies; /* alliedgroup and others should check sf.faction.alive before using a faction from f.allies */ struct group *groups; /* alliedgroup and others should check sf.faction.alive before using a faction from f.groups */ int nregions; @@ -165,14 +164,10 @@ extern "C" { #define COUNT_MONSTERS 0x01 #define COUNT_MIGRANTS 0x02 #define COUNT_DEFAULT 0x04 -#define COUNT_ALL 0x07 -#define COUNT_UNITS 0x10 int count_faction(const struct faction * f, int flags); int count_migrants(const struct faction * f); int count_maxmigrants(const struct faction * f); - int count_all(const struct faction * f); - int count_units(const struct faction * f); int max_magicians(const struct faction * f); struct faction *getfaction(void); diff --git a/src/kernel/save.c b/src/kernel/save.c index e487737f9..5be078d8a 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -657,10 +657,7 @@ unit *read_unit(struct gamedata *data) if (f != u->faction) { u_setfaction(u, f); } - if (u->faction) { - ++u->faction->no_units; - } - else { + if (!u->faction) { log_error("unit %s has faction == NULL", itoa36(u->no)); return 0; } diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 595accba2..2239cf81b 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1129,7 +1129,7 @@ void u_setfaction(unit * u, faction * f) if (u->faction == f) return; if (u->faction) { - --u->faction->no_units; + --u->faction->num_units; set_number(u, 0); join_group(u, NULL); free_orders(&u->orders); @@ -1166,7 +1166,7 @@ void u_setfaction(unit * u, faction * f) set_number(u, cnt); } if (f) { - ++f->no_units; + ++f->num_units; } } @@ -1581,7 +1581,7 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace, int maxheroes(const struct faction *f) { - int nsize = count_all(f); + int nsize = f->num_people; if (nsize == 0) return 0; else { diff --git a/src/laws.c b/src/laws.c index d66cf496b..6722194a9 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1280,7 +1280,7 @@ static void remove_idle_players(void) else if (turn != f->lastorders) { char info[256]; sprintf(info, "%d Einheiten, %d Personen", - f->no_units, f->num_total); + f->num_units, f->num_people); } fp = &f->next; } @@ -2519,7 +2519,7 @@ int promotion_cmd(unit * u, struct order *ord) u_race(u))); return 0; } - people = count_all(u->faction) * u->number; + people = u->faction->num_people * u->number; money = get_pooled(u, rsilver, GET_ALL, people); if (people > money) { @@ -3020,8 +3020,7 @@ static int maxunits(const faction * f) int checkunitnumber(const faction * f, int add) { int alimit, flimit; - int flags = COUNT_DEFAULT | COUNT_MIGRANTS | COUNT_UNITS; - int fno = count_faction(f, flags) + add; + int fno = f->num_units + add; flimit = rule_faction_limit(); if (flimit && fno > flimit) { return 2; @@ -3039,7 +3038,7 @@ int checkunitnumber(const faction * f, int add) for (f2 = factions; f2; f2 = f2->next) { if (f != f2 && f->alliance == f2->alliance) { - unitsinalliance += count_faction(f2, flags); + unitsinalliance += f2->num_units; if (unitsinalliance > alimit) { return 1; } diff --git a/src/modules/score.c b/src/modules/score.c index 0776d6507..efb3465d4 100644 --- a/src/modules/score.c +++ b/src/modules/score.c @@ -160,7 +160,7 @@ void score(void) faction *f; fwrite(utf8_bom, 1, 3, scoreFP); for (f = factions; f; f = f->next) - if (!fval(f, FFL_NPC) && f->num_total != 0) { + if (!fval(f, FFL_NPC) && f->num_people != 0) { char score[32]; write_score(score, sizeof(score), f->score); fprintf(scoreFP, "%s ", score); @@ -195,7 +195,7 @@ void score(void) if (f->alliance && f->alliance == a) { alliance_factions++; alliance_score += f->score; - alliance_number += f->num_total; + alliance_number += f->num_people; if (token != NULL) { unit *u = f->units; while (u != NULL) { diff --git a/src/report.c b/src/report.c index 2f8ba7bce..dbcf54ff1 100644 --- a/src/report.c +++ b/src/report.c @@ -2106,14 +2106,8 @@ report_plaintext(const char *filename, report_context * ctx, RENDER(f, buf, sizeof(buf), ("nr_score", "score average", score, avg)); centre(out, buf, true); } - no_units = count_units(f); - no_people = count_all(f); - if (f->flags & FFL_NPC) { - no_people = f->num_total; - } - else { - no_people = f->num_people; - } + no_units = f->num_units; + no_people = f->num_people; m = msg_message("nr_population", "population units limit", no_people, no_units, rule_faction_limit()); nr_render(m, f->locale, buf, sizeof(buf), f); msg_release(m); diff --git a/src/summary.c b/src/summary.c index 86273e67d..71bb30efc 100644 --- a/src/summary.c +++ b/src/summary.c @@ -132,12 +132,12 @@ static void out_faction(FILE * file, const struct faction *f) fprintf(file, "%s (%s/%d) (%.3s/%.3s), %d Einh., %d Pers., %d NMR\n", f->name, itoa36(f->no), f_get_alliance(f) ? f->alliance->id : 0, LOC(default_locale, rc_name_s(f->race, NAME_SINGULAR)), magic_school[f->magiegebiet], - count_units(f), f->num_total, turn - f->lastorders); + f->num_units, f->num_people, turn - f->lastorders); } else { fprintf(file, "%s (%.3s/%.3s), %d Einh., %d Pers., %d NMR\n", factionname(f), LOC(default_locale, rc_name_s(f->race, NAME_SINGULAR)), - magic_school[f->magiegebiet], count_units(f), f->num_total, + magic_school[f->magiegebiet], f->num_units, f->num_people, turn - f->lastorders); } } @@ -394,7 +394,7 @@ summary *make_summary(void) } ++plang->number; f->nregions = 0; - f->num_total = 0; + f->num_people = 0; if (f->units) { s->factions++; /* Problem mit Monsterpartei ... */ @@ -476,7 +476,7 @@ summary *make_summary(void) } } - f->num_total += u->number; + f->num_people += u->number; orace = (int)old_race(u_race(u)); if (orace >= 0) { s->poprace[orace] += u->number; From 21e260907c331c853b326cb1f0de7eae27aaa771 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 11 Mar 2017 20:03:49 +0100 Subject: [PATCH 057/218] BUG 2311: unit limits were not enforced by GIVE. --- src/give.c | 17 +++++++++++++++++ src/give.test.c | 49 +++++++++++++++++++++++++++++++++---------------- src/laws.c | 2 -- src/laws.h | 1 + src/laws.test.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 98 insertions(+), 19 deletions(-) diff --git a/src/give.c b/src/give.c index 0f1c56c39..1265ab169 100644 --- a/src/give.c +++ b/src/give.c @@ -533,6 +533,23 @@ void give_unit(unit * u, unit * u2, order * ord) } } return; + } else { + int err = checkunitnumber(u2->faction, 1); + if (err) { + if (err == 1) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, ord, + "too_many_units_in_alliance", + "allowed", rule_alliance_limit())); + } + else { + ADDMSG(&u->faction->msgs, + msg_feedback(u, ord, + "too_many_units_in_faction", + "allowed", rule_faction_limit())); + } + return; + } } if (!alliedunit(u2, u->faction, HELP_GIVE) && ucontact(u2, u) == 0) { diff --git a/src/give.test.c b/src/give.test.c index 1767dec36..604e42549 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -54,26 +54,12 @@ static void setup_give(struct give *env) { } } -static void test_give_unit_to_peasants(CuTest * tc) { - struct give env = { 0 }; - test_setup_ex(tc); - env.f1 = test_create_faction(0); - env.f2 = 0; - setup_give(&env); - rsetpeasants(env.r, 0); - give_unit(env.src, NULL, NULL); - CuAssertIntEquals(tc, 0, env.src->number); - CuAssertIntEquals(tc, 1, rpeasants(env.r)); - test_cleanup(); -} - static void test_give_unit(CuTest * tc) { struct give env = { 0 }; test_setup_ex(tc); env.f1 = test_create_faction(0); env.f2 = test_create_faction(0); setup_give(&env); - env.r->terrain = test_create_terrain("ocean", SEA_REGION); config_set("rules.give.max_men", "0"); give_unit(env.src, env.dst, NULL); CuAssertPtrEquals(tc, env.f1, env.src->faction); @@ -88,7 +74,37 @@ static void test_give_unit(CuTest * tc) { test_cleanup(); } -static void test_give_unit_in_ocean(CuTest * tc) { +static void test_give_unit_limits(CuTest * tc) { + struct give env = { 0 }; + test_setup_ex(tc); + env.f1 = test_create_faction(0); + env.f2 = test_create_faction(0); + setup_give(&env); + CuAssertIntEquals(tc, 1, env.f1->num_units); + CuAssertIntEquals(tc, 1, env.f2->num_units); + config_set("rules.limit.faction", "1"); + give_unit(env.src, env.dst, NULL); + CuAssertPtrEquals(tc, env.f1, env.src->faction); + CuAssertIntEquals(tc, 0, env.f2->newbies); + CuAssertIntEquals(tc, 1, env.f1->num_units); + CuAssertIntEquals(tc, 1, env.f2->num_units); + test_cleanup(); +} + +static void test_give_unit_to_peasants(CuTest * tc) { + struct give env = { 0 }; + test_setup_ex(tc); + env.f1 = test_create_faction(0); + env.f2 = 0; + setup_give(&env); + rsetpeasants(env.r, 0); + give_unit(env.src, NULL, NULL); + CuAssertIntEquals(tc, 0, env.src->number); + CuAssertIntEquals(tc, 1, rpeasants(env.r)); + test_cleanup(); +} + +static void test_give_unit_to_ocean(CuTest * tc) { struct give env = { 0 }; test_setup_ex(tc); env.f1 = test_create_faction(0); @@ -429,7 +445,8 @@ CuSuite *get_give_suite(void) SUITE_ADD_TEST(suite, test_give_men_requires_contact); SUITE_ADD_TEST(suite, test_give_men_not_to_self); SUITE_ADD_TEST(suite, test_give_unit); - SUITE_ADD_TEST(suite, test_give_unit_in_ocean); + SUITE_ADD_TEST(suite, test_give_unit_limits); + SUITE_ADD_TEST(suite, test_give_unit_to_ocean); SUITE_ADD_TEST(suite, test_give_unit_to_peasants); SUITE_ADD_TEST(suite, test_give_peasants); SUITE_ADD_TEST(suite, test_give_herbs); diff --git a/src/laws.c b/src/laws.c index 6722194a9..9c25ac461 100644 --- a/src/laws.c +++ b/src/laws.c @@ -3028,8 +3028,6 @@ int checkunitnumber(const faction * f, int add) alimit = rule_alliance_limit(); if (alimit) { - /* if unitsperalliance is true, maxunits returns the - number of units allowed in an alliance */ faction *f2; int unitsinalliance = fno; if (unitsinalliance > alimit) { diff --git a/src/laws.h b/src/laws.h index 090d2b978..7f1385483 100755 --- a/src/laws.h +++ b/src/laws.h @@ -58,6 +58,7 @@ extern "C" { void turn_process(void); void turn_end(void); + int checkunitnumber(const struct faction * f, int add); void new_units(void); void defaultorders(void); void quit(void); diff --git a/src/laws.test.c b/src/laws.test.c index 937754988..e8391b67c 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -5,6 +5,7 @@ #include "monsters.h" #include +#include #include #include #include @@ -427,7 +428,51 @@ static void test_unit_limit(CuTest * tc) test_cleanup(); } -extern int checkunitnumber(const faction * f, int add); +static void test_limit_new_units(CuTest * tc) +{ + faction *f; + unit *u; + alliance *al; + + test_setup(); + al = makealliance(1, "Hodor"); + f = test_create_faction(NULL); + u = test_create_unit(f, test_create_region(0, 0, NULL)); + CuAssertIntEquals(tc, 1, f->num_units); + CuAssertIntEquals(tc, 1, f->num_people); + scale_number(u, 10); + CuAssertIntEquals(tc, 10, f->num_people); + config_set("rules.limit.faction", "2"); + + u->orders = create_order(K_MAKETEMP, f->locale, "1"); + new_units(); + CuAssertPtrNotNull(tc, u->next); + CuAssertIntEquals(tc, 2, f->num_units); + + new_units(); + CuAssertIntEquals(tc, 2, f->num_units); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "too_many_units_in_faction")); + + setalliance(f, al); + + config_set("rules.limit.faction", "3"); + config_set("rules.limit.alliance", "2"); + + new_units(); + CuAssertIntEquals(tc, 2, f->num_units); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "too_many_units_in_alliance")); + + config_set("rules.limit.alliance", "3"); + u = test_create_unit(test_create_faction(NULL), u->region); + setalliance(u->faction, al); + + new_units(); + CuAssertIntEquals(tc, 2, f->num_units); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "too_many_units_in_alliance")); + + test_cleanup(); +} + static void test_cannot_create_unit_above_limit(CuTest * tc) { faction *f; @@ -1535,6 +1580,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_fishing_does_not_give_goblins_money); SUITE_ADD_TEST(suite, test_fishing_gets_reset); SUITE_ADD_TEST(suite, test_unit_limit); + SUITE_ADD_TEST(suite, test_limit_new_units); SUITE_ADD_TEST(suite, test_update_guards); SUITE_ADD_TEST(suite, test_newbie_cannot_guard); SUITE_ADD_TEST(suite, test_unarmed_cannot_guard); From 4c21ff5d6317c11dc3cf57b2c3e8e1d72372b1d9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 11 Mar 2017 20:30:17 +0100 Subject: [PATCH 058/218] BUG 2311: enforce all unit limits. --- src/give.test.c | 1 + src/kernel/alliance.c | 28 +++++++++++++++++++++++++++- src/kernel/alliance.h | 2 +- src/kernel/alliance.test.c | 24 ++++++++++++++++++++++++ src/laws.c | 14 ++------------ 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/give.test.c b/src/give.test.c index 604e42549..33a9ebfd9 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -88,6 +88,7 @@ static void test_give_unit_limits(CuTest * tc) { CuAssertIntEquals(tc, 0, env.f2->newbies); CuAssertIntEquals(tc, 1, env.f1->num_units); CuAssertIntEquals(tc, 1, env.f2->num_units); + CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "too_many_units_in_faction")); test_cleanup(); } diff --git a/src/kernel/alliance.c b/src/kernel/alliance.c index 0feb8407d..910670d10 100644 --- a/src/kernel/alliance.c +++ b/src/kernel/alliance.c @@ -239,8 +239,25 @@ static void perform_transfer(void) } } +bool num_units_cb(void *entry, void *more) { + faction *f = (faction *)entry; + int *num = (int *)more; + *num += f->num_units; + return true; +} + +int alliance_size(const alliance *al) +{ + int num = 0; + if (al) { + selist_foreach_ex(al->members, num_units_cb, &num); + } + return num; +} + static void perform_join(void) { + int alimit = rule_alliance_limit(); alliance_transaction **tap = transactions + ALLIANCE_JOIN; while (*tap) { alliance_transaction *ta = *tap; @@ -270,7 +287,16 @@ static void perform_join(void) ti = *tip; } if (ti) { - setalliance(fj, al); + int maxsize = (alimit > 0) ? (alimit - alliance_size(al)) : 0; + if (alimit > 0 && fj->num_units > maxsize) { + ADDMSG(&fj->msgs, + msg_feedback(ta->u, ta->ord, + "too_many_units_in_alliance", + "allowed", alimit)); + } + else { + setalliance(fj, al); + } *tip = ti->next; free(ti); } diff --git a/src/kernel/alliance.h b/src/kernel/alliance.h index 8e112e8c9..00b4b29e4 100644 --- a/src/kernel/alliance.h +++ b/src/kernel/alliance.h @@ -67,7 +67,7 @@ extern "C" { struct faction *alliance_get_leader(struct alliance *al); void alliance_cmd(void); bool is_allied(const struct faction *f1, const struct faction *f2); - + int alliance_size(const struct alliance *al); /* #units in the alliance */ void alliance_setname(alliance * self, const char *name); /* execute commands */ diff --git a/src/kernel/alliance.test.c b/src/kernel/alliance.test.c index f63767672..885bc8413 100644 --- a/src/kernel/alliance.test.c +++ b/src/kernel/alliance.test.c @@ -112,6 +112,29 @@ static void test_alliance_cmd(CuTest *tc) { test_cleanup(); } +static void test_alliance_limits(CuTest *tc) { + unit *u1, *u2; + struct region *r; + + test_setup(); + r = test_create_region(0, 0, 0); + u1 = test_create_unit(test_create_faction(0), r); + u2 = test_create_unit(test_create_faction(0), r); + + config_set("rules.limit.alliance", "1"); + unit_addorder(u1, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_NEW], itoa36(42))); + unit_addorder(u1, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_INVITE], itoa36(u2->faction->no))); + unit_addorder(u2, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_JOIN], itoa36(42))); + CuAssertTrue(tc, !is_allied(u1->faction, u2->faction)); + CuAssertPtrEquals(tc, 0, f_get_alliance(u1->faction)); + alliance_cmd(); + CuAssertPtrNotNull(tc, f_get_alliance(u1->faction)); + CuAssertPtrEquals(tc, 0, f_get_alliance(u2->faction)); + CuAssertTrue(tc, !is_allied(u1->faction, u2->faction)); + CuAssertPtrNotNull(tc, test_find_messagetype(u2->faction->msgs, "too_many_units_in_alliance")); + test_cleanup(); +} + static void test_alliance_cmd_kick(CuTest *tc) { unit *u1, *u2; struct region *r; @@ -200,6 +223,7 @@ CuSuite *get_alliance_suite(void) SUITE_ADD_TEST(suite, test_alliance_dead_faction); SUITE_ADD_TEST(suite, test_alliance_make); SUITE_ADD_TEST(suite, test_alliance_join); + SUITE_ADD_TEST(suite, test_alliance_limits); SUITE_ADD_TEST(suite, test_alliance_cmd); SUITE_ADD_TEST(suite, test_alliance_cmd_no_invite); SUITE_ADD_TEST(suite, test_alliance_cmd_kick); diff --git a/src/laws.c b/src/laws.c index 9c25ac461..736510cd2 100644 --- a/src/laws.c +++ b/src/laws.c @@ -3028,20 +3028,10 @@ int checkunitnumber(const faction * f, int add) alimit = rule_alliance_limit(); if (alimit) { - faction *f2; - int unitsinalliance = fno; - if (unitsinalliance > alimit) { + int unitsinalliance = alliance_size(f->alliance); + if (unitsinalliance + add > alimit) { return 1; } - - for (f2 = factions; f2; f2 = f2->next) { - if (f != f2 && f->alliance == f2->alliance) { - unitsinalliance += f2->num_units; - if (unitsinalliance > alimit) { - return 1; - } - } - } } return 0; From ae41cafcb49a6b0c8d6eb8cda1345d650d4b557d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 12 Mar 2017 11:19:40 +0100 Subject: [PATCH 059/218] fix double free in new lighthouse code --- CHANGELOG.md | 16 ++++++++++++++++ src/reports.c | 1 - 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..16ec084e0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,16 @@ +# Geplante Aenderungen in zukuenftigen Eressea-Versionen + +Als Anhaltspunkt fuer die Empfaenger der woechentlichen Testauswertungnen +will ich versuchen, die Liste meiner Aenderungen seit dem letzten Release +zu dokumentieren. + +## Version 3.12.0 + +- [other] optimierte Berechnung der Sichtbarkeit von Leuchttuermen +- [bug] Einheitenlimit bei GIB PERSON beachten +- [bug] Einheitenlimit bei ALLIANCE JOIN beachten +- [rule] Einheiten- und Personenzahl im Report beinhaltet *alle* Einheiten der Partei. +- [other] Statistik fuer Spielleiter zeigt das Parteisilber nicht mehr an. +- [other] Berechnung der Message-Ids optimiert. + + diff --git a/src/reports.c b/src/reports.c index 1e4e43061..88f6ebb21 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1242,7 +1242,6 @@ static void prepare_lighthouse_ql(faction *f, selist *rlist) { add_seen_nb(f, rl, seen_lighthouse); } } - selist_free(rlist); } static void prepare_lighthouse(faction *f, region *r, int range) From 39ec03b2af3995cd76efab8db16a58b15061c129 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 12 Mar 2017 12:02:29 +0100 Subject: [PATCH 060/218] coverity CID 164473 remove logically dead code. --- src/spy.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/spy.c b/src/spy.c index c9667f7ee..08662ea8e 100644 --- a/src/spy.c +++ b/src/spy.c @@ -199,8 +199,6 @@ static bool can_set_factionstealth(const unit * u, const faction * f) } ru = ru->next; } - if (ru != NULL) - break; } mu = mu->nextF; } From 720c41c1bf35be39be6c6bf6539d03ed194a5c66 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 12 Mar 2017 12:53:10 +0100 Subject: [PATCH 061/218] reproduce bug 2313. recruiting breaks f->num_units. --- src/economy.test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/economy.test.c b/src/economy.test.c index 7163da7e1..1fca4d194 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -316,8 +316,12 @@ static void test_recruit(CuTest *tc) { f = test_create_faction(0); u = test_create_unit(f, test_create_region(0, 0, 0)); CuAssertIntEquals(tc, 1, u->number); + CuAssertIntEquals(tc, 1, f->num_people); + CuAssertIntEquals(tc, 1, f->num_units); add_recruits(u, 1, 1); CuAssertIntEquals(tc, 2, u->number); + CuAssertIntEquals(tc, 2, f->num_people); + CuAssertIntEquals(tc, 1, f->num_units); CuAssertPtrEquals(tc, u, f->units); CuAssertPtrEquals(tc, NULL, u->nextF); CuAssertPtrEquals(tc, NULL, u->prevF); From decc38a05688fcadebcda2370fc41cac79419fa8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 12 Mar 2017 13:02:55 +0100 Subject: [PATCH 062/218] BUG 2313: proper accounting in remove_unit. https://bugs.eressea.de/view.php?id=2313 --- src/kernel/unit.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 2239cf81b..59629bc61 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -438,8 +438,11 @@ int remove_unit(unit ** ulist, unit * u) *ulist = u->next; } - if (u->faction && u->faction->units == u) { - u->faction->units = u->nextF; + if (u->faction) { + --u->faction->num_units; + if (u->faction->units == u) { + u->faction->units = u->nextF; + } } if (u->prevF) { u->prevF->nextF = u->nextF; From d8e5feac61b36192fb3bc0ae377b09013422f793 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 12 Mar 2017 13:23:40 +0100 Subject: [PATCH 063/218] additional test for bug 2313. do not count spells toward num_unit or num_people. --- src/kernel/unit.test.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index e1654b821..3932bb239 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -519,6 +519,39 @@ static void test_heal_factor(CuTest *tc) { test_cleanup(); } +static void test_unlimited_units(CuTest *tc) { + race *rc; + faction *f; + unit *u; + + test_setup(); + f = test_create_faction(NULL); + rc = test_create_race("spell"); + rc->flags |= RCF_INVISIBLE; + CuAssertIntEquals(tc, 0, f->num_units); + CuAssertIntEquals(tc, 0, f->num_people); + u = test_create_unit(f, test_create_region(0, 0, NULL)); +// CuAssertTrue(tc, count_unit(u)); + CuAssertIntEquals(tc, 1, f->num_units); + CuAssertIntEquals(tc, 1, f->num_people); + u_setfaction(u, NULL); + CuAssertIntEquals(tc, 0, f->num_units); + CuAssertIntEquals(tc, 0, f->num_people); + u_setfaction(u, f); + CuAssertIntEquals(tc, 1, f->num_units); + CuAssertIntEquals(tc, 1, f->num_people); + u_setrace(u, rc); + CuAssertIntEquals(tc, 0, f->num_units); + CuAssertIntEquals(tc, 0, f->num_people); + scale_number(u, 10); + CuAssertIntEquals(tc, 0, f->num_units); + CuAssertIntEquals(tc, 0, f->num_people); + u_setrace(u, f->race); + CuAssertIntEquals(tc, 1, f->num_units); + CuAssertIntEquals(tc, 10, f->num_people); + test_cleanup(); +} + CuSuite *get_unit_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -534,6 +567,7 @@ CuSuite *get_unit_suite(void) SUITE_ADD_TEST(suite, test_remove_units_with_dead_faction); SUITE_ADD_TEST(suite, test_remove_empty_units_in_region); SUITE_ADD_TEST(suite, test_names); + SUITE_ADD_TEST(suite, test_unlimited_units); SUITE_ADD_TEST(suite, test_default_name); SUITE_ADD_TEST(suite, test_skillmod); SUITE_ADD_TEST(suite, test_skill_hunger); From a93dc5459ba7f75f887b206af56d6089db990f76 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 12 Mar 2017 13:39:25 +0100 Subject: [PATCH 064/218] BUG 2313: spells must not be counted. https://bugs.eressea.de/view.php?id=2313 --- src/kernel/unit.c | 50 +++++++++++++++++++++++++++++++----------- src/kernel/unit.h | 1 + src/kernel/unit.test.c | 6 ++++- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 59629bc61..ddc8e0e4a 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -439,7 +439,9 @@ int remove_unit(unit ** ulist, unit * u) } if (u->faction) { - --u->faction->num_units; + if (count_unit(u)) { + --u->faction->num_units; + } if (u->faction->units == u) { u->faction->units = u->nextF; } @@ -1128,12 +1130,13 @@ struct building *inside_building(const struct unit *u) void u_setfaction(unit * u, faction * f) { - int cnt = u->number; if (u->faction == f) return; if (u->faction) { - --u->faction->num_units; - set_number(u, 0); + if (count_unit(u)) { + --u->faction->num_units; + u->faction->num_people -= u->number; + } join_group(u, NULL); free_orders(&u->orders); set_order(&u->thisorder, NULL); @@ -1165,14 +1168,19 @@ void u_setfaction(unit * u, faction * f) if (u->region) { update_interval(f, u->region); } - if (cnt) { - set_number(u, cnt); - } - if (f) { + if (f && count_unit(u)) { ++f->num_units; + f->num_people += u->number; } } +bool count_unit(const unit *u) +{ + const race *rc = u_race(u); + /* spells are invisible. units we cannot see do not count to our limit */ + return rc == NULL || (rc->flags & RCF_INVISIBLE) == 0; +} + void set_number(unit * u, int count) { assert(count >= 0); @@ -1181,10 +1189,10 @@ void set_number(unit * u, int count) if (count == 0) { u->flags &= ~(UFL_HERO); } - if (u->faction) { + if (u->faction && count_unit(u)) { u->faction->num_people += count - u->number; } - u->number = (unsigned short)count; + u->number = count; } void remove_skill(unit * u, skill_t sk) @@ -1487,6 +1495,8 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace, unit *u = (unit *)calloc(1, sizeof(unit)); assert(urace); + u_setrace(u, urace); + u->irace = NULL; if (f) { assert(faction_alive(f)); u_setfaction(u, f); @@ -1499,8 +1509,6 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace, } } } - u_setrace(u, urace); - u->irace = NULL; set_number(u, number); @@ -1806,7 +1814,23 @@ const struct race *u_race(const struct unit *u) void u_setrace(struct unit *u, const struct race *rc) { assert(rc); - u->_race = rc; + if (!u->faction) { + u->_race = rc; + } + else { + int n = 0; + if (count_unit(u)) { + --n; + } + u->_race = rc; + if (count_unit(u)) { + ++n; + } + if (n != 0) { + u->faction->num_units += n; + u->faction->num_people += n * u->number; + } + } } void unit_add_spell(unit * u, sc_mage * m, struct spell * sp, int level) diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 14096c872..8ae13c5e2 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -130,6 +130,7 @@ extern "C" { int weight(const struct unit *u); void renumber_unit(struct unit *u, int no); + bool count_unit(const unit *u); /* unit counts towards faction.num_units and faction.num_people */ const struct race *u_irace(const struct unit *u); const struct race *u_race(const struct unit *u); diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 3932bb239..caa8a9b5c 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -531,7 +531,7 @@ static void test_unlimited_units(CuTest *tc) { CuAssertIntEquals(tc, 0, f->num_units); CuAssertIntEquals(tc, 0, f->num_people); u = test_create_unit(f, test_create_region(0, 0, NULL)); -// CuAssertTrue(tc, count_unit(u)); + CuAssertTrue(tc, count_unit(u)); CuAssertIntEquals(tc, 1, f->num_units); CuAssertIntEquals(tc, 1, f->num_people); u_setfaction(u, NULL); @@ -541,6 +541,7 @@ static void test_unlimited_units(CuTest *tc) { CuAssertIntEquals(tc, 1, f->num_units); CuAssertIntEquals(tc, 1, f->num_people); u_setrace(u, rc); + CuAssertTrue(tc, !count_unit(u)); CuAssertIntEquals(tc, 0, f->num_units); CuAssertIntEquals(tc, 0, f->num_people); scale_number(u, 10); @@ -549,6 +550,9 @@ static void test_unlimited_units(CuTest *tc) { u_setrace(u, f->race); CuAssertIntEquals(tc, 1, f->num_units); CuAssertIntEquals(tc, 10, f->num_people); + remove_unit(&u->region->units, u); + CuAssertIntEquals(tc, 0, f->num_units); + CuAssertIntEquals(tc, 0, f->num_people); test_cleanup(); } From 627f5ba2d159e2b3efa1970bb3ec030e8c93e7a8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 12 Mar 2017 14:18:42 +0100 Subject: [PATCH 065/218] BUG 2313: summary should not reset num_people. it did not count spells correctly. --- src/summary.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/summary.c b/src/summary.c index 71bb30efc..1f4933696 100644 --- a/src/summary.c +++ b/src/summary.c @@ -394,7 +394,6 @@ summary *make_summary(void) } ++plang->number; f->nregions = 0; - f->num_people = 0; if (f->units) { s->factions++; /* Problem mit Monsterpartei ... */ @@ -476,7 +475,6 @@ summary *make_summary(void) } } - f->num_people += u->number; orace = (int)old_race(u_race(u)); if (orace >= 0) { s->poprace[orace] += u->number; From 7b4550b9d6498f527c14fd39d5404e3cce3a9f25 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 12 Mar 2017 14:20:34 +0100 Subject: [PATCH 066/218] kill faction.nregions, it is calculated but never read. --- src/kernel/faction.h | 1 - src/summary.c | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 9b290e5da..c6afc767c 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -81,7 +81,6 @@ extern "C" { int options; struct ally *allies; /* alliedgroup and others should check sf.faction.alive before using a faction from f.allies */ struct group *groups; /* alliedgroup and others should check sf.faction.alive before using a faction from f.groups */ - int nregions; score_t score; struct alliance *alliance; int alliance_joindate; /* the turn on which the faction joined its current alliance (or left the last one) */ diff --git a/src/summary.c b/src/summary.c index 1f4933696..aafdfe081 100644 --- a/src/summary.c +++ b/src/summary.c @@ -393,7 +393,6 @@ summary *make_summary(void) plang->locale = lang; } ++plang->number; - f->nregions = 0; if (f->units) { s->factions++; /* Problem mit Monsterpartei ... */ @@ -432,11 +431,6 @@ summary *make_summary(void) s->peasants += rpeasants(r); s->peasantmoney += rmoney(r); - /* Einheiten Info. nregions darf nur einmal pro Partei - * incrementiert werden. */ - - for (u = r->units; u; u = u->next) - freset(u->faction, FFL_SELECT); for (u = r->units; u; u = u->next) { int orace; f = u->faction; @@ -469,10 +463,6 @@ summary *make_summary(void) if (aktskill > s->maxskill) s->maxskill = aktskill; } - if (!fval(f, FFL_SELECT)) { - f->nregions++; - fset(f, FFL_SELECT); - } } orace = (int)old_race(u_race(u)); From 4b88a5abc76ed07d683d14326f2c8e624170f8f2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 12 Mar 2017 19:48:44 +0100 Subject: [PATCH 067/218] BUG 2301: validate [game] section in eressea.ini load_inifile is old stuff, should use config_get instead. --- src/kernel/config.c | 22 ++++++++++++++++++++++ src/main.c | 14 ++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/kernel/config.c b/src/kernel/config.c index a18fc6494..4d4a0e601 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -732,6 +732,17 @@ bool config_changed(int *cache_key) { return false; } +static const char * valid_keys[] = { + "game.id", + "game.name", + "game.locale", + "game.verbose", + "game.email", + "game.mailcmd", + "game.sender", + NULL +}; + #define MAXKEYS 16 void config_set_from(const dictionary *d) { @@ -742,6 +753,8 @@ void config_set_from(const dictionary *d) int k, nkeys = iniparser_getsecnkeys(d, sec); const char *keys[MAXKEYS]; size_t slen = strlen(sec); + bool check = strcmp(sec, "game") == 0; + assert(nkeys <= MAXKEYS); assert(slen Date: Sun, 12 Mar 2017 21:03:38 +0100 Subject: [PATCH 068/218] require that main.c declare any ini variables that we might expect. --- src/kernel/config.c | 21 ++++------------- src/kernel/config.h | 2 +- src/kernel/config.test.c | 2 +- src/main.c | 50 +++++++++++++++++++++++++--------------- 4 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/kernel/config.c b/src/kernel/config.c index 4d4a0e601..67dddb11e 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -732,19 +732,8 @@ bool config_changed(int *cache_key) { return false; } -static const char * valid_keys[] = { - "game.id", - "game.name", - "game.locale", - "game.verbose", - "game.email", - "game.mailcmd", - "game.sender", - NULL -}; - #define MAXKEYS 16 -void config_set_from(const dictionary *d) +void config_set_from(const dictionary *d, const char *valid_keys[]) { int s, nsec = iniparser_getnsec(d); for (s=0;s!=nsec;++s) { @@ -753,7 +742,6 @@ void config_set_from(const dictionary *d) int k, nkeys = iniparser_getsecnkeys(d, sec); const char *keys[MAXKEYS]; size_t slen = strlen(sec); - bool check = strcmp(sec, "game") == 0; assert(nkeys <= MAXKEYS); assert(slen Date: Mon, 13 Mar 2017 09:19:37 +0100 Subject: [PATCH 069/218] remove data_turn and gamename from global settings. make run-turn.sh work without valgrind --- conf/eressea.ini | 2 -- src/kernel/config.c | 6 ++---- src/kernel/config.h | 2 -- src/kernel/save.c | 3 +-- src/summary.c | 1 - tests/run-turn.sh | 5 +++-- 6 files changed, 6 insertions(+), 13 deletions(-) diff --git a/conf/eressea.ini b/conf/eressea.ini index b6db180ca..c745631ad 100644 --- a/conf/eressea.ini +++ b/conf/eressea.ini @@ -2,11 +2,9 @@ email = eressea-server@kn-bremen.de sender = Eressea Server name = Eressea -base = . report = reports verbose = 0 lomem = 0 -debug = 0 memcheck = 0 locales = de,en diff --git a/src/kernel/config.c b/src/kernel/config.c index 67dddb11e..3bbb0fd69 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -93,9 +93,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -struct settings global = { - "Eressea", /* gamename */ -}; +struct settings global; bool lomem = false; int turn = -1; @@ -841,7 +839,7 @@ void free_gamedata(void) const char * game_name(void) { const char * param = config_get("game.name"); - return param ? param : global.gamename; + return param ? param : "Eressea"; } const char * game_mailcmd(void) diff --git a/src/kernel/config.h b/src/kernel/config.h index 1fc70cd5b..86eda7c5c 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -108,9 +108,7 @@ extern "C" { /* globale settings des Spieles */ typedef struct settings { - const char *gamename; struct attrib *attribs; - unsigned int data_turn; void *vm_state; struct global_functions { int(*wage) (const struct region * r, const struct faction * f, diff --git a/src/kernel/save.c b/src/kernel/save.c index 5be078d8a..2e1686f2a 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -244,7 +244,7 @@ static faction *factionorders(void) /* TODO: +1 ist ein Workaround, weil cturn erst in process_orders * incrementiert wird. */ - f->lastorders = global.data_turn + 1; + f->lastorders = turn + 1; } else { @@ -1633,7 +1633,6 @@ int read_game(gamedata *data) { } read_attribs(data, &global.attribs, NULL); READ_INT(store, &turn); - global.data_turn = turn; log_debug(" - reading turn %d", turn); rng_init(turn); READ_INT(store, NULL); /* max_unique_id = ignore */ diff --git a/src/summary.c b/src/summary.c index aafdfe081..c18e54ee5 100644 --- a/src/summary.c +++ b/src/summary.c @@ -76,7 +76,6 @@ int update_nmrs(void) { int i, newplayers = 0; faction *f; - int turn = global.data_turn; int timeout = NMRTimeout(); if (timeout>0) { diff --git a/tests/run-turn.sh b/tests/run-turn.sh index 9297278c3..fd6eb63ee 100755 --- a/tests/run-turn.sh +++ b/tests/run-turn.sh @@ -28,12 +28,12 @@ while [ ! -d $ROOT/.git ]; do ROOT=`dirname $ROOT` done -set -e cd $ROOT/tests setup cleanup VALGRIND=`which valgrind` SERVER=../Debug/eressea/eressea +set -e if [ -n "$VALGRIND" ]; then SUPP=../share/ubuntu-12_04.supp SERVER="$VALGRIND --track-origins=yes --gen-suppressions=all --suppressions=$SUPP --error-exitcode=1 --leak-check=no $SERVER" @@ -53,6 +53,7 @@ assert_grep_count reports/$CRFILE '^BURG' 1 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 @@ -62,4 +63,4 @@ 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 echo "integration tests: PASS" -#cleanup +cleanup From 8d8173def3fefdb02aaaa9058f2019ccc9ace76a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 13 Mar 2017 09:30:20 +0100 Subject: [PATCH 070/218] remove the functions struct from settings (next: remove wage, too) --- src/kernel/building.c | 4 ++-- src/kernel/config.c | 2 +- src/kernel/config.h | 6 ++---- src/kernel/xmlreader.c | 2 +- src/laws.test.c | 6 +++--- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 6d0db8f43..1a9e826e6 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -811,8 +811,8 @@ minimum_wage(const region * r, const faction * f, const race * rc, int in_turn) * die Bauern wenn f == NULL. */ int wage(const region * r, const faction * f, const race * rc, int in_turn) { - if (global.functions.wage) { - return global.functions.wage(r, f, rc, in_turn); + if (global.wage) { + return global.wage(r, f, rc, in_turn); } return default_wage(r, f, rc, in_turn); } diff --git a/src/kernel/config.c b/src/kernel/config.c index 3bbb0fd69..6d84a7c73 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -796,7 +796,7 @@ bool config_token(const char *key, const char *tok) { } void free_config(void) { - global.functions.wage = NULL; + global.wage = NULL; free_params(&configuration); ++config_cache_key; } diff --git a/src/kernel/config.h b/src/kernel/config.h index 86eda7c5c..c8c2e4be9 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -110,10 +110,8 @@ extern "C" { typedef struct settings { struct attrib *attribs; void *vm_state; - struct global_functions { - int(*wage) (const struct region * r, const struct faction * f, - const struct race * rc, int in_turn); - } functions; + int(*wage) (const struct region * r, const struct faction * f, + const struct race * rc, int in_turn); } settings; void set_param(struct param **p, const char *key, const char *value); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 4db528853..dcaf97580 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -907,7 +907,7 @@ static int parse_rules(xmlDocPtr doc) } assert(propValue != NULL); if (strcmp((const char *)propValue, "wage") == 0) { - global.functions.wage = + global.wage = (int(*)(const struct region *, const struct faction *, const struct race *, int))fun; } diff --git a/src/laws.test.c b/src/laws.test.c index e8391b67c..9ed457af7 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1452,7 +1452,7 @@ static void test_immigration(CuTest * tc) { region *r; double inject[] = { 1 }; - int (*old_wage)(const region*, const faction*, const race*, int) = global.functions.wage; + int (*old_wage)(const region*, const faction*, const race*, int) = global.wage; test_setup(); r = test_create_region(0, 0, 0); @@ -1472,10 +1472,10 @@ static void test_immigration(CuTest * tc) random_source_inject_array(inject, 2); - global.functions.wage = low_wage; + global.wage = low_wage; immigration(); CuAssertIntEquals(tc, 2, rpeasants(r)); - global.functions.wage = old_wage; + global.wage = old_wage; test_cleanup(); } From e68510a07eafc0708cecc4e80392e3b1621ed993 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 15 Mar 2017 21:30:53 +0100 Subject: [PATCH 071/218] use report locae, not default, for EFFECTS and GRENZE --- src/creport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/creport.c b/src/creport.c index fd307c5ec..aeeb52042 100644 --- a/src/creport.c +++ b/src/creport.c @@ -276,7 +276,7 @@ cr_output_curses(struct stream *out, const faction * viewer, const void *obj, ob stream_printf(out, "EFFECTS\n"); } stream_printf(out, "\"%d %s\"\n", data->value, translate(key, - LOC(default_locale, key))); + LOC(viewer->locale, key))); } a = a->next; } @@ -1148,7 +1148,7 @@ cr_borders(const region * r, const faction * f, seen_mode mode, FILE * F) const char *bname = border_name(b, r, f, GF_PURE); bname = mkname("border", bname); fprintf(F, "GRENZE %d\n", ++g); - fprintf(F, "\"%s\";typ\n", LOC(default_locale, bname)); + fprintf(F, "\"%s\";typ\n", LOC(f->locale, bname)); fprintf(F, "%d;richtung\n", d); if (!b->type->transparent(b, f)) fputs("1;opaque\n", F); From 67a566d728b32fd266e59cf42486c22d7d375418 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 14 Mar 2017 08:27:15 +0100 Subject: [PATCH 072/218] remove CRTAG_LOCLE define and lookups --- src/creport.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/creport.c b/src/creport.c index aeeb52042..14e6e8faa 100644 --- a/src/creport.c +++ b/src/creport.c @@ -87,19 +87,23 @@ bool opt_cr_absolute_coords = false; /* globals */ #define C_REPORT_VERSION 66 -#define TAG_LOCALE "de" -#ifdef TAG_LOCALE +struct locale *crtag_locale(void) { + static struct locale * lang; + static int config; + if (config_changed(&config)) { + const char *lname = config_get("creport.tags"); + lang = get_locale(lname ? lname : "de"); + } + return lang; +} + static const char *crtag(const char *key) { /* TODO: those locale lookups are shit, but static kills testing */ const char *result; - const struct locale *lang = get_locale(TAG_LOCALE); - result = LOC(lang, key); + result = LOC(crtag_locale(), key); return result; } -#else -#define crtag(x) (x) -#endif /* * translation table */ @@ -134,7 +138,7 @@ static const char *translate(const char *key, const char *value) return crtag(key); } -static void write_translations(FILE * F) +static void report_translations(FILE * F) { int i; fputs("TRANSLATION\n", F); @@ -1680,7 +1684,9 @@ report_computer(const char *filename, report_context * ctx, const char *bom) } } report_crtypes(F, f->locale); - write_translations(F); + if (f->locale!=crtag_locale()) { + report_translations(F); + } reset_translations(); fclose(F); return 0; From ac12cb966d02c595cd616387d932486caa7593bd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 16 Mar 2017 16:07:52 +0100 Subject: [PATCH 073/218] implement fixed wage functions, select by constant value --- conf/e3/config.json | 1 + conf/e3/rules.xml | 3 --- src/kernel/building.c | 15 +++++++++++---- src/kernel/config.c | 1 - src/kernel/config.h | 2 -- src/kernel/xmlreader.c | 40 ---------------------------------------- src/laws.test.c | 8 +------- 7 files changed, 13 insertions(+), 57 deletions(-) diff --git a/conf/e3/config.json b/conf/e3/config.json index 1cecc89d2..a42961e03 100644 --- a/conf/e3/config.json +++ b/conf/e3/config.json @@ -56,6 +56,7 @@ "seed.population.max": 8, "rules.reserve.twophase": true, "rules.owners.force_leave": false, + "rules.wage.function": 2, "rules.monsters.attack_chance": 0.1, "rules.transfermen": false, "stealth.faction.other": false, diff --git a/conf/e3/rules.xml b/conf/e3/rules.xml index 421b54d7a..d59787551 100644 --- a/conf/e3/rules.xml +++ b/conf/e3/rules.xml @@ -28,7 +28,4 @@ - - - diff --git a/src/kernel/building.c b/src/kernel/building.c index 1a9e826e6..64b616fdc 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -811,10 +811,18 @@ minimum_wage(const region * r, const faction * f, const race * rc, int in_turn) * die Bauern wenn f == NULL. */ int wage(const region * r, const faction * f, const race * rc, int in_turn) { - if (global.wage) { - return global.wage(r, f, rc, in_turn); + static int config; + static int rule_wage; + if (config_changed(&config)) { + rule_wage = config_get_int("rules.wage.function", 1); } - return default_wage(r, f, rc, in_turn); + if (rule_wage==0) { + return 0; + } + if (rule_wage==1) { + return default_wage(r, f, rc, in_turn); + } + return minimum_wage(r, f, rc, in_turn); } int cmp_wage(const struct building *b, const building * a) @@ -913,7 +921,6 @@ int cmp_current_owner(const building * b, const building * a) void register_buildings(void) { - register_function((pf_generic)minimum_wage, "minimum_wage"); register_function((pf_generic)init_smithy, "init_smithy"); register_function((pf_generic)castle_name, "castle_name"); register_function((pf_generic)castle_name_2, "castle_name_2"); diff --git a/src/kernel/config.c b/src/kernel/config.c index 6d84a7c73..4b3ab5a91 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -796,7 +796,6 @@ bool config_token(const char *key, const char *tok) { } void free_config(void) { - global.wage = NULL; free_params(&configuration); ++config_cache_key; } diff --git a/src/kernel/config.h b/src/kernel/config.h index c8c2e4be9..a4378332d 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -110,8 +110,6 @@ extern "C" { typedef struct settings { struct attrib *attribs; void *vm_state; - int(*wage) (const struct region * r, const struct faction * f, - const struct race * rc, int in_turn); } settings; void set_param(struct param **p, const char *key, const char *value); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index dcaf97580..7cb871785 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -883,44 +883,6 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) return itype; } -static int parse_rules(xmlDocPtr doc) -{ - xmlXPathContextPtr xpath = xmlXPathNewContext(doc); - xmlXPathObjectPtr functions; - xmlNodeSetPtr nodes; - int i; - - /* reading eressea/resources/resource */ - functions = xmlXPathEvalExpression(BAD_CAST "/eressea/rules/function", xpath); - nodes = functions->nodesetval; - for (i = 0; i != nodes->nodeNr; ++i) { - xmlNodePtr node = nodes->nodeTab[i]; - xmlChar *propValue; - pf_generic fun; - - parse_function(node, &fun, &propValue); - - if (fun == NULL) { - log_error("unknown function for rule '%s' %s\n", (const char *)propValue); - xmlFree(propValue); - continue; - } - assert(propValue != NULL); - if (strcmp((const char *)propValue, "wage") == 0) { - global.wage = - (int(*)(const struct region *, const struct faction *, - const struct race *, int))fun; - } - else { - log_error("unknown function for rule '%s'\n", (const char *)propValue); - } - xmlFree(propValue); - } - xmlXPathFreeObject(functions); - xmlXPathFreeContext(xpath); - return 0; -} - static int parse_resources(xmlDocPtr doc) { xmlXPathContextPtr xpath = xmlXPathNewContext(doc); @@ -1960,8 +1922,6 @@ static int parse_strings(xmlDocPtr doc) void register_xmlreader(void) { - xml_register_callback(parse_rules); - xml_register_callback(parse_races); xml_register_callback(parse_calendar); xml_register_callback(parse_resources); diff --git a/src/laws.test.c b/src/laws.test.c index 9ed457af7..ce8ca2c19 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1444,15 +1444,10 @@ static void test_show_race(CuTest *tc) { test_cleanup(); } -static int low_wage(const region * r, const faction * f, const race * rc, int in_turn) { - return 1; -} - static void test_immigration(CuTest * tc) { region *r; double inject[] = { 1 }; - int (*old_wage)(const region*, const faction*, const race*, int) = global.wage; test_setup(); r = test_create_region(0, 0, 0); @@ -1472,10 +1467,9 @@ static void test_immigration(CuTest * tc) random_source_inject_array(inject, 2); - global.wage = low_wage; + config_set("rules.wage.function", "0"); immigration(); CuAssertIntEquals(tc, 2, rpeasants(r)); - global.wage = old_wage; test_cleanup(); } From beb498d70ca42800ab1f30473560731127b774c9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 16 Mar 2017 19:40:51 +0100 Subject: [PATCH 074/218] remove leftover code/data for artrewards. --- res/core/messages.xml | 18 ------------------ src/kernel/building.c | 7 ------- 2 files changed, 25 deletions(-) diff --git a/res/core/messages.xml b/res/core/messages.xml index 32d8e35a6..42b95bc4c 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -7678,24 +7678,6 @@ "$unit($unit) plays the bagpipe. Stricken with fear the peasants give $int($money) silver." - - - - - - "$unit($unit) in $region($region) erschafft eine Akademie der Künste." - "$unit($unit) in $region($region) creates an academy of arts." - - - - - - - - "$unit($unit) in $region($region) erschafft eine Skulptur." - "$unit($unit) in $region($region) creates a sculpture." - - diff --git a/src/kernel/building.c b/src/kernel/building.c index 64b616fdc..8fdfee544 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -767,13 +767,6 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn) } } - /* Artsculpture: Income +5 */ - for (b = r->buildings; b; b = b->next) { - if (is_building_type(b->type, "artsculpture")) { - wage += 5; - } - } - if (r->attribs) { attrib *a; const struct curse_type *ctype; From 4c67e0603b662caad9ca33f342e327affa52c4fd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 17 Mar 2017 22:31:59 +0100 Subject: [PATCH 075/218] remove attribs from rtype (it's only in rtype->construction that we use it?) test to verify that mine bonus for iron works as advertised. change the oder of arguments for faction.create (race is the only thing not optional). --- scripts/eressea/autoseed.lua | 2 +- scripts/tests/common.lua | 98 ++++++++++++++++---------------- scripts/tests/config.lua | 2 +- scripts/tests/e2/destroy.lua | 8 +-- scripts/tests/e2/e2features.lua | 32 +++++------ scripts/tests/e2/guard.lua | 12 ++-- scripts/tests/e2/items.lua | 16 +++--- scripts/tests/e2/movement.lua | 14 ++--- scripts/tests/e2/shiplanding.lua | 22 +++---- scripts/tests/e2/ships.lua | 4 +- scripts/tests/e2/spells.lua | 2 +- scripts/tests/e2/stealth.lua | 4 +- scripts/tests/e2/undead.lua | 4 +- scripts/tests/e3/castles.lua | 12 ++-- scripts/tests/e3/items.lua | 10 ++-- scripts/tests/e3/morale.lua | 18 +++--- scripts/tests/e3/parser.lua | 6 +- scripts/tests/e3/rules.lua | 82 +++++++++++++------------- scripts/tests/e3/spells-e2.lua | 2 +- scripts/tests/e3/spells.lua | 4 +- scripts/tests/e3/stealth.lua | 4 +- scripts/tests/economy.lua | 44 ++++++++++++++ scripts/tests/faction.lua | 2 +- scripts/tests/items.lua | 20 +++---- scripts/tests/laws.lua | 14 ++--- scripts/tests/magicbag.lua | 2 +- scripts/tests/movement.lua | 12 ++-- scripts/tests/orders.lua | 2 +- scripts/tests/pool.lua | 8 +-- scripts/tests/process.lua | 2 +- scripts/tests/report.lua | 12 ++-- scripts/tests/storage.lua | 4 +- scripts/tests/study.lua | 14 ++--- scripts/tests/xmas.lua | 10 ++-- src/bind_faction.c | 4 +- src/economy.c | 2 +- src/kernel/building.c | 1 + src/kernel/item.h | 1 - src/kernel/skills.h | 6 ++ 39 files changed, 284 insertions(+), 234 deletions(-) diff --git a/scripts/eressea/autoseed.lua b/scripts/eressea/autoseed.lua index 9e5060f85..2896708f8 100644 --- a/scripts/eressea/autoseed.lua +++ b/scripts/eressea/autoseed.lua @@ -61,7 +61,7 @@ end local function seed(r, email, race, lang) assert(r) - local f = faction.create(email, race, lang) + local f = faction.create(race, email, lang) assert(f) local u = unit.create(f, r) assert(u) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 4f6ed9cbb..dc449903d 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -17,8 +17,8 @@ local function two_units(r, f1, f2) end local function two_factions() - local f1 = faction.create("one@eressea.de", "human", "de") - local f2 = faction.create("two@eressea.de", "elf", "de") + local f1 = faction.create("human", "one@eressea.de", "de") + local f2 = faction.create("elf", "two@eressea.de", "de") return f1, f2 end @@ -44,7 +44,7 @@ end function test_flags() local r = region.create(0, 0, "plain") - local f = faction.create("flags@eressea.de", "halfling", "de") + local f = faction.create("halfling", "flags@eressea.de", "de") local u = unit.create(f, r, 1) local no = itoa36(f.id) local flags = 50332673 @@ -62,7 +62,7 @@ function test_elvenhorse_requires_riding_5() local r = region.create(0, 0, "plain") region.create(1, 0, "plain") local goal = region.create(2, 0, "plain") - local f = faction.create("riding@eressea.de", "halfling", "de") + local f = faction.create("halfling", "riding@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("elvenhorse", 1) u:set_skill("riding", 6)-- halfling has -1 modifier @@ -76,7 +76,7 @@ function test_cannot_ride_elvenhorse_without_enough_skill() local r = region.create(0, 0, "plain") local goal = region.create(1, 0, "plain") region.create(2, 0, "plain") - local f = faction.create("elvenhorse@eressea.de", "halfling", "de") + local f = faction.create("halfling", "elvenhorse@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("elvenhorse", 1) u:set_skill("riding", 5) -- halfling has -1 modifier @@ -96,7 +96,7 @@ end function test_demon_food() local r = region.create(0, 0, "plain") - local f = faction.create("demonfood@eressea.de", "demon", "de") + local f = faction.create("demon", "demonfood@eressea.de", "de") local u = unit.create(f, r, 1) local p = r:get_resource("peasant") r:set_resource("peasant", 2000) @@ -136,7 +136,7 @@ function test_plane() local nx, ny = plane.normalize(pl, 4, 4) assert_equal(nx, -3, "normalization failed") assert_equal(ny, -3, "normalization failed") - local f = faction.create("plan@eressea.de", "human", "de") + local f = faction.create("human", "plan@eressea.de", "de") f.id = atoi36("tpla") local r, x, y for x = -3, 3 do for y = -3, 3 do @@ -155,7 +155,7 @@ end function test_read_write() local r = region.create(0, 0, "plain") - local f = faction.create("readwrite@eressea.de", "human", "de") + local f = faction.create("human", "readwrite@eressea.de", "de") local u = unit.create(f, r) u.number = 2 local fno = f.id @@ -184,7 +184,7 @@ end function test_descriptions() local info = "Descriptions can be very long. Bug 1984 behauptet, dass es Probleme gibt mit Beschreibungen die laenger als 120 Zeichen sind. This description is longer than 120 characters." local r = region.create(0, 0, "plain") - local f = faction.create("descriptions@eressea.de", "human", "de") + local f = faction.create("human", "descriptions@eressea.de", "de") local u = unit.create(f, r, 1) local s = _test_create_ship(r) local b = building.create(r, "castle") @@ -236,7 +236,7 @@ end function test_faction() local r = region.create(0, 0, "plain") - local f = faction.create("testfaction@eressea.de", "human", "de") + local f = faction.create("human", "testfaction@eressea.de", "de") assert(f) f.info = "Spazz" assert(f.info=="Spazz") @@ -259,7 +259,7 @@ end function test_unit() local r = region.create(0, 0, "plain") - local f = faction.create("testunit@eressea.de", "human", "de") + local f = faction.create("human", "testunit@eressea.de", "de") local u = unit.create(f, r) u.number = 20 u.name = "Enno" @@ -292,7 +292,7 @@ end function test_building() local u - local f = faction.create("testbuilding@eressea.de", "human", "de") + local f = faction.create("human", "testbuilding@eressea.de", "de") local r = region.create(0, 0, "plain") local b = building.create(r, "castle") u = unit.create(f, r) @@ -318,7 +318,7 @@ end function test_message() local r = region.create(0, 0, "plain") - local f = faction.create("testmessage@eressea.de", "human", "de") + local f = faction.create("human", "testmessage@eressea.de", "de") local u = unit.create(f, r) local msg = message.create("item_create_spell") msg:set_unit("mage", u) @@ -346,7 +346,7 @@ function test_events() plain = region.create(0, 0, "plain") skill = 8 - f = faction.create("noreply2@eressea.de", "elf", "de") + f = faction.create("elf", "noreply2@eressea.de", "de") f.age = 20 u = unit.create(f, plain) @@ -356,7 +356,7 @@ function test_events() u:add_order("NUMMER PARTEI test") u:add_handler("message", msg_handler) msg = "BOTSCHAFT EINHEIT " .. itoa36(u.id) .. " Du~Elf~stinken" - f = faction.create("noreply3@eressea.de", "elf", "de") + f = faction.create("elf", "noreply3@eressea.de", "de") f.age = 20 u = unit.create(f, plain) @@ -371,7 +371,7 @@ end function test_renumber_ship() local r = region.create(0, 0, "plain") - local f = faction.create("noreply4@eressea.de", "human", "de") + local f = faction.create("human", "noreply4@eressea.de", "de") local u = unit.create(f, r) local s = ship.create(r, config.ships[1]) u.ship = s @@ -386,7 +386,7 @@ end function test_recruit2() local r = region.create(0, 0, "plain") - local f = faction.create("noreply4@eressea.de", "human", "de") + local f = faction.create("human", "noreply4@eressea.de", "de") local u = unit.create(f, r) u.number = 1 u:add_item("money", 2000) @@ -401,7 +401,7 @@ end function test_guard() region.create(1, 0, "plain") local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply5@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply5@eressea.de", "de") f1.age = 20 local u1 = unit.create(f1, r, 10) u1:add_item("sword", 10) @@ -411,7 +411,7 @@ function test_guard() u1:add_order("NACH O") u1.name="Kalle Pimp" - local f2 = faction.create("noreply6@eressea.de", "human", "de") + local f2 = faction.create("human", "noreply6@eressea.de", "de") f2.age = 20 local u2 = unit.create(f2, r, 1) local u3 = unit.create(f2, r, 1) @@ -429,7 +429,7 @@ end function test_recruit() local r = region.create(0, 0, "plain") - local f = faction.create("noreply7@eressea.de", "human", "de") + local f = faction.create("human", "noreply7@eressea.de", "de") local u = unit.create(f, r) u.number = 1 local n = 3 @@ -445,7 +445,7 @@ end function test_produce() local r = region.create(0, 0, "plain") - local f = faction.create("noreply8@eressea.de", "human", "de") + local f = faction.create("human", "noreply8@eressea.de", "de") local u = unit.create(f, r, 1) u:clear_orders() local sword = config.get_resource('sword') @@ -460,7 +460,7 @@ end function test_work() local r = region.create(0, 0, "plain") - local f = faction.create("noreply9@eressea.de", "human", "de") + local f = faction.create("human", "noreply9@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("money", u.number * 10) -- humans cost 10 u:set_skill("herbalism", 5) @@ -473,7 +473,7 @@ end function test_upkeep() eressea.settings.set("rules.food.flags", "0") local r = region.create(0, 0, "plain") - local f = faction.create("noreply10@eressea.de", "human", "de") + local f = faction.create("human", "noreply10@eressea.de", "de") local u = unit.create(f, r, 5) u:add_item("money", u.number * 11) u:clear_orders() @@ -485,7 +485,7 @@ end function test_id() local r = region.create(0, 0, "plain") - local f = faction.create("noreply11@eressea.de", "human", "de") + local f = faction.create("human", "noreply11@eressea.de", "de") f.id = atoi36("42") assert_not_equal(f, get_faction(42)) assert_equal(f, get_faction("42")) @@ -521,7 +521,7 @@ function test_mallorn() m:set_resource("tree", 100) assert_equal(100, m:get_resource("tree")) - local f = faction.create("noreply13@eressea.de", "human", "de") + local f = faction.create("human", "noreply13@eressea.de", "de") local u1 = unit.create(f, r, 1) u1:add_item("money", u1.number * 100) @@ -558,7 +558,7 @@ function test_coordinate_translation() local pl = plane.create(1, 500, 500, 1001, 1001) -- astralraum local pe = plane.create(1, -8761, 3620, 23, 23) -- eternath local r = region.create(1000, 1000, "plain") - local f = faction.create("noreply14@eressea.de", "human", "de") + local f = faction.create("human", "noreply14@eressea.de", "de") assert_not_equal(nil, r) assert_equal(r.x, 1000) assert_equal(r.y, 1000) @@ -604,8 +604,8 @@ end function test_building_other() local r = region.create(0,0, "plain") - local f1 = faction.create("noreply17@eressea.de", "human", "de") - local f2 = faction.create("noreply18@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply17@eressea.de", "de") + local f2 = faction.create("human", "noreply18@eressea.de", "de") local b = building.create(r, "castle") b.size = 10 local u1 = unit.create(f1, r, 3) @@ -632,7 +632,7 @@ end local function _test_create_laen() eressea.settings.set("rules.terraform.all", "1") local r = region.create(0,0, "mountain") - local f1 = faction.create("noreply19@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply19@eressea.de", "de") local u1 = unit.create(f1, r, 1) r:set_resource("laen", 50) return r, u1 @@ -671,7 +671,7 @@ end function test_mine() local r = region.create(0,0, "mountain") - local f1 = faction.create("noreply20@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply20@eressea.de", "de") local u1 = unit.create(f1, r, 1) u1:add_item("money", 1000) @@ -692,9 +692,9 @@ end function test_guard_resources() -- this is not quite http://bugs.eressea.de/view.php?id=1756 local r = region.create(0,0, "mountain") - local f1 = faction.create("noreply21@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply21@eressea.de", "de") f1.age=20 - local f2 = faction.create("noreply22@eressea.de", "human", "de") + local f2 = faction.create("human", "noreply22@eressea.de", "de") f2.age=20 local u1 = unit.create(f1, r, 1) u1:add_item("money", 100) @@ -722,7 +722,7 @@ end function test_hero_hero_transfer() local r = region.create(0,0, "mountain") - local f = faction.create("noreply23@eressea.de", "human", "de") + local f = faction.create("human", "noreply23@eressea.de", "de") f.age=20 local UFL_HERO = 128 @@ -743,7 +743,7 @@ end function test_hero_normal_transfer() local r = region.create(0,0, "mountain") - local f = faction.create("noreply24@eressea.de", "human", "de") + local f = faction.create("human", "noreply24@eressea.de", "de") f.age=20 local UFL_HERO = 128 @@ -762,7 +762,7 @@ end function test_expensive_skills_cost_money() local r = region.create(0,0, "mountain") - local f = faction.create("noreply25@eressea.de", "elf", "de") + local f = faction.create("elf", "noreply25@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("money", 10000) u:clear_orders() @@ -775,7 +775,7 @@ end function test_food_is_consumed() local r = region.create(0, 0, "plain") - local f = faction.create("noreply26@eressea.de", "human", "de") + local f = faction.create("human", "noreply26@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("money", 100) u:clear_orders() @@ -787,7 +787,7 @@ end function test_food_can_override() local r = region.create(0, 0, "plain") - local f = faction.create("noreply27@eressea.de", "human", "de") + local f = faction.create("human", "noreply27@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("money", 100) u:clear_orders() @@ -799,7 +799,7 @@ end function test_swim_and_survive() local r = region.create(0, 0, "plain") - local f = faction.create("noreply28@eressea.de", "human", "de") + local f = faction.create("human", "noreply28@eressea.de", "de") f.nam = "chaos" local u = unit.create(f, r, 1) process_orders() @@ -813,7 +813,7 @@ end function test_swim_and_die() local r = region.create(0, 0, "plain") - local f = faction.create("noreply29@eressea.de", "human", "de") + local f = faction.create("human", "noreply29@eressea.de", "de") local u = unit.create(f, r, 1) local uid = u.id process_orders() @@ -828,7 +828,7 @@ function test_ride_with_horse() region.create(1, 0, "plain") region.create(2, 0, "plain") local r = region.create(0, 0, "plain") - local f = faction.create("noreply30@eressea.de", "human", "de") + local f = faction.create("human", "noreply30@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("horse", 1) local horse_cfg = config.get_resource("horse") @@ -851,7 +851,7 @@ function test_ride_with_horses_and_cart() region.create(1, 0, "plain") region.create(2, 0, "plain") local r = region.create(0, 0, "plain") - local f = faction.create("noreply31@eressea.de", "human", "de") + local f = faction.create("human", "noreply31@eressea.de", "de") local u = unit.create(f, r, 1) local horse_cfg = config.get_resource("horse") local cart_cfg = config.get_resource("cart") @@ -904,7 +904,7 @@ function test_walk_and_carry_the_cart() region.create(1, 0, "plain") local r = region.create(2, 0, "plain") local r = region.create(0, 0, "plain") - local f = faction.create("noreply32@eressea.de", "human", "de") + local f = faction.create("human", "noreply32@eressea.de", "de") local u = unit.create(f, r, 10) u:add_item("cart", 1) @@ -925,7 +925,7 @@ end function test_bug_1795_limit() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u1 = one_unit(r,f) u1:add_item("money", 100000000) u1:add_order("REKRUTIEREN 9999") @@ -940,7 +940,7 @@ end function test_bug_1795_demons() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "demon", "de") + local f = faction.create("demon", "noreply@eressea.de", "de") local u1 = one_unit(r,f) r:set_resource("peasant", 2000) local peasants = r:get_resource("peasant") @@ -966,7 +966,7 @@ end function test_parser() local r = region.create(0, 0, "mountain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) local filename = "orders.txt" @@ -991,7 +991,7 @@ end function test_prefix() local r0 = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f1, r0, 1) set_order(u1, "PRAEFIX See") @@ -1018,7 +1018,7 @@ end function test_recruit() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("money", 1000) @@ -1031,7 +1031,7 @@ end function test_give_horses() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) r:set_resource("horse", 0) @@ -1047,7 +1047,7 @@ end function test_give_silver() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) r:set_resource("peasant", 0) diff --git a/scripts/tests/config.lua b/scripts/tests/config.lua index e47b7f925..a83b64350 100644 --- a/scripts/tests/config.lua +++ b/scripts/tests/config.lua @@ -11,7 +11,7 @@ function test_read_race() eressea.free_game() assert_not_nil(eressea.config) eressea.config.parse('{ "races": { "orc" : {}}}') - f = faction.create("orc@example.com", "orc", "en") + f = faction.create("orc", "orc@example.com", "en") assert_not_nil(f) end diff --git a/scripts/tests/e2/destroy.lua b/scripts/tests/e2/destroy.lua index 3f422c2e5..430ca301c 100644 --- a/scripts/tests/e2/destroy.lua +++ b/scripts/tests/e2/destroy.lua @@ -10,7 +10,7 @@ end function disabled_test_dont_move_after_destroy() local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u = unit.create(f, r1, 1) u.building = building.create(u.region, "castle") u:clear_orders() @@ -26,8 +26,8 @@ end function test_dont_destroy_after_attack() local r1 = region.create(0, 0, "plain") - local u = unit.create(faction.create("one@example.com", "human", "de"), r1, 10) - local u2 = unit.create(faction.create("two@example.com", "human", "de"), r1, 1) + local u = unit.create(faction.create("human", "one@example.com", "de"), r1, 10) + local u2 = unit.create(faction.create("human", "two@example.com", "de"), r1, 1) u.building = building.create(u.region, "castle") u:clear_orders() u:add_order("ATTACKIERE " .. itoa36(u2.id)) @@ -38,7 +38,7 @@ end function test_destroy_is_long() local r1 = region.create(0, 0, "plain") - local u = unit.create(faction.create("one@example.com", "human", "de"), r1, 10) + local u = unit.create(faction.create("human", "one@example.com", "de"), r1, 10) u.building = building.create(u.region, "castle") u:clear_orders() u:add_order("LERNE Unterhaltung") diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index f0e597770..cecd8785a 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -18,7 +18,7 @@ end function test_herbalism() -- OBS: herbalism is currently an E2-only skill local r = region.create(0, 0, "plain") - local f = faction.create("herbalism@eressea.de", "human", "de") + local f = faction.create("human", "herbalism@eressea.de", "de") local u = unit.create(f, r, 1) eressea.settings.set("rules.grow.formula", 0) -- plants do not grow @@ -42,7 +42,7 @@ end function test_build_harbour() -- try to reproduce mantis bug 2221 local r = region.create(0, 0, "plain") - local f = faction.create("harbour@eressea.de", "human", "de") + local f = faction.create("human", "harbour@eressea.de", "de") local u = unit.create(f, r) size = 30 u.number = 20 @@ -70,8 +70,8 @@ local function one_unit(r, f) end local function two_factions() - local f1 = faction.create("one@eressea.de", "human", "de") - local f2 = faction.create("two@eressea.de", "human", "de") + local f1 = faction.create("human", "one@eressea.de", "de") + local f2 = faction.create("human", "two@eressea.de", "de") return f1, f2 end @@ -82,7 +82,7 @@ end function test_learn() eressea.settings.set("study.random_progress", "0") local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") f.age = 20 local u = unit.create(f, r) u:clear_orders() @@ -101,7 +101,7 @@ end function test_teach() eressea.settings.set("study.random_progress", "0") local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") f.age = 20 local u = unit.create(f, r, 10) local u2 = unit.create(f, r) @@ -118,7 +118,7 @@ end function test_rename() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r) u:add_item("aoh", 1) assert_equal(u:get_item("ao_healing"), 1) @@ -126,7 +126,7 @@ end function test_unit_limit_is_1500() local r = region.create(0,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") for i = 1,1500 do unit.create(f, r, 1) end @@ -142,7 +142,7 @@ function test_ship_capacity() local r = region.create(0,0, "ocean") region.create(1,0, "ocean") local r2 = region.create(2,0, "ocean") - local f = faction.create("capacity@eressea.de", "human", "de") + local f = faction.create("human", "capacity@eressea.de", "de") -- u1 is at the limit and moves local s1 = ship.create(r, "boat") @@ -179,7 +179,7 @@ end function test_levitate() local r = region.create(0,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 2) local s = ship.create(r, "boat") u.ship = s @@ -205,15 +205,15 @@ end function test_races() local races = { "wolf", "orc", "human", "demon" } for k,v in ipairs(races) do - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") assert_not_equal(nil, f) end end function test_can_give_person() local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") + local f2 = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f1, r, 10) local u2 = unit.create(f2, r, 10) u1.faction.age = 10 @@ -231,7 +231,7 @@ function test_can_give_person() end function test_no_uruk() - local f1 = faction.create("noreply@eressea.de", "uruk", "de") + local f1 = faction.create("uruk", "noreply@eressea.de", "de") assert_equal(f1.race, "orc") end @@ -326,7 +326,7 @@ end function test_stonegolems() local r0 = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "stonegolem", "de") + local f1 = faction.create("stonegolem", "noreply@eressea.de", "de") local u1 = unit.create(f1, r0, 1) local u2 = unit.create(f1, r0, 2) local c1 = building.create(r0, "castle") @@ -355,7 +355,7 @@ end function test_birthdaycake() r = region.create(0,0, "plain") - f = faction.create("cake@eressea.de", "human", "de") + f = faction.create("human", "cake@eressea.de", "de") u = unit.create(f, r, 1) u:add_item("birthdaycake", 1) u:clear_orders() diff --git a/scripts/tests/e2/guard.lua b/scripts/tests/e2/guard.lua index 8e62a364d..e3cf8075f 100644 --- a/scripts/tests/e2/guard.lua +++ b/scripts/tests/e2/guard.lua @@ -11,7 +11,7 @@ end function test_guard_unarmed() local r1 = region.create(0, 0, "plain") - local f1 = faction.create("hodor@eressea.de", "human", "de") + local f1 = faction.create("human", "hodor@eressea.de", "de") local u1 = unit.create(f1, r1, 1) assert_equal(false, u1.guard) u1:clear_orders() @@ -22,7 +22,7 @@ end function test_guard_armed() local r1 = region.create(0, 0, "plain") - local f1 = faction.create("hodor@eressea.de", "human", "de") + local f1 = faction.create("human", "hodor@eressea.de", "de") local u1 = unit.create(f1, r1, 1) assert_equal(false, u1.guard) u1:add_item("sword", 1) @@ -36,10 +36,10 @@ end function test_guard_allows_move_after_combat() -- bug 1493 local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") - local f1 = faction.create("bernd@eressea.de", "human", "de") + local f1 = faction.create("human", "bernd@eressea.de", "de") local u1 = unit.create(f1, r1, 10) local uid1 = u1.id - local f2 = faction.create("horst@eressea.de", "human", "de") + local f2 = faction.create("human", "horst@eressea.de", "de") local u2 = unit.create(f2, r1, 1) u1:add_order("BEWACHE") u1:add_item("sword", 10) @@ -59,10 +59,10 @@ end function test_no_guard_no_move_after_combat() -- bug 1493 local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") - local f1 = faction.create("bernd@eressea.de", "human", "de") + local f1 = faction.create("human", "bernd@eressea.de", "de") local u1 = unit.create(f1, r1, 10) local uid1 = u1.id - local f2 = faction.create("horst@eressea.de", "human", "de") + local f2 = faction.create("human", "horst@eressea.de", "de") local u2 = unit.create(f2, r1, 1) u1:add_order("BEWACHE") u1:add_item("sword", 10) diff --git a/scripts/tests/e2/items.lua b/scripts/tests/e2/items.lua index 24f27f4b2..da7b3ae8f 100644 --- a/scripts/tests/e2/items.lua +++ b/scripts/tests/e2/items.lua @@ -13,7 +13,7 @@ end function test_nestwarmth_insect() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "insect", "de") + local f = faction.create("insect", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) local flags = u.flags u:add_item("nestwarmth", 2) @@ -29,7 +29,7 @@ end function test_nestwarmth_other() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) local flags = u.flags u:add_item("nestwarmth", 2) @@ -45,7 +45,7 @@ end function test_meow() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("aoc", 1) u:clear_orders() @@ -59,7 +59,7 @@ end function test_aurapotion50() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("aurapotion50", 1) u:set_skill('magic', 10); @@ -77,7 +77,7 @@ end function test_bagpipe() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) turn_begin() u:add_item("bagpipeoffear", 1) @@ -96,7 +96,7 @@ end function test_speedsail() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) turn_begin() @@ -115,7 +115,7 @@ end function test_foolpotion() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) turn_begin() u:add_item("p7", 1) @@ -141,7 +141,7 @@ end function test_snowman() local r = region.create(0, 0, "glacier") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("snowman", 1) u:clear_orders() diff --git a/scripts/tests/e2/movement.lua b/scripts/tests/e2/movement.lua index 390af2c48..b17d369f4 100644 --- a/scripts/tests/e2/movement.lua +++ b/scripts/tests/e2/movement.lua @@ -13,8 +13,8 @@ end local r = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") local r3 = region.create(-1, 0, "ocean") - local f = faction.create("pirate@eressea.de", "human", "de") - local f2 = faction.create("elf@eressea.de", "human", "de") + local f = faction.create("human", "pirate@eressea.de", "de") + local f2 = faction.create("human", "elf@eressea.de", "de") local u1 = unit.create(f, r2, 1) local u2 = unit.create(f2, r3, 1) @@ -39,7 +39,7 @@ end function test_dolphin_on_land() local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f, r1, 1) u1.race = "dolphin" u1:clear_orders() @@ -51,7 +51,7 @@ end function test_dolphin_to_land() local r1 = region.create(0, 0, "ocean") local r2 = region.create(1, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f, r1, 1) u1.race = "dolphin" u1:clear_orders() @@ -63,7 +63,7 @@ end function test_dolphin_in_ocean() local r1 = region.create(0, 0, "ocean") local r2 = region.create(1, 0, "ocean") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f, r1, 1) u1.race = "dolphin" u1:clear_orders() @@ -75,7 +75,7 @@ end function test_follow() local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u1 = unit.create(f, r1, 1) local u2 = unit.create(f, r1, 1) u1:clear_orders() @@ -93,7 +93,7 @@ function test_follow_ship() local r1 = region.create(0, 0, "plain") region.create(1, 0, "ocean") region.create(2, 0, "ocean") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u1 = unit.create(f, r1, 1) local u2 = unit.create(f, r1, 1) u1:add_item("money", 100) diff --git a/scripts/tests/e2/shiplanding.lua b/scripts/tests/e2/shiplanding.lua index a46a7da37..2258a1992 100644 --- a/scripts/tests/e2/shiplanding.lua +++ b/scripts/tests/e2/shiplanding.lua @@ -11,8 +11,8 @@ end function test_landing1() local ocean = region.create(1, 0, "ocean") local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") + local f2 = faction.create("human", "noreply@eressea.de", "de") local s = ship.create(ocean, "longboat") local u1 = unit.create(f, ocean, 1) local u2 = unit.create(f2, r, 1) @@ -34,8 +34,8 @@ function test_landing_harbour_with_help() local r = region.create(0, 0, "glacier") local harbour = building.create(r, "harbour") harbour.size = 25 - local f = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") + local f2 = faction.create("human", "noreply@eressea.de", "de") local s = ship.create(ocean, "longboat") local u1 = unit.create(f, ocean, 1) local u2 = unit.create(f2, r, 1) @@ -60,8 +60,8 @@ function test_landing_harbour_without_help() local r = region.create(0, 0, "glacier") local harbour = building.create(r, "harbour") harbour.size = 25 - local f = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") + local f2 = faction.create("human", "noreply@eressea.de", "de") local s = ship.create(ocean, "longboat") local u1 = unit.create(f, ocean, 1) local u2 = unit.create(f2, r, 1) @@ -84,7 +84,7 @@ function test_landing_harbour_unpaid() local r = region.create(0, 0, "glacier") local harbour = building.create(r, "harbour") harbour.size = 25 - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local s = ship.create(ocean, "longboat") local u1 = unit.create(f, ocean, 1) local u2 = unit.create(f, r, 1) @@ -104,8 +104,8 @@ end function test_landing_terrain() local ocean = region.create(1, 0, "ocean") local r = region.create(0, 0, "glacier") - local f = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") + local f2 = faction.create("human", "noreply@eressea.de", "de") local s = ship.create(ocean, "longboat") local u1 = unit.create(f, ocean, 1) local u2 = unit.create(f2, r, 1) @@ -126,8 +126,8 @@ function test_landing_insects() local r = region.create(0, 0, "glacier") local harbour = building.create(r, "harbour") harbour.size = 25 - local f = faction.create("noreply@eressea.de", "insect", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("insect", "noreply@eressea.de", "de") + local f2 = faction.create("human", "noreply@eressea.de", "de") local s = ship.create(ocean, "longboat") local u1 = unit.create(f, ocean, 1) local u2 = unit.create(f2, r, 1) diff --git a/scripts/tests/e2/ships.lua b/scripts/tests/e2/ships.lua index 151afc12c..351609a92 100644 --- a/scripts/tests/e2/ships.lua +++ b/scripts/tests/e2/ships.lua @@ -11,7 +11,7 @@ end function test_ship_requires_skill() local r1 = region.create(0, 0, "ocean") local r2 = region.create(1, 0, "ocean") - local f = faction.create("fake@eressea.de", "human", "de") + local f = faction.create("human", "fake@eressea.de", "de") local u1 = unit.create(f, r1, 1) u1.name = "fake" u1.ship = ship.create(r1, "longboat") @@ -25,7 +25,7 @@ end function no_test_ship_happy_case() local r1 = region.create(0, 0, "ocean") local r2 = region.create(1, 0, "ocean") - local f = faction.create("hodor@eressea.de", "human", "de") + local f = faction.create("human", "hodor@eressea.de", "de") local u1 = unit.create(f, r1, 1) local u2 = unit.create(f, r1, 1) u1.ship = ship.create(r1, "longboat") diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index 6b1123a6f..107b20232 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -12,7 +12,7 @@ end function test_shapeshift() local r = region.create(42, 0, "plain") - local f = faction.create("noreply@eressea.de", "demon", "de") + local f = faction.create("demon", "noreply@eressea.de", "de") local u1 = unit.create(f, r, 1) local u2 = unit.create(f, r, 1) u1:clear_orders() diff --git a/scripts/tests/e2/stealth.lua b/scripts/tests/e2/stealth.lua index ab4320bb1..7f531776c 100644 --- a/scripts/tests/e2/stealth.lua +++ b/scripts/tests/e2/stealth.lua @@ -21,9 +21,9 @@ function setup() set_rule('rules.food.flags', '4') local r = region.create(0,0, "plain") - f = faction.create("stealthy@eressea.de", "human", "de") + f = faction.create("human", "stealthy@eressea.de", "de") u = unit.create(f, r, 1) - f = faction.create("stealth@eressea.de", "human", "de") + f = faction.create("human", "stealth@eressea.de", "de") unit.create(f, r, 1) -- TARNE PARTEI NUMMER must have a unit in the region end diff --git a/scripts/tests/e2/undead.lua b/scripts/tests/e2/undead.lua index 9f3f67f13..71c14ac36 100644 --- a/scripts/tests/e2/undead.lua +++ b/scripts/tests/e2/undead.lua @@ -8,7 +8,7 @@ end function test_undead_give_item() local r1 = region.create(0, 0, "plain") - local f1 = faction.create("hodor@eressea.de", "human", "de") + local f1 = faction.create("human", "hodor@eressea.de", "de") local u1 = unit.create(f1, r1, 1) u1.race = "undead" u1:clear_orders() @@ -20,7 +20,7 @@ end function test_undead_dont_give_person() local r1 = region.create(0, 0, "plain") - local f1 = faction.create("hodor@eressea.de", "human", "de") + local f1 = faction.create("human", "hodor@eressea.de", "de") local u1 = unit.create(f1, r1, 2) u1.race = "undead" u1:clear_orders() diff --git a/scripts/tests/e3/castles.lua b/scripts/tests/e3/castles.lua index b16019159..c5641c68e 100644 --- a/scripts/tests/e3/castles.lua +++ b/scripts/tests/e3/castles.lua @@ -13,7 +13,7 @@ end function test_build_watch() local r = region.create(0, 0, "plain") - local f = faction.create("e3build@eressea.de", "human", "de") + local f = faction.create("human", "e3build@eressea.de", "de") local u = unit.create(f, r, 1) u.number = 20 @@ -46,9 +46,9 @@ end function test_small_castles() local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f1, r, 1) - local f2 = faction.create("noreply@eressea.de", "halfling", "de") + local f2 = faction.create("halfling", "noreply@eressea.de", "de") local u2 = unit.create(f2, r, 1) local b = building.create(r, "castle") @@ -65,7 +65,7 @@ end function test_build_normal() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:clear_orders() u:add_item("stone", 10) @@ -78,7 +78,7 @@ end function test_build_packice() local r = region.create(0, 0, "packice") - local f = faction.create("packice@eressea.de", "human", "de") + local f = faction.create("human", "packice@eressea.de", "de") local u = unit.create(f, r, 1) u:clear_orders() u:add_item("stone", 10) @@ -90,7 +90,7 @@ end function test_build_castle_stages() local r = region.create(0,0, "plain") - local f = faction.create("castle@eressea.de", "human", "de") + local f = faction.create("human", "castle@eressea.de", "de") local u = unit.create(f, r, 1000) local b = building.create(r, "castle") diff --git a/scripts/tests/e3/items.lua b/scripts/tests/e3/items.lua index caf566468..d3b857381 100644 --- a/scripts/tests/e3/items.lua +++ b/scripts/tests/e3/items.lua @@ -10,7 +10,7 @@ end function test_give_horses() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) r:set_resource("horse", 0) @@ -23,9 +23,9 @@ end function test_goblins() local r = region.create(0, 0, "plain") - local f1 = faction.create("goblin@eressea.de", "goblin", "de") - local f2 = faction.create("dwarf@eressea.de", "dwarf", "de") - local f3 = faction.create("elf@eressea.de", "elf", "de") + local f1 = faction.create("goblin", "goblin@eressea.de", "de") + local f2 = faction.create("dwarf", "dwarf@eressea.de", "de") + local f3 = faction.create("elf", "elf@eressea.de", "de") local ud = unit.create(f1, r, 1) local uh = unit.create(f1, r, 1) uh.race = "halfling" @@ -54,7 +54,7 @@ end function test_make_horse() eressea.settings.set("rules.horses.growth", "0") local r = region.create(0, 0, "plain") - local f = faction.create("horses@eressea.de", "human", "de") + local f = faction.create("human", "horses@eressea.de", "de") local u = unit.create(f, r, 1) u:set_skill("training", 4) r:set_resource("horse", 100) diff --git a/scripts/tests/e3/morale.lua b/scripts/tests/e3/morale.lua index c01fad186..1dd92a758 100644 --- a/scripts/tests/e3/morale.lua +++ b/scripts/tests/e3/morale.lua @@ -14,7 +14,7 @@ end function test_when_owner_returns_morale_stays() local r = region.create(0, 0, "plain") assert_equal(1, r.morale) - local f1 = faction.create("owner_returns@eressea.de", "human", "de") + local f1 = faction.create("human", "owner_returns@eressea.de", "de") local u1 = unit.create(f1, r, 1) u1:add_item("money", 10000) local b = building.create(r, "castle") @@ -38,13 +38,13 @@ end function test_morale_alliance() local r = region.create(0, 0, "plain") assert_equal(1, r.morale) - local f1 = faction.create("ma1@eressea.de", "human", "de") + local f1 = faction.create("human", "ma1@eressea.de", "de") local u1 = unit.create(f1, r, 1) u1:add_item("money", 10000) - local f2 = faction.create("ma2@eressea.de", "human", "de") + local f2 = faction.create("human", "ma2@eressea.de", "de") local u2 = unit.create(f2, r, 1) u2:add_item("money", 10000) - local f3 = faction.create("ma3@eressea.de", "human", "de") + local f3 = faction.create("human", "ma3@eressea.de", "de") local u3 = unit.create(f3, r, 1) u3:add_item("money", 10000) @@ -95,9 +95,9 @@ end function test_bigger_castle_empty() local r = region.create(0, 0, "plain") assert_equal(1, r.morale) - local f1 = faction.create("small1@eressea.de", "human", "de") + local f1 = faction.create("human", "small1@eressea.de", "de") local u1 = unit.create(f1, r, 1) - local f2 = faction.create("small2@eressea.de", "human", "de") + local f2 = faction.create("human", "small2@eressea.de", "de") local u2 = unit.create(f2, r, 1) u1:add_item("money", 10000) @@ -129,7 +129,7 @@ end function test_morale_change() local r = region.create(0, 0, "plain") assert_equal(1, r.morale) - local f1 = faction.create("mchange@eressea.de", "human", "de") + local f1 = faction.create("human", "mchange@eressea.de", "de") local u1 = unit.create(f1, r, 1) u1:add_item("money", 10000) @@ -195,9 +195,9 @@ end function test_morale_give_command() local r = region.create(0, 0, "plain") assert_equal(1, r.morale) - local f1 = faction.create("mold1@eressea.de", "human", "de") + local f1 = faction.create("human", "mold1@eressea.de", "de") local u1 = unit.create(f1, r, 1) - local f2 = faction.create("mold2@eressea.de", "human", "de") + local f2 = faction.create("human", "mold2@eressea.de", "de") local u2 = unit.create(f2, r, 1) local b = building.create(r, "castle") diff --git a/scripts/tests/e3/parser.lua b/scripts/tests/e3/parser.lua index 9d957464d..a56f08f76 100644 --- a/scripts/tests/e3/parser.lua +++ b/scripts/tests/e3/parser.lua @@ -8,7 +8,7 @@ end function test_set_status_en() local r = region.create(0, 0, "plain") - local f = faction.create("bug_1882@eressea.de", "human", "en") + local f = faction.create("human", "bug_1882@eressea.de", "en") local u = unit.create(f, r, 1) u.status = 1 u:clear_orders() @@ -23,7 +23,7 @@ end function test_set_status_de() local r = region.create(0, 0, "plain") - local f = faction.create("bug_1882@eressea.de", "human", "de") + local f = faction.create("human", "bug_1882@eressea.de", "de") local u = unit.create(f, r, 1) u.status = 1 u:clear_orders() @@ -34,7 +34,7 @@ end function test_breed_horses() local r = region.create(0, 0, "plain") - local f = faction.create("bug_1886@eressea.de", "human", "en") + local f = faction.create("human", "bug_1886@eressea.de", "en") local u = unit.create(f, r, 1) local b = building.create(r, "stables") b.size = 10 diff --git a/scripts/tests/e3/rules.lua b/scripts/tests/e3/rules.lua index 150ad3ae0..c01132b58 100644 --- a/scripts/tests/e3/rules.lua +++ b/scripts/tests/e3/rules.lua @@ -43,7 +43,7 @@ end function disable_test_bug_1738_build_castle_e3() local r = region.create(0, 0, "plain") - local f = faction.create("bug_1738@eressea.de", "human", "de") + local f = faction.create("human", "bug_1738@eressea.de", "de") local c = building.create(r, "castle") c.size = 228 @@ -73,10 +73,10 @@ end function disable_test_alliance() local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f1, r, 1) u1:add_item("money", u1.number * 100) - local f2 = faction.create("info@eressea.de", "human", "de") + local f2 = faction.create("human", "info@eressea.de", "de") local u2 = unit.create(f2, r, 1) u2:add_item("money", u2.number * 100) assert(f1.alliance==nil) @@ -125,7 +125,7 @@ end function test_no_stealth() local r = region.create(0,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:set_skill("stealth", 1) @@ -138,7 +138,7 @@ end function test_no_teach() local r = region.create(0,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f, r, 1) local u2 = unit.create(f, r, 1) @@ -160,7 +160,7 @@ function test_seecast() for i = 1,10 do region.create(i, 0, "ocean") end - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local s1 = ship.create(r, "cutter") local u1 = unit.create(f, r, 2) u1:set_skill("sailing", 3) @@ -193,7 +193,7 @@ function test_fishing() eressea.settings.set("rules.food.flags", "0") local r = region.create(0,0, "ocean") local r2 = region.create(1,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local s1 = ship.create(r, "cutter") local u1 = unit.create(f, r, 3) u1.ship = s1 @@ -219,8 +219,8 @@ function test_ship_capacity() local r = region.create(0,0, "ocean") region.create(1,0, "ocean") local r2 = region.create(2,0, "ocean") - local f = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "goblin", "de") + local f = faction.create("human", "noreply@eressea.de", "de") + local f2 = faction.create("goblin", "noreply@eressea.de", "de") -- u1 is at the limit and moves local s1 = ship.create(r, "cutter") @@ -273,9 +273,9 @@ end function test_owners() local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f1, r, 1) - local f2 = faction.create("noreply@eressea.de", "human", "de") + local f2 = faction.create("human", "noreply@eressea.de", "de") local u2 = unit.create(f2, r, 1) local u3 = unit.create(f2, r, 1) @@ -304,7 +304,7 @@ function test_taxes() local r = region.create(0, 0, "plain") r:set_resource("peasant", 1000) r:set_resource("money", 5000) - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:clear_orders() u:add_order("LERNE Holzfaellen") -- do not work @@ -320,7 +320,7 @@ end function test_region_owner_cannot_leave_castle() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") f.id = 42 local b1 = building.create(r, "castle") b1.size = 10 @@ -366,7 +366,7 @@ function market_fixture() b.size = 10 b.working = true - local f = faction.create("market1@eressea.de", "human", "de") + local f = faction.create("human", "market1@eressea.de", "de") f.id = 42 local u = unit.create(f, r, 1) u.building = b @@ -424,7 +424,7 @@ end function test_multiple_markets() local r, u1, b, herbnames, luxurynames, herbtable, luxurytable = market_fixture() local r2 = get_region(1,0) - local f = faction.create("multim@eressea.de", "human", "de") + local f = faction.create("human", "multim@eressea.de", "de") local u2 = unit.create(f, r2, 1) local b2 = building.create(r2, "market") b2.size = 10 @@ -444,7 +444,7 @@ end function test_market() local r = region.create(0, 0, "plain") - local f1 = faction.create("market2@eressea.de", "human", "de") + local f1 = faction.create("human", "market2@eressea.de", "de") local u1 = unit.create(f1, r, 1) local b = building.create(r, "market") @@ -541,7 +541,7 @@ function test_market_gives_items() r = get_region(0, 0) local b = building.create(r, "market") b.size = 10 - local f = faction.create("market0@eressea.de", "human", "de") + local f = faction.create("human", "market0@eressea.de", "de") f.id = 42 local u = unit.create(f, r, 1) u.building = b @@ -559,7 +559,7 @@ end function test_spells() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u.race = "elf" u:clear_orders() @@ -587,7 +587,7 @@ function test_spells() end function test_canoe_passes_through_land() - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local src = region.create(0, 0, "ocean") local land = region.create(1, 0, "plain") region.create(2, 0, "ocean") @@ -610,8 +610,8 @@ end function test_give_50_percent_of_money() local r = region.create(0, 0, "plain") - local u1 = unit.create(faction.create("noreply@eressea.de", "human", "de"), r, 1) - local u2 = unit.create(faction.create("noreply@eressea.de", "orc", "de"), r, 1) + local u1 = unit.create(faction.create("human", "noreply@eressea.de", "de"), r, 1) + local u2 = unit.create(faction.create("orc", "noreply@eressea.de", "de"), r, 1) u1.faction.age = 10 u2.faction.age = 10 u1:add_item("money", 500) @@ -637,8 +637,8 @@ end function test_give_100_percent_of_items() r = region.create(0, 0, "plain") - local u1 = unit.create(faction.create("noreply@eressea.de", "human", "de"), r, 1) - local u2 = unit.create(faction.create("noreply@eressea.de", "orc", "de"), r, 1) + local u1 = unit.create(faction.create("human", "noreply@eressea.de", "de"), r, 1) + local u2 = unit.create(faction.create("orc", "noreply@eressea.de", "de"), r, 1) u1.faction.age = 10 u2.faction.age = 10 u1:add_item("money", 500) @@ -656,8 +656,8 @@ end function test_cannot_give_person() local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") + local f2 = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f1, r, 10) local u2 = unit.create(f2, r, 10) u1.faction.age = 10 @@ -675,8 +675,8 @@ end function test_cannot_give_unit() local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") + local f2 = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f1, r, 10) local u2 = unit.create(f2, r, 10) u1.faction.age = 10 @@ -694,9 +694,9 @@ end function test_guard_by_owners() -- http://bugs.eressea.de/view.php?id=1756 local r = region.create(0,0, "mountain") - local f1 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") f1.age=20 - local f2 = faction.create("noreply@eressea.de", "human", "de") + local f2 = faction.create("human", "noreply@eressea.de", "de") f2.age=20 local u1 = unit.create(f1, r, 1) local b = building.create(r, "castle") @@ -717,7 +717,7 @@ function test_guard_by_owners() end local function setup_packice(x, onfoot) - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local plain = region.create(0,0, "plain") local ice = region.create(1,0, "packice") local ocean = region.create(2,0, "ocean") @@ -778,7 +778,7 @@ function test_cannot_walk_into_ocean() end function test_p2() - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local r = region.create(0, 0, "plain") local u = unit.create(f, r, 1) r:set_resource("tree", 0) @@ -795,7 +795,7 @@ end function test_p2_move() -- http://bugs.eressea.de/view.php?id=1855 - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local r = region.create(0, 0, "plain") region.create(1, 0, "plain") local u = unit.create(f, r, 1) @@ -814,7 +814,7 @@ end function test_golem_use_four_iron() local r0 = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "halfling", "de") + local f1 = faction.create("halfling", "noreply@eressea.de", "de") local u1 = unit.create(f1, r0, 3) u1.race = "irongolem" u1:set_skill("weaponsmithing", 1) @@ -832,7 +832,7 @@ function test_silver_weight_stops_movement() local r1 = region.create(1, 1, "plain") local r2 = region.create(2, 1, "plain") region.create(3, 1, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f1, r1, 1) u1:clear_orders() u1:add_order("NACH OST") @@ -849,7 +849,7 @@ function test_silver_weight_stops_ship() local r1 = region.create(1, 1, "ocean") local r2 = region.create(2, 1, "ocean") region.create(3, 1, "ocean") - local f1 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f1, r1, 1) u1:set_skill("sailing", 3) local s1 = ship.create(r1, "canoe") @@ -866,7 +866,7 @@ end function test_building_owner_can_enter_ship() local r1 = region.create(1, 2, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") local b1 = building.create(r1, "castle") b1.size = 10 local s1 = ship.create(r1, "cutter") @@ -889,7 +889,7 @@ end function test_only_building_owner_can_set_not_paid() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f, r, 1) local u2 = unit.create(f, r, 1) local mine = building.create(r, "mine") @@ -913,7 +913,7 @@ end function test_spyreport_message() local r1 = region.create(1, 2, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") + local f1 = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f1, r1, 1) local u2 = unit.create(f1, r1, 1) msg = message.create("spyreport") @@ -940,7 +940,7 @@ function test_bug2083() r:set_resource("peasant", 2000) r.luxury = "balm" - local f = faction.create("2083@eressea.de", "human", "de") + local f = faction.create("human", "2083@eressea.de", "de") local u = unit.create(f, r, 1) u:set_skill("building", 8) u:add_item("stone", 100) @@ -967,7 +967,7 @@ function test_bug2083() end function test_no_uruk() - local f1 = faction.create("noreply@eressea.de", "uruk", "de") + local f1 = faction.create("uruk", "noreply@eressea.de", "de") assert_equal(f1.race, "orc") end @@ -975,7 +975,7 @@ function test_bug2187() set_rule("rules.food.flags", "0") local r = region.create(0,0,"plain") - local f = faction.create("2187@eressea.de", "goblin", "de") + local f = faction.create("goblin", "2187@eressea.de", "de") local u = unit.create(f, r, 1) u.race = "demon" u.hp = u.hp_max * u.number diff --git a/scripts/tests/e3/spells-e2.lua b/scripts/tests/e3/spells-e2.lua index bf3fa1d6c..f232b8a1a 100644 --- a/scripts/tests/e3/spells-e2.lua +++ b/scripts/tests/e3/spells-e2.lua @@ -11,7 +11,7 @@ function setup() eressea.settings.set("rules.food.flags", "4") r = region.create(0, 0, "plain") - f = faction.create("spell_payment@eressea.de", "elf", "de") + f = faction.create("elf", "spell_payment@eressea.de", "de") u = unit.create(f, r, 1) u.magic = "gray" u:set_skill("magic", 12) diff --git a/scripts/tests/e3/spells.lua b/scripts/tests/e3/spells.lua index f99e4687b..df9408fbd 100644 --- a/scripts/tests/e3/spells.lua +++ b/scripts/tests/e3/spells.lua @@ -11,7 +11,7 @@ end function test_blessedharvest_lasts_n_turn() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "halfling", "de") + local f = faction.create("halfling", "noreply@eressea.de", "de") local u = unit.create(f, r) local err = 0 r:set_resource("peasant", 100) @@ -46,7 +46,7 @@ end function test_magic() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "halfling", "de") + local f = faction.create("halfling", "noreply@eressea.de", "de") local u = unit.create(f, r) local b = building.create(r, "castle") diff --git a/scripts/tests/e3/stealth.lua b/scripts/tests/e3/stealth.lua index 38ca7d8ea..866eb4f14 100644 --- a/scripts/tests/e3/stealth.lua +++ b/scripts/tests/e3/stealth.lua @@ -10,9 +10,9 @@ function setup() eressea.settings.set("rules.food.flags", "4") local r = region.create(0,0, "plain") - f = faction.create("stealth1@eressea.de", "human", "de") + f = faction.create("human", "stealth1@eressea.de", "de") u = unit.create(f, r, 1) - f = faction.create("stealth2@eressea.de", "human", "de") + f = faction.create("human", "stealth2@eressea.de", "de") end function test_stealth_faction_on() diff --git a/scripts/tests/economy.lua b/scripts/tests/economy.lua index fe1574887..807bda631 100644 --- a/scripts/tests/economy.lua +++ b/scripts/tests/economy.lua @@ -11,6 +11,50 @@ function setup() eressea.settings.set("rules.encounters", "0") end +function test_mine_bonus() + local r = region.create(0, 0, "mountain") + r:set_resource("iron", 100) + local level = r:get_resourcelevel("iron") + assert_equal(1, level) + local u = unit.create(faction.create("human"), r) + u.number = 10 + u:set_skill("mining", 1) + u:add_order("MACHE EISEN") + process_orders() + assert_equal(10, u:get_item("iron")) + assert_equal(90, r:get_resource("iron")) + + u.building = building.create(r, "mine") + u.building.size = 10 + u:add_item("money", 500) -- maintenance + process_orders() + assert_equal(30, u:get_item("iron")) + assert_equal(80, r:get_resource("iron")) +end + +function test_mine_example() + local r = region.create(0, 0, "mountain") + r:set_resource("iron", 100) + local level = r:get_resourcelevel("iron") + assert_equal(1, level) + local u = unit.create(faction.create("dwarf"), r) + assert_equal("dwarf", u.faction.race) + assert_equal("dwarf", u.race) + u.faction.name = "Zwerge" + u.number = 10 + u:set_skill("mining", 1) + u:add_order("MACHE EISEN") + process_orders() + assert_equal(30, u:get_item("iron")) + assert_equal(82, r:get_resource("iron")) + u.building = building.create(r, "mine") + u.building.size = 10 + u:add_item("money", 500) -- maintenance + process_orders() + assert_equal(70, u:get_item("iron")) + assert_equal(70, r:get_resource("iron")) +end + function test_no_guards() local r = region.create(0, 0, "plain") r:set_resource("tree", 100) diff --git a/scripts/tests/faction.lua b/scripts/tests/faction.lua index 87a6b5100..c264f4596 100644 --- a/scripts/tests/faction.lua +++ b/scripts/tests/faction.lua @@ -12,7 +12,7 @@ function setup() }]] eressea.config.reset() assert(eressea.config.parse(conf)==0) - f = faction.create("faction@eressea.de", "human", "de") + f = faction.create("human", "faction@eressea.de", "de") assert(f~=nil) end diff --git a/scripts/tests/items.lua b/scripts/tests/items.lua index aad52c2b2..5c2093953 100644 --- a/scripts/tests/items.lua +++ b/scripts/tests/items.lua @@ -13,7 +13,7 @@ end function test_mistletoe_okay() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) turn_begin() u:add_item('mistletoe', 2) @@ -29,7 +29,7 @@ end function test_mistletoe_fail() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) turn_begin() u:add_item('mistletoe', 1) @@ -46,7 +46,7 @@ end function test_dreameye() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("dreameye", 2) u:clear_orders() @@ -63,7 +63,7 @@ end function test_manacrystal() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("manacrystal", 2) u:clear_orders() @@ -81,7 +81,7 @@ end function test_skillpotion() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("skillpotion", 2) u:clear_orders() @@ -93,7 +93,7 @@ end function test_studypotion() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) turn_begin() u:add_item("studypotion", 2) @@ -109,7 +109,7 @@ end function test_antimagic() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) turn_begin() @@ -129,7 +129,7 @@ end function test_ointment() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) local hp = u.hp u.hp = 1 @@ -144,7 +144,7 @@ end function test_bloodpotion_demon() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "demon", "de") + local f = faction.create("demon", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("peasantblood", 1) u:clear_orders() @@ -157,7 +157,7 @@ end function test_bloodpotion_other() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u:add_item("peasantblood", 1) u:clear_orders() diff --git a/scripts/tests/laws.lua b/scripts/tests/laws.lua index 6f41fc54b..8b64ffb7f 100644 --- a/scripts/tests/laws.lua +++ b/scripts/tests/laws.lua @@ -30,8 +30,8 @@ end function test_force_leave_on() local r = region.create(0, 0, "plain") - local f1 = faction.create("owner@eressea.de") - local f2 = faction.create("guest@eressea.de") + local f1 = faction.create("human", "owner@eressea.de") + local f2 = faction.create("human", "guest@eressea.de") local u1 = unit.create(f1, r, 1) local u2 = unit.create(f2, r, 1) local b1 = building.create(r, "castle") @@ -45,8 +45,8 @@ end function test_force_leave_off() local r = region.create(0, 0, "plain") - local f1 = faction.create("owner@eressea.de") - local f2 = faction.create("guest@eressea.de") + local f1 = faction.create("human", "owner@eressea.de") + local f2 = faction.create("human", "guest@eressea.de") local u1 = unit.create(f1, r, 1) local u2 = unit.create(f2, r, 1) local b1 = building.create(r, "castle") @@ -60,7 +60,7 @@ end function test_make_temp() local r = region.create(0, 0, "plain") - local f1 = faction.create("owner@eressea.de", "human", "de") + local f1 = faction.create("human", "owner@eressea.de", "de") local u1 = unit.create(f1, r, 10) local u, u2 @@ -86,8 +86,8 @@ end function test_force_leave_postcombat() local r = region.create(0, 0, "plain") - local f1 = faction.create("owner@eressea.de", "human", "de") - local f2 = faction.create("guest@eressea.de", "human", "de") + local f1 = faction.create("human", "owner@eressea.de", "de") + local f2 = faction.create("human", "guest@eressea.de", "de") local u1 = unit.create(f1, r, 10) local u2 = unit.create(f2, r, 10) local u, u3 diff --git a/scripts/tests/magicbag.lua b/scripts/tests/magicbag.lua index 4ca5e6ae5..b51925726 100644 --- a/scripts/tests/magicbag.lua +++ b/scripts/tests/magicbag.lua @@ -6,7 +6,7 @@ local u function setup() eressea.free_game() - u = unit.create(faction.create("test@example.com", "human", "de"), region.create(0, 0, "plain"), 1) + u = unit.create(faction.create("human", "test@example.com", "de"), region.create(0, 0, "plain"), 1) end function test_magicbag_weight() diff --git a/scripts/tests/movement.lua b/scripts/tests/movement.lua index 110b5b2a2..22bd8d30e 100644 --- a/scripts/tests/movement.lua +++ b/scripts/tests/movement.lua @@ -48,7 +48,7 @@ end function test_walk_to_land() local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") - local f = faction.create("walk@example.com", "human", "de") + local f = faction.create("human", "walk@example.com", "de") local u = unit.create(f, r1, 1) u:add_order("NACH O") process_orders() @@ -58,7 +58,7 @@ end function test_walk_into_ocean_fails() local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "ocean") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u = unit.create(f, r1, 1) u:add_order("NACH O") process_orders() @@ -69,7 +69,7 @@ function test_walk_distance() local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") region.create(2, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u = unit.create(f, r1, 1) u:add_order("NACH O O") process_orders() @@ -81,7 +81,7 @@ function test_ride_max_distance() local r2 = region.create(2, 0, "plain") region.create(1, 0, "plain") region.create(3, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u = unit.create(f, r1, 1) u:add_item("horse", 1) u:set_skill("riding", 2) @@ -94,7 +94,7 @@ function test_ride_over_capacity_leads_horse() local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") region.create(2, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u = unit.create(f, r1, 3) u:add_item("horse", 1) u:set_skill("riding", 2) @@ -107,7 +107,7 @@ function test_ride_no_skill_leads_horse() local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") region.create(2, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u = unit.create(f, r1, 1) u:add_item("horse", 1) u:add_order("NACH O O") diff --git a/scripts/tests/orders.lua b/scripts/tests/orders.lua index dde9508e9..d88a59293 100644 --- a/scripts/tests/orders.lua +++ b/scripts/tests/orders.lua @@ -12,7 +12,7 @@ local r, f, u function setup() eressea.free_game() r = _G.region.create(0, 0, "mountain") - f = _G.faction.create("noreply@eressea.de", "human", "de") + f = _G.faction.create("human", "noreply@eressea.de", "de") u = _G.unit.create(f, r, 1) u:clear_orders() eressea.settings.set("rules.food.flags", "4") diff --git a/scripts/tests/pool.lua b/scripts/tests/pool.lua index d9b336919..0d24f8129 100644 --- a/scripts/tests/pool.lua +++ b/scripts/tests/pool.lua @@ -33,7 +33,7 @@ end function test_give_nopool() local r = region.create(1, 1, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u1 = unit.create(f, r, 1) local u2 = unit.create(f, r, 1) u1:add_item("money", 100) @@ -45,7 +45,7 @@ end function test_give_from_faction() local r = region.create(1, 1, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u1 = unit.create(f, r, 1) local u2 = unit.create(f, r, 1) local u3 = unit.create(f, r, 1) @@ -62,8 +62,8 @@ function test_give_divisor() eressea.settings.set("rules.items.give_divisor", 2) eressea.settings.set("GiveRestriction", 0) local r = region.create(1, 1, "plain") - local f1 = faction.create("test@example.com", "human", "de") - local f2 = faction.create("test@example.com", "human", "de") + local f1 = faction.create("human", "test@example.com", "de") + local f2 = faction.create("human", "test@example.com", "de") local u1 = unit.create(f1, r, 1) local u2 = unit.create(f2, r, 1) u2:add_order("KONTAKTIERE " .. itoa36(u1.id)) diff --git a/scripts/tests/process.lua b/scripts/tests/process.lua index 3256c73e6..c5515be0b 100644 --- a/scripts/tests/process.lua +++ b/scripts/tests/process.lua @@ -7,7 +7,7 @@ local u, r, f,turn function setup() eressea.free_game() r = region.create(0, 0, "plain") - f = faction.create("bernd@eressea.de", "human", "de") + f = faction.create("human", "bernd@eressea.de", "de") u = unit.create(f, r, 1) u:add_item("money", 10) turn = get_turn() diff --git a/scripts/tests/report.lua b/scripts/tests/report.lua index 2a037c770..12d1538c3 100644 --- a/scripts/tests/report.lua +++ b/scripts/tests/report.lua @@ -36,7 +36,7 @@ end function test_coordinates_unnamed_plane() local p = plane.create(0, -3, -3, 7, 7) local r = region.create(0, 0, "mountain") - local f = faction.create("unnamed@eressea.de", "human", "de") + local f = faction.create("human", "unnamed@eressea.de", "de") local u = unit.create(f, r, 1) init_reports() write_report(f) @@ -46,7 +46,7 @@ end function test_coordinates_no_plane() local r = region.create(0, 0, "mountain") - local f = faction.create("noplane@eressea.de", "human", "de") + local f = faction.create("human", "noplane@eressea.de", "de") local u = unit.create(f, r, 1) init_reports() write_report(f) @@ -56,7 +56,7 @@ end function test_show_shadowmaster_attacks() local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) u.race = "shadowmaster" u:clear_orders() @@ -71,7 +71,7 @@ end function test_coordinates_named_plane() local p = plane.create(0, -3, -3, 7, 7, "Hell") local r = region.create(0, 0, "mountain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) init_reports() write_report(f) @@ -82,7 +82,7 @@ end function test_coordinates_noname_plane() local p = plane.create(0, -3, -3, 7, 7, "") local r = region.create(0, 0, "mountain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 1) init_reports() write_report(f) @@ -93,7 +93,7 @@ end function test_lighthouse() eressea.free_game() local r = region.create(0, 0, "mountain") - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") region.create(1, 0, "mountain") region.create(2, 0, "ocean") region.create(0, 1, "firewall") diff --git a/scripts/tests/storage.lua b/scripts/tests/storage.lua index c262652db..32fbe9ef3 100644 --- a/scripts/tests/storage.lua +++ b/scripts/tests/storage.lua @@ -8,7 +8,7 @@ end function test_store_unit() local r = region.create(0, 0, "plain") - local f = faction.create("noreply15@eressea.de", "human", "de") + local f = faction.create("human", "noreply15@eressea.de", "de") local u = unit.create(f, r, 1) local fid = f.id u:add_item("money", u.number * 100) @@ -20,7 +20,7 @@ function test_store_unit() eressea.free_game() -- recreate world: r = region.create(0, 0, "plain") - f = faction.create("noreply16@eressea.de", "human", "de") + f = faction.create("human", "noreply16@eressea.de", "de") f.id = fid store = storage.create(filename, "rb") assert_not_nil(store) diff --git a/scripts/tests/study.lua b/scripts/tests/study.lua index 9bb8cda5e..2a713dd43 100644 --- a/scripts/tests/study.lua +++ b/scripts/tests/study.lua @@ -24,7 +24,7 @@ end function test_study() local r = region.create(0, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u = unit.create(f, r, 1) u:add_order("LERNEN Armbrust") process_orders() @@ -33,7 +33,7 @@ end function test_study_expensive() local r = region.create(0, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u = unit.create(f, r, 1) eressea.settings.set("skills.cost.alchemy", "50") eressea.settings.set("rules.encounters", "0") @@ -46,7 +46,7 @@ end function test_unit_spells() local r = region.create(0, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u = unit.create(f, r, 1) u.magic = "gray" u:set_skill("magic", 1) @@ -76,7 +76,7 @@ end function test_study_no_teacher() local r = region.create(0, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u1 = make_student(f, r, 1) u1:set_skill("crossbow", 1) process_orders() @@ -85,7 +85,7 @@ end function test_study_with_teacher() local r = region.create(0, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u1 = make_student(f, r, 1) make_teacher(u1) @@ -96,7 +96,7 @@ end function test_study_too_many_students() local r = region.create(0, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u1 = make_student(f, r, 20, "Taktik") u1.name = "Student" u1:add_item("money", 201*u1.number) @@ -107,7 +107,7 @@ end function test_study_multiple_teachers() local r = region.create(0, 0, "plain") - local f = faction.create("test@example.com", "human", "de") + local f = faction.create("human", "test@example.com", "de") local u1 = make_student(f, r, 20, "Taktik") u1.name = "Student" u1:add_item("money", 201*u1.number) diff --git a/scripts/tests/xmas.lua b/scripts/tests/xmas.lua index 459984901..304cc333a 100644 --- a/scripts/tests/xmas.lua +++ b/scripts/tests/xmas.lua @@ -15,7 +15,7 @@ end function test_snowglobe_fail() local r1 = region.create(0, 0, "glacier") local r2 = region.create(1, 0, "ocean") - local f = faction.create("snowglobe1@eressea.de", "human", "de") + local f = faction.create("human", "snowglobe1@eressea.de", "de") local u = unit.create(f, r1, 1) u:add_item("snowglobe", 1) u:clear_orders() @@ -30,7 +30,7 @@ end function test_snowglobe_missing_direction() local r1 = region.create(0, 0, "glacier") local r2 = region.create(1, 0, "ocean") - local f = faction.create("snowglobe1@eressea.de", "human", "de") + local f = faction.create("human", "snowglobe1@eressea.de", "de") local u = unit.create(f, r1, 1) u:add_item("snowglobe", 1) u:clear_orders() @@ -44,7 +44,7 @@ end function test_snowglobe() local r1 = region.create(0, 0, "glacier") local r2 = region.create(1, 0, "ocean") - local f = faction.create("snowglobe2@eressea.de", "human", "de") + local f = faction.create("human", "snowglobe2@eressea.de", "de") local u = unit.create(f, r1, 1) local fail = 0 u:add_item("snowglobe", have) @@ -62,7 +62,7 @@ end local function use_tree(terrain) local r = region.create(0, 0, terrain) - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u1 = unit.create(f, r, 5) r:set_resource("tree", 0) u1:add_item("xmastree", 1) @@ -86,7 +86,7 @@ function test_stardust() eressea.settings.set("rules.economy.repopulate_maximum", 0) local r = region.create(0, 0, "plain") r:set_resource("peasant", 10) - local f = faction.create("noreply@eressea.de", "human", "de") + local f = faction.create("human", "noreply@eressea.de", "de") local u = unit.create(f, r, 5) u:add_item("stardust", 1) u:clear_orders() diff --git a/src/bind_faction.c b/src/bind_faction.c index 518ccccac..d16f15936 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -401,8 +401,8 @@ static int tolua_faction_get(lua_State * L) static int tolua_faction_create(lua_State * L) { - const char *email = tolua_tostring(L, 1, 0); - const char *racename = tolua_tostring(L, 2, 0); + const char *racename = tolua_tostring(L, 1, 0); + const char *email = tolua_tostring(L, 2, 0); const char *lang = tolua_tostring(L, 3, 0); struct locale *loc = lang ? get_locale(lang) : default_locale; faction *f = NULL; diff --git a/src/economy.c b/src/economy.c index d5ee5a4bf..c34ba8134 100644 --- a/src/economy.c +++ b/src/economy.c @@ -813,7 +813,7 @@ static void manufacture(unit * u, const item_type * itype, int want) skill = effskill(u, sk, 0); skill = - skillmod(itype->rtype->attribs, u, u->region, sk, skill, SMF_PRODUCTION); + skillmod(itype->construction->attribs, u, u->region, sk, skill, SMF_PRODUCTION); if (skill < 0) { /* an error occured */ diff --git a/src/kernel/building.c b/src/kernel/building.c index 8fdfee544..ef95fd782 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -123,6 +123,7 @@ void free_buildingtypes(void) { building_type *bt_get_or_create(const char *name) { + assert(name && name[0]); if (name != NULL) { building_type *btype = bt_find_i(name); if (btype == NULL) { diff --git a/src/kernel/item.h b/src/kernel/item.h index d647bce8c..9727e805f 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -79,7 +79,6 @@ extern "C" { struct rawmaterial_type *raw; struct resource_mod *modifiers; /* --- pointers --- */ - struct attrib *attribs; struct item_type *itype; struct potion_type *ptype; struct luxury_type *ltype; diff --git a/src/kernel/skills.h b/src/kernel/skills.h index 192030dcf..bca7dca50 100644 --- a/src/kernel/skills.h +++ b/src/kernel/skills.h @@ -15,6 +15,12 @@ #include +struct race; +struct unit; +struct region; +struct attrib; +struct attrib_type; + #ifdef __cplusplus extern "C" { #endif From ae6d9f0e1ae9c52695c939c544f134bd15c34e1a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 18 Mar 2017 08:00:35 +0100 Subject: [PATCH 076/218] Zwergenbonus gibt es nur in E2 --- scripts/tests/e2/e2features.lua | 23 +++++++++++++++++++++++ scripts/tests/economy.lua | 23 ----------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index cecd8785a..3576b7349 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -39,6 +39,29 @@ function test_herbalism() assert_equal(98, r:get_resource("seed")) end +function test_dwarf_bonus() + local r = region.create(0, 0, "mountain") + r:set_resource("iron", 100) + local level = r:get_resourcelevel("iron") + assert_equal(1, level) + local u = unit.create(faction.create("dwarf"), r) + assert_equal("dwarf", u.faction.race) + assert_equal("dwarf", u.race) + u.faction.name = "Zwerge" + u.number = 10 + u:set_skill("mining", 1) + u:add_order("MACHE EISEN") + process_orders() + assert_equal(30, u:get_item("iron")) + assert_equal(82, r:get_resource("iron")) + u.building = building.create(r, "mine") + u.building.size = 10 + u:add_item("money", 500) -- maintenance + process_orders() + assert_equal(70, u:get_item("iron")) + assert_equal(70, r:get_resource("iron")) +end + function test_build_harbour() -- try to reproduce mantis bug 2221 local r = region.create(0, 0, "plain") diff --git a/scripts/tests/economy.lua b/scripts/tests/economy.lua index 807bda631..5d98f3f51 100644 --- a/scripts/tests/economy.lua +++ b/scripts/tests/economy.lua @@ -32,29 +32,6 @@ function test_mine_bonus() assert_equal(80, r:get_resource("iron")) end -function test_mine_example() - local r = region.create(0, 0, "mountain") - r:set_resource("iron", 100) - local level = r:get_resourcelevel("iron") - assert_equal(1, level) - local u = unit.create(faction.create("dwarf"), r) - assert_equal("dwarf", u.faction.race) - assert_equal("dwarf", u.race) - u.faction.name = "Zwerge" - u.number = 10 - u:set_skill("mining", 1) - u:add_order("MACHE EISEN") - process_orders() - assert_equal(30, u:get_item("iron")) - assert_equal(82, r:get_resource("iron")) - u.building = building.create(r, "mine") - u.building.size = 10 - u:add_item("money", 500) -- maintenance - process_orders() - assert_equal(70, u:get_item("iron")) - assert_equal(70, r:get_resource("iron")) -end - function test_no_guards() local r = region.create(0, 0, "plain") r:set_resource("tree", 100) From bdf7411954a7bd20ac2e8480baa6e1a531f3533c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 18 Mar 2017 10:33:52 +0100 Subject: [PATCH 077/218] backfill a test for smithies --- scripts/tests/economy.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/scripts/tests/economy.lua b/scripts/tests/economy.lua index 5d98f3f51..a1bfa3bb6 100644 --- a/scripts/tests/economy.lua +++ b/scripts/tests/economy.lua @@ -32,6 +32,25 @@ function test_mine_bonus() assert_equal(80, r:get_resource("iron")) end +function test_smithy_bonus() + local r = region.create(0, 0, "mountain") + local u = unit.create(faction.create("human"), r) + u:set_skill("weaponsmithing", 5) + u:add_item("iron", 20) + u:add_order("MACHE SCHWERT") + process_orders() + assert_equal(1, u:get_item('sword')) + assert_equal(19, u:get_item('iron')) + + u.building = building.create(r, "smithy") + u.building.size = 10 + u:add_item("money", 300) -- maintenance + u:add_item("log", 1) -- maintenance + process_orders() + assert_equal(3, u:get_item('sword')) + assert_equal(18, u:get_item('iron')) +end + function test_no_guards() local r = region.create(0, 0, "plain") r:set_resource("tree", 100) From 17145eaf10ce862ae654d1f0375a694a7ddc637b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 22 Mar 2017 20:37:09 +0100 Subject: [PATCH 078/218] make region:set_resource do the right thing also for adamantium --- scripts/tests/e2/adamantium.lua | 52 +++++++++++++++++++++++++++++++++ scripts/tests/e2/init.lua | 1 + src/bind_region.c | 2 +- src/economy.c | 10 +++++-- src/economy.test.c | 12 ++++---- src/kernel/region.c | 33 ++++++++++++++------- src/kernel/region.test.c | 27 +++++++++++++++++ src/kernel/resources.c | 33 +++++++++++++-------- src/kernel/resources.h | 6 ++-- src/kernel/save.c | 8 ++--- src/modules/autoseed.c | 14 --------- src/report.test.c | 3 +- src/reports.c | 9 +++--- 13 files changed, 151 insertions(+), 59 deletions(-) create mode 100644 scripts/tests/e2/adamantium.lua diff --git a/scripts/tests/e2/adamantium.lua b/scripts/tests/e2/adamantium.lua new file mode 100644 index 000000000..feb4f90a0 --- /dev/null +++ b/scripts/tests/e2/adamantium.lua @@ -0,0 +1,52 @@ +require "lunit" + +module("tests.e2.adamantium", package.seeall, lunit.testcase ) + +function setup() + eressea.free_game() + eressea.settings.set("nmr.timeout", "0") + eressea.settings.set("rules.food.flags", "4") + eressea.settings.set("rules.ship.storms", "0") + eressea.settings.set("rules.encounters", "0") +end + +local function _test_create_adamantium() + eressea.settings.set("rules.terraform.all", "1") + local r = region.create(0,0, "mountain") + local f1 = faction.create("human", "noreply19@eressea.de", "de") + local u1 = unit.create(f1, r, 1) + r:set_resource("adamantium", 50) + assert_equal(50, r:get_resource("adamantium")) + return r, u1 +end + +function test_adamantium1() + local r, u1 = _test_create_adamantium() + + u1:add_item("money", 1000) + u1:set_skill("mining", 14) + u1:clear_orders() + u1:add_order("MACHEN Adamantium") + + process_orders() + assert_equal(0, u1:get_item("adamantium")) +end + +function test_adamantium2() + local r, u1 = _test_create_adamantium() + + u1:add_item("money", 1000) + u1:set_skill("mining", 15) + u1:clear_orders() + u1:add_order("MACHEN Adamantium") + + local b = building.create(r, "mine") + b.size = 10 + u1.building = b + local adamantium = r:get_resource("adamantium") + + process_orders() + assert_equal(1, u1:get_item("adamantium")) + assert_equal(adamantium - 1, r:get_resource("adamantium")) +end + diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index 2f87b83fc..651a9ad9b 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -1,3 +1,4 @@ +require 'tests.e2.adamantium' require 'tests.e2.undead' require 'tests.e2.shiplanding' require 'tests.e2.e2features' diff --git a/src/bind_region.c b/src/bind_region.c index fdab4a10f..2f9309549 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -349,7 +349,7 @@ static int tolua_region_get_resourcelevel(lua_State * L) if (rtype != NULL) { const rawmaterial *rm; for (rm = r->resources; rm; rm = rm->next) { - if (rm->type->rtype == rtype) { + if (rm->rtype == rtype) { lua_pushinteger(L, rm->level); return 1; } diff --git a/src/economy.c b/src/economy.c index c34ba8134..ce174dd09 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1085,7 +1085,7 @@ leveled_allocation(const resource_type * rtype, region * r, allocation * alist) avail = MIN(avail, nreq); if (need > 0) { int use = 0; - for (al = alist; al; al = al->next) + for (al = alist; al; al = al->next) { if (!fval(al, AFL_DONE)) { if (avail > 0) { int want = required(al->want - al->get, al->save); @@ -1100,9 +1100,13 @@ leveled_allocation(const resource_type * rtype, region * r, allocation * alist) al->get = MIN(al->want, al->get + x * al->save.sa[1] / al->save.sa[0]); } } + } if (use) { - assert(use <= rm->amount); - rm->type->use(rm, r, use); + rawmaterial_type *raw = rmt_get(rm->rtype); + if (raw && raw->use) { + assert(use <= rm->amount); + raw->use(rm, r, use); + } } assert(avail == 0 || nreq == 0); } diff --git a/src/economy.test.c b/src/economy.test.c index 1fca4d194..a0a000ccd 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -383,14 +383,14 @@ static void test_make_item(CuTest *tc) { itype->construction->materials = 0; rtype->flags |= RTF_LIMITED; rmt_create(rtype); - add_resource(u->region, 1, 300, 150, rtype); - u->region->resources->amount = 300; /* there are 300 stones at level 1 */ + add_resource(u->region, 1, 300, 150, rtype); /* there are 300 stones at level 1 */ + CuAssertIntEquals(tc, 300, region_getresource(u->region, rtype)); set_level(u, SK_ALCHEMY, 10); make_item(u, itype, 10); split_allocations(u->region); CuAssertIntEquals(tc, 11, get_item(u, itype)); - CuAssertIntEquals(tc, 290, u->region->resources->amount); /* used 10 stones to make 10 stones */ + CuAssertIntEquals(tc, 290, region_getresource(u->region, rtype)); /* used 10 stones to make 10 stones */ rtype->modifiers = calloc(2, sizeof(resource_mod)); rtype->modifiers[0].flags = RMF_SAVEMATERIAL; @@ -400,18 +400,18 @@ static void test_make_item(CuTest *tc) { make_item(u, itype, 10); split_allocations(u->region); CuAssertIntEquals(tc, 21, get_item(u, itype)); - CuAssertIntEquals(tc, 284, u->region->resources->amount); /* 60% saving = 6 stones make 10 stones */ + CuAssertIntEquals(tc, 284, region_getresource(u->region, rtype)); /* 60% saving = 6 stones make 10 stones */ make_item(u, itype, 1); split_allocations(u->region); CuAssertIntEquals(tc, 22, get_item(u, itype)); - CuAssertIntEquals(tc, 283, u->region->resources->amount); /* no free lunches */ + CuAssertIntEquals(tc, 283, region_getresource(u->region, rtype)); /* no free lunches */ rtype->modifiers[0].value = frac_make(1, 2); make_item(u, itype, 6); split_allocations(u->region); CuAssertIntEquals(tc, 28, get_item(u, itype)); - CuAssertIntEquals(tc, 280, u->region->resources->amount); /* 50% saving = 3 stones make 6 stones */ + CuAssertIntEquals(tc, 280, region_getresource(u->region, rtype)); /* 50% saving = 3 stones make 6 stones */ rtype->modifiers[0].flags = RMF_REQUIREDBUILDING; rtype->modifiers[0].race = NULL; diff --git a/src/kernel/region.c b/src/kernel/region.c index 48256fb60..2a54a2eaa 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -826,7 +826,7 @@ void region_setresource(region * r, const resource_type * rtype, int value) { rawmaterial *rm = r->resources; while (rm) { - if (rm->type->rtype == rtype) { + if (rm->rtype == rtype) { rm->amount = value; break; } @@ -840,14 +840,27 @@ void region_setresource(region * r, const resource_type * rtype, int value) else if (rtype == get_resourcetype(R_HORSE)) rsethorses(r, value); else { - int i; - for (i = 0; r->terrain->production[i].type; ++i) { - const terrain_production *production = r->terrain->production + i; - if (production->type == rtype) { - add_resource(r, 1, value, dice_rand(production->divisor), rtype); - break; + rawmaterial *rm; + if (r->terrain->production) { + int i; + for (i = 0; r->terrain->production[i].type; ++i) { + const terrain_production *production = r->terrain->production + i; + if (production->type == rtype) { + add_resource(r, 1, value, dice_rand(production->divisor), rtype); + return; + } } } + /* adamantium etc are not usually terraformed: */ + for (rm = r->resources; rm; rm = rm->next) { + if (rm->rtype == rtype) { + rm->amount = value; + return; + } + } + if (!rm) { + add_resource(r, 1, value, 150, rtype); + } } } } @@ -856,7 +869,7 @@ int region_getresource(const region * r, const resource_type * rtype) { const rawmaterial *rm; for (rm = r->resources; rm; rm = rm->next) { - if (rm->type->rtype == rtype) { + if (rm->rtype == rtype) { return rm->amount; } } @@ -1047,8 +1060,8 @@ void terraform_region(region * r, const terrain_type * terrain) if (terrain->production != NULL) { int i; for (i = 0; terrain->production[i].type; ++i) { - if (rm->type->rtype == terrain->production[i].type) { - rtype = rm->type->rtype; + if (rm->rtype == terrain->production[i].type) { + rtype = rm->rtype; break; } } diff --git a/src/kernel/region.test.c b/src/kernel/region.test.c index 892b37a8e..879faad50 100644 --- a/src/kernel/region.test.c +++ b/src/kernel/region.test.c @@ -1,6 +1,7 @@ #include #include "region.h" +#include "resources.h" #include "building.h" #include "unit.h" #include "terrain.h" @@ -52,10 +53,36 @@ static void test_region_get_owner(CuTest *tc) { test_cleanup(); } +static void test_region_getset_resource(CuTest *tc) { + region *r; + item_type *itype; + + test_setup(); + init_resources(); + itype = test_create_itemtype("iron"); + itype->construction = calloc(1, sizeof(construction)); + rmt_create(itype->rtype); + r = test_create_region(0, 0, NULL); + + region_setresource(r, itype->rtype, 50); + CuAssertIntEquals(tc, 50, region_getresource(r, itype->rtype)); + + region_setresource(r, get_resourcetype(R_HORSE), 10); + CuAssertIntEquals(tc, 10, region_getresource(r, get_resourcetype(R_HORSE))); + CuAssertIntEquals(tc, 10, rhorses(r)); + + region_setresource(r, get_resourcetype(R_PEASANT), 10); + CuAssertIntEquals(tc, 10, region_getresource(r, get_resourcetype(R_PEASANT))); + CuAssertIntEquals(tc, 10, rpeasants(r)); + + test_cleanup(); +} + CuSuite *get_region_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_terraform); + SUITE_ADD_TEST(suite, test_region_getset_resource); SUITE_ADD_TEST(suite, test_region_get_owner); return suite; } diff --git a/src/kernel/resources.c b/src/kernel/resources.c index 932147a5f..f40bf0564 100644 --- a/src/kernel/resources.c +++ b/src/kernel/resources.c @@ -36,8 +36,10 @@ void update_resources(region * r) { struct rawmaterial *res = r->resources; while (res) { - if (res->type->update) - res->type->update(res, r); + struct rawmaterial_type *raw = rmt_get(res->rtype); + if (raw && raw->update) { + raw->update(res, r); + } res = res->next; } } @@ -55,7 +57,7 @@ static void update_resource(struct rawmaterial *res, double modifier) assert(res->amount > 0); } -void +struct rawmaterial * add_resource(region * r, int level, int base, int divisor, const resource_type * rtype) { @@ -66,12 +68,11 @@ const resource_type * rtype) rm->level = level; rm->startlevel = level; rm->base = base; + rm->amount = base; rm->divisor = divisor; rm->flags = 0; - rm->type = rmt_get(rtype); - assert(rm->type); - update_resource(rm, 1.0); - rm->type->terraform(rm, r); + rm->rtype = rtype; + return rm; } void terraform_resources(region * r) @@ -88,7 +89,7 @@ void terraform_resources(region * r) const resource_type *rtype = production->type; for (rm = r->resources; rm; rm = rm->next) { - if (rm->type->rtype == rtype) + if (rm->rtype == rtype) break; } if (rm) { @@ -96,9 +97,16 @@ void terraform_resources(region * r) } if (terraform_all || chance(production->chance)) { - add_resource(r, dice_rand(production->startlevel), + rawmaterial *rm; + rawmaterial_type *raw; + rm = add_resource(r, dice_rand(production->startlevel), dice_rand(production->base), dice_rand(production->divisor), production->type); + update_resource(rm, 1.0); + raw = rmt_get(rm->rtype); + if (raw && raw->terraform) { + raw->terraform(rm, r); + } } } } @@ -143,7 +151,7 @@ static int visible_default(const rawmaterial * res, int skilllevel) /* resources are visible, if skill equals minimum skill to mine them * plus current level of difficulty */ { - const struct item_type *itype = res->type->rtype->itype; + const struct item_type *itype = res->rtype->itype; if (res->level <= 1 && res->level + itype->construction->minskill <= skilllevel + 1) { assert(res->amount > 0); @@ -167,7 +175,7 @@ static void use_default(rawmaterial * res, const region * r, int amount) int i; for (i = 0; r->terrain->production[i].type; ++i) { - if (res->type->rtype == r->terrain->production[i].type) + if (res->rtype == r->terrain->production[i].type) break; } @@ -179,8 +187,9 @@ static void use_default(rawmaterial * res, const region * r, int amount) struct rawmaterial *rm_get(region * r, const struct resource_type *rtype) { struct rawmaterial *rm = r->resources; - while (rm && rm->type->rtype != rtype) + while (rm && rm->rtype != rtype) { rm = rm->next; + } return rm; } diff --git a/src/kernel/resources.h b/src/kernel/resources.h index 7f48fa0dd..3bae0778f 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -24,7 +24,7 @@ extern "C" { }; typedef struct rawmaterial { - const struct rawmaterial_type *type; + const struct resource_type *rtype; #ifdef LOMEM int amount:16; int level:8; @@ -68,8 +68,8 @@ extern "C" { struct rawmaterial_type *rmt_find(const char *str); struct rawmaterial_type *rmt_get(const struct resource_type *); - void add_resource(struct region *r, int level, int base, int divisor, - const struct resource_type *rtype); + struct rawmaterial *add_resource(struct region *r, int level, + int base, int divisor, const struct resource_type *rtype); struct rawmaterial_type *rmt_create(struct resource_type *rtype); extern int(*res_limit_fun)(const struct region *, const struct resource_type *); diff --git a/src/kernel/save.c b/src/kernel/save.c index 2e1686f2a..7237b0e81 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -954,11 +954,11 @@ static region *readregion(struct gamedata *data, int x, int y) if (strcmp(name, "end") == 0) break; res = malloc(sizeof(rawmaterial)); - res->type = rmt_find(name); - if (res->type == NULL) { + res->rtype = rt_find(name); + if (!res->rtype || !res->rtype->raw) { log_error("invalid resourcetype %s in data.", name); } - assert(res->type != NULL); + assert(res->rtype); READ_INT(data->store, &n); res->level = n; READ_INT(data->store, &n); @@ -1067,7 +1067,7 @@ void writeregion(struct gamedata *data, const region * r) WRITE_INT(data->store, rhorses(r)); while (res) { - WRITE_TOK(data->store, res->type->rtype->_name); + WRITE_TOK(data->store, res->rtype->_name); WRITE_INT(data->store, res->level); WRITE_INT(data->store, res->amount); WRITE_INT(data->store, res->startlevel); diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c index 1e2d2d23f..ffab4ca46 100644 --- a/src/modules/autoseed.c +++ b/src/modules/autoseed.c @@ -81,20 +81,6 @@ const terrain_type *random_terrain(const terrain_type * terrains[], return terrain; } -int seed_adamantium(region * r, int base) -{ - const resource_type *rtype = rt_find("adamantium"); - rawmaterial *rm; - for (rm = r->resources; rm; rm = rm->next) { - if (rm->type->rtype == rtype) - break; - } - if (!rm) { - add_resource(r, 1, base, 150, rtype); - } - return 0; -} - static int count_demand(const region * r) { struct demand *dmd; diff --git a/src/report.test.c b/src/report.test.c index 3c6a09ae1..2bdbebb7c 100644 --- a/src/report.test.c +++ b/src/report.test.c @@ -95,8 +95,7 @@ static void test_report_region(CuTest *tc) { mstream_init(&out); r = test_create_region(0, 0, 0); - add_resource(r, 1, 100, 10, rt_stone); - r->resources->amount = 135; + add_resource(r, 1, 135, 10, rt_stone); CuAssertIntEquals(tc, 1, r->resources->level); r->land->peasants = 5; r->land->horses = 7; diff --git a/src/reports.c b/src/reports.c index 88f6ebb21..353ed09fe 100644 --- a/src/reports.c +++ b/src/reports.c @@ -448,12 +448,13 @@ const faction * viewer, bool see_unit) rawmaterial *res = r->resources; while (res) { int maxskill = 0; - const item_type *itype = resource2item(res->type->rtype); + const item_type *itype = resource2item(res->rtype); int minskill = itype->construction->minskill; skill_t skill = itype->construction->skill; int level = res->level + minskill - 1; int visible = -1; - if (res->type->visible == NULL) { + rawmaterial_type *raw = rmt_get(res->rtype); + if (raw->visible == NULL) { visible = res->amount; level = res->level + minskill - 1; } @@ -464,7 +465,7 @@ const faction * viewer, bool see_unit) int s = effskill(u, skill, 0); if (s > maxskill) { maxskill = s; - visible = res->type->visible(res, maxskill); + visible = raw->visible(res, maxskill); } } } @@ -472,7 +473,7 @@ const faction * viewer, bool see_unit) if (level >= 0 && visible >= 0) { if (n >= size) return -1; - report_resource(result + n, res->type->rtype, visible, level); + report_resource(result + n, res->rtype, visible, level); n++; } res = res->next; From 0c8a9354db11079e29987cc02dd39af2df3ead95 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 22 Mar 2017 20:46:29 +0100 Subject: [PATCH 079/218] rmt_find no longer used. handle old data files with rm_iron, etc. --- src/kernel/resources.c | 10 ---------- src/kernel/resources.h | 1 - src/kernel/save.c | 3 +++ 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/kernel/resources.c b/src/kernel/resources.c index f40bf0564..8d6e1c2ac 100644 --- a/src/kernel/resources.c +++ b/src/kernel/resources.c @@ -193,16 +193,6 @@ struct rawmaterial *rm_get(region * r, const struct resource_type *rtype) return rm; } -struct rawmaterial_type *rmt_find(const char *str) -{ - resource_type *rtype = rt_find(str); - if (!rtype && strncmp(str, "rm_", 3) == 0) { - rtype = rt_find(str+3); - } - assert(rtype); - return rtype ? rtype->raw : NULL; -} - struct rawmaterial_type *rmt_get(const struct resource_type *rtype) { return rtype->raw; diff --git a/src/kernel/resources.h b/src/kernel/resources.h index 3bae0778f..67cd48d43 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -65,7 +65,6 @@ extern "C" { void terraform_resources(struct region *r); struct rawmaterial *rm_get(struct region *, const struct resource_type *); - struct rawmaterial_type *rmt_find(const char *str); struct rawmaterial_type *rmt_get(const struct resource_type *); struct rawmaterial *add_resource(struct region *r, int level, diff --git a/src/kernel/save.c b/src/kernel/save.c index 7237b0e81..105ad7324 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -955,6 +955,9 @@ static region *readregion(struct gamedata *data, int x, int y) break; res = malloc(sizeof(rawmaterial)); res->rtype = rt_find(name); + if (!res->rtype && strncmp("rm_", name, 3) == 0) { + res->rtype = rt_find(name + 3); + } if (!res->rtype || !res->rtype->raw) { log_error("invalid resourcetype %s in data.", name); } From 68e36e92523fade47b37fb9d8de44d5357962c12 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 23 Mar 2017 08:29:24 +0100 Subject: [PATCH 080/218] test that adamantium requires a mine --- scripts/tests/e2/adamantium.lua | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/tests/e2/adamantium.lua b/scripts/tests/e2/adamantium.lua index feb4f90a0..8cb703f33 100644 --- a/scripts/tests/e2/adamantium.lua +++ b/scripts/tests/e2/adamantium.lua @@ -22,21 +22,22 @@ end function test_adamantium1() local r, u1 = _test_create_adamantium() - + u1:add_item("money", 1000) - u1:set_skill("mining", 14) + u1:set_skill("mining", 8) u1:clear_orders() u1:add_order("MACHEN Adamantium") process_orders() + -- adamantium needs a mine, so nothing happens: assert_equal(0, u1:get_item("adamantium")) end function test_adamantium2() local r, u1 = _test_create_adamantium() - + u1.id = 42 u1:add_item("money", 1000) - u1:set_skill("mining", 15) + u1:set_skill("mining", 8) u1:clear_orders() u1:add_order("MACHEN Adamantium") From ab87b1da852f8e25016e6dc390b11c0bceea38ac Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 23 Mar 2017 18:51:30 +0100 Subject: [PATCH 081/218] add failing test for skill bonus from mine, start work --- scripts/tests/e2/adamantium.lua | 6 ++++++ src/economy.c | 14 ++++++++++---- src/kernel/building.h | 1 + 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/scripts/tests/e2/adamantium.lua b/scripts/tests/e2/adamantium.lua index 8cb703f33..0def0772f 100644 --- a/scripts/tests/e2/adamantium.lua +++ b/scripts/tests/e2/adamantium.lua @@ -49,5 +49,11 @@ function test_adamantium2() process_orders() assert_equal(1, u1:get_item("adamantium")) assert_equal(adamantium - 1, r:get_resource("adamantium")) + + -- mines give +1 to mining. mining 16 should give 2 adamantium + u1:set_skill("mining", 15) + process_orders() + assert_equal(3, u1:get_item("adamantium")) + assert_equal(adamantium - 3, r:get_resource("adamantium")) end diff --git a/src/economy.c b/src/economy.c index ce174dd09..971cbe794 100644 --- a/src/economy.c +++ b/src/economy.c @@ -923,7 +923,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) allocation *al; const resource_type *rring; int amount, skill, skill_mod = 0; - variant save_mod; + variant save_mod = frac_make(1, 1); /* momentan kann man keine ressourcen abbauen, wenn man daf�r * Materialverbrauch hat: */ @@ -950,9 +950,15 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) return; } } - else { - save_mod.sa[0] = 1; - save_mod.sa[1] = 1; + if (u->building && u->building->type->modifiers) { + building *b = inside_building(u); + if (b) { + message *msg = get_modifiers(u, b->type->modifiers, &save_mod, &skill_mod); + if (msg) { + ADDMSG(&u->faction->msgs, msg); + return; + } + } } /* Bergw�chter k�nnen Abbau von Eisen/Laen durch Bewachen verhindern. diff --git a/src/kernel/building.h b/src/kernel/building.h index 6d66aa9ab..88fe9bedd 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -73,6 +73,7 @@ extern "C" { void(*age) (struct building *); double(*taxes) (const struct building *, int size); struct attrib *attribs; + struct resource_mod *modifiers; } building_type; extern struct selist *buildingtypes; From 485e8f0ce49bc0360bcb989c5de51e14fb2c3eae Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 23 Mar 2017 19:28:56 +0100 Subject: [PATCH 082/218] Revert "add failing test for skill bonus from mine, start work" This reverts commit ab87b1da852f8e25016e6dc390b11c0bceea38ac. --- scripts/tests/e2/adamantium.lua | 6 ------ src/economy.c | 14 ++++---------- src/kernel/building.h | 1 - 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/scripts/tests/e2/adamantium.lua b/scripts/tests/e2/adamantium.lua index 0def0772f..8cb703f33 100644 --- a/scripts/tests/e2/adamantium.lua +++ b/scripts/tests/e2/adamantium.lua @@ -49,11 +49,5 @@ function test_adamantium2() process_orders() assert_equal(1, u1:get_item("adamantium")) assert_equal(adamantium - 1, r:get_resource("adamantium")) - - -- mines give +1 to mining. mining 16 should give 2 adamantium - u1:set_skill("mining", 15) - process_orders() - assert_equal(3, u1:get_item("adamantium")) - assert_equal(adamantium - 3, r:get_resource("adamantium")) end diff --git a/src/economy.c b/src/economy.c index 971cbe794..ce174dd09 100644 --- a/src/economy.c +++ b/src/economy.c @@ -923,7 +923,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) allocation *al; const resource_type *rring; int amount, skill, skill_mod = 0; - variant save_mod = frac_make(1, 1); + variant save_mod; /* momentan kann man keine ressourcen abbauen, wenn man daf�r * Materialverbrauch hat: */ @@ -950,15 +950,9 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) return; } } - if (u->building && u->building->type->modifiers) { - building *b = inside_building(u); - if (b) { - message *msg = get_modifiers(u, b->type->modifiers, &save_mod, &skill_mod); - if (msg) { - ADDMSG(&u->faction->msgs, msg); - return; - } - } + else { + save_mod.sa[0] = 1; + save_mod.sa[1] = 1; } /* Bergw�chter k�nnen Abbau von Eisen/Laen durch Bewachen verhindern. diff --git a/src/kernel/building.h b/src/kernel/building.h index 88fe9bedd..6d66aa9ab 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -73,7 +73,6 @@ extern "C" { void(*age) (struct building *); double(*taxes) (const struct building *, int size); struct attrib *attribs; - struct resource_mod *modifiers; } building_type; extern struct selist *buildingtypes; From f941c5552ff112592e82d473403146619e304260 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 23 Mar 2017 19:32:17 +0100 Subject: [PATCH 083/218] remove RF_SELECT code from split_allocations. the flag was only ever written, never read. --- src/economy.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/economy.c b/src/economy.c index ce174dd09..e3a6dc18d 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1170,7 +1170,6 @@ static allocate_function get_allocator(const struct resource_type *rtype) void split_allocations(region * r) { allocation_list **p_alist = &allocations; - freset(r, RF_SELECT); while (*p_alist) { allocation_list *alist = *p_alist; const resource_type *rtype = alist->type; @@ -1178,7 +1177,6 @@ void split_allocations(region * r) const item_type *itype = resource2item(rtype); allocation **p_al = &alist->data; - freset(r, RF_SELECT); alloc(rtype, r, alist->data); while (*p_al) { @@ -1187,7 +1185,6 @@ void split_allocations(region * r) assert(itype || !"not implemented for non-items"); i_change(&al->unit->items, itype, al->get); produceexp(al->unit, itype->construction->skill, al->unit->number); - fset(r, RF_SELECT); } if (al->want == INT_MAX) al->want = al->get; From b44c5e54bfb892d304e80c97290596ac55dfc633 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 25 Mar 2017 10:37:13 +0100 Subject: [PATCH 084/218] =?UTF-8?q?Neuer=20Befehlespr=C3=A4fix:=20!=20zur?= =?UTF-8?q?=20Unterdr=C3=BCckung=20von=20Fehlern.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/tests/laws.lua | 1 + scripts/tests/orders.lua | 12 +++++++ src/kernel/messages.c | 19 +++++++---- src/kernel/messages.test.c | 18 ++++++++++ src/kernel/order.c | 24 +++++++++---- src/kernel/order.h | 1 + src/kernel/order.test.c | 70 +++++++++++++++++++++++++++++++------- src/monsters.c | 10 ++---- src/piracy.c | 3 ++ src/piracy.test.c | 1 + 10 files changed, 125 insertions(+), 34 deletions(-) diff --git a/scripts/tests/laws.lua b/scripts/tests/laws.lua index 8b64ffb7f..3a724a440 100644 --- a/scripts/tests/laws.lua +++ b/scripts/tests/laws.lua @@ -16,6 +16,7 @@ function setup() "attack" : "ATTACKIERE", "maketemp" : "MACHETEMP", "end" : "ENDE", + "use" : "BENUTZEN", "recruit" : "REKRUTIERE" } }, diff --git a/scripts/tests/orders.lua b/scripts/tests/orders.lua index d88a59293..af0919640 100644 --- a/scripts/tests/orders.lua +++ b/scripts/tests/orders.lua @@ -20,6 +20,18 @@ function setup() eressea.settings.set("NewbieImmunity", "0") end +function test_no_errors() + turn_begin() + u:add_order("!BENUTZEN 23 Yanxspirit") + turn_process() + assert_equal(0, f:count_msg_type('error43')) + u:clear_orders() + u:add_order("BENUTZEN 23 Yanxspirit") + turn_process() + assert_equal(1, f:count_msg_type('error43')) + turn_end() +end + function test_learn() u:add_order("LERNEN Hiebwaffen") _G.process_orders() diff --git a/src/kernel/messages.c b/src/kernel/messages.c index f74e9c0d7..a157e276c 100644 --- a/src/kernel/messages.c +++ b/src/kernel/messages.c @@ -86,9 +86,6 @@ struct message *msg_feedback(const struct unit *u, struct order *ord, variant var; memset(args, 0, sizeof(args)); - if (ord == NULL) - ord = u->thisorder; - if (!mtype) { log_warning("trying to create message of unknown type \"%s\"\n", name); if (!mt_find("missing_feedback")) { @@ -248,8 +245,12 @@ void addmessage(region * r, faction * f, const char *s, msg_t mtype, int level) message * msg_error(const unit * u, struct order *ord, int mno) { static char msgname[20]; - if (fval(u->faction, FFL_NPC)) - return 0; + if (ord && ord->_noerror) { + return NULL; + } + if (fval(u->faction, FFL_NPC)) { + return NULL; + } sprintf(msgname, "error%d", mno); return msg_feedback(u, ord, msgname, ""); } @@ -259,7 +260,9 @@ message * cmistake(const unit * u, struct order *ord, int mno, int mtype) message * result; UNUSED_ARG(mtype); result = msg_error(u, ord, mno); - ADDMSG(&u->faction->msgs, result); + if (result) { + ADDMSG(&u->faction->msgs, result); + } return result; } @@ -267,7 +270,9 @@ void syntax_error(const struct unit *u, struct order *ord) { message * result; result = msg_error(u, ord, 10); - ADDMSG(&u->faction->msgs, result); + if (result) { + ADDMSG(&u->faction->msgs, result); + } } void free_messagelist(mlist *msgs) diff --git a/src/kernel/messages.test.c b/src/kernel/messages.test.c index 7b0f2dd5e..9cc3a138b 100644 --- a/src/kernel/messages.test.c +++ b/src/kernel/messages.test.c @@ -1,6 +1,9 @@ #include #include "messages.h" +#include "unit.h" +#include "order.h" + #include #include @@ -68,11 +71,26 @@ static void test_merge_split(CuTest *tc) { test_cleanup(); } +static void test_noerror(CuTest *tc) { + unit *u; + struct locale *lang; + + test_setup(); + lang = test_create_locale(); + u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); + u->thisorder = parse_order("!@move", lang); + CuAssertTrue(tc, u->thisorder->_persistent); + CuAssertTrue(tc, u->thisorder->_noerror); + CuAssertPtrEquals(tc, NULL, msg_error(u, u->thisorder, 100)); + test_cleanup(); +} + CuSuite *get_messages_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_missing_message); SUITE_ADD_TEST(suite, test_merge_split); SUITE_ADD_TEST(suite, test_message); + SUITE_ADD_TEST(suite, test_noerror); return suite; } diff --git a/src/kernel/order.c b/src/kernel/order.c index 776190b67..9e7a45991 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -99,6 +99,15 @@ char* get_command(const order *ord, char *sbuffer, size_t size) { keyword_t kwd = ORD_KEYWORD(ord); int bytes; + if (ord->_noerror) { + if (size > 0) { + *bufp++ = '!'; + --size; + } + else { + WARN_STATIC_BUFFER(); + } + } if (ord->_persistent) { if (size > 0) { *bufp++ = '@'; @@ -159,6 +168,7 @@ order *copy_order(const order * src) order *ord = (order *)malloc(sizeof(order)); ord->next = NULL; ord->_persistent = src->_persistent; + ord->_noerror = src->_noerror; ord->data = src->data; ++ord->data->_refcount; return ord; @@ -280,7 +290,7 @@ void close_orders(void) { } static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent, - const struct locale *lang) + bool noerror, const struct locale *lang) { order *ord = NULL; int lindex; @@ -313,6 +323,7 @@ static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent, ord = (order *)malloc(sizeof(order)); ord->_persistent = persistent; + ord->_noerror = noerror; ord->next = NULL; ord->data = create_data(kwd, sptr, lindex); @@ -373,7 +384,7 @@ order *create_order(keyword_t kwd, const struct locale * lang, else { zBuffer[0] = 0; } - return create_order_i(kwd, zBuffer, false, lang); + return create_order_i(kwd, zBuffer, false, false, lang); } order *parse_order(const char *s, const struct locale * lang) @@ -386,11 +397,12 @@ order *parse_order(const char *s, const struct locale * lang) if (*s != 0) { keyword_t kwd; const char *sptr; - bool persistent = false; + bool persistent = false, noerror = false; const char * p; - while (*s == '@') { - persistent = true; + while (*s == '!' || *s=='@') { + if (*s=='!') noerror = true; + else if (*s == '@') persistent = true; ++s; } sptr = s; @@ -407,7 +419,7 @@ order *parse_order(const char *s, const struct locale * lang) if (kwd != NOKEYWORD) { while (isspace(*(unsigned char *)sptr)) ++sptr; s = sptr; - return create_order_i(kwd, s, persistent, lang); + return create_order_i(kwd, s, persistent, noerror, lang); } } return NULL; diff --git a/src/kernel/order.h b/src/kernel/order.h index 7f4b00a5e..bf4d02982 100644 --- a/src/kernel/order.h +++ b/src/kernel/order.h @@ -37,6 +37,7 @@ extern "C" { /* do not access this data: */ struct order_data *data; bool _persistent; + bool _noerror; } order; /* constructor */ diff --git a/src/kernel/order.test.c b/src/kernel/order.test.c index f5eb51c6f..876d75b1e 100644 --- a/src/kernel/order.test.c +++ b/src/kernel/order.test.c @@ -14,14 +14,13 @@ static void test_create_order(CuTest *tc) { order *ord; struct locale * lang; - test_cleanup(); - lang = get_or_create_locale("en"); + test_setup(); + lang = test_create_locale(); - locale_setstring(lang, "keyword::move", "MOVE"); ord = create_order(K_MOVE, lang, "NORTH"); CuAssertPtrNotNull(tc, ord); CuAssertIntEquals(tc, K_MOVE, getkeyword(ord)); - CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd))); + CuAssertStrEquals(tc, "move NORTH", get_command(ord, cmd, sizeof(cmd))); CuAssertIntEquals(tc, K_MOVE, init_order(ord)); CuAssertStrEquals(tc, "NORTH", getstrtoken()); @@ -34,19 +33,44 @@ static void test_parse_order(CuTest *tc) { order *ord; struct locale * lang; - test_cleanup(); - lang = get_or_create_locale("en"); + test_setup(); + lang = test_create_locale(); - locale_setstring(lang, "keyword::move", "MOVE"); - init_keyword(lang, K_MOVE, "MOVE"); ord = parse_order("MOVE NORTH", lang); CuAssertPtrNotNull(tc, ord); + CuAssertTrue(tc, !ord->_noerror); + CuAssertTrue(tc, !ord->_persistent); CuAssertIntEquals(tc, K_MOVE, getkeyword(ord)); - CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd))); + CuAssertStrEquals(tc, "move NORTH", get_command(ord, cmd, sizeof(cmd))); CuAssertIntEquals(tc, K_MOVE, init_order(ord)); CuAssertStrEquals(tc, "NORTH", getstrtoken()); free_order(ord); + + ord = parse_order("!MOVE NORTH", lang); + CuAssertPtrNotNull(tc, ord); + CuAssertTrue(tc, ord->_noerror); + CuAssertTrue(tc, !ord->_persistent); + free_order(ord); + + ord = parse_order("@MOVE NORTH", lang); + CuAssertPtrNotNull(tc, ord); + CuAssertTrue(tc, !ord->_noerror); + CuAssertTrue(tc, ord->_persistent); + free_order(ord); + + ord = parse_order("@!MOVE NORTH", lang); + CuAssertPtrNotNull(tc, ord); + CuAssertTrue(tc, ord->_noerror); + CuAssertTrue(tc, ord->_persistent); + free_order(ord); + + ord = parse_order("!@MOVE NORTH", lang); + CuAssertPtrNotNull(tc, ord); + CuAssertTrue(tc, ord->_noerror); + CuAssertTrue(tc, ord->_persistent); + free_order(ord); + test_cleanup(); } @@ -81,7 +105,7 @@ static void test_parse_make_temp(CuTest *tc) { lang = get_or_create_locale("en"); locale_setstring(lang, keyword(K_MAKE), "MAKE"); locale_setstring(lang, keyword(K_MAKETEMP), "MAKETEMP"); - locale_setstring(lang, "TEMP", "TEMP"); + locale_setstring(lang, parameters[P_TEMP], "TEMP"); init_locale(lang); ord = parse_order("M T herp", lang); @@ -156,9 +180,9 @@ static void test_replace_order(CuTest *tc) { struct locale * lang; test_cleanup(); - lang = get_or_create_locale("en"); - orig = create_order(K_MAKE, lang, 0); - repl = create_order(K_ALLY, lang, 0); + lang = test_create_locale(); + orig = create_order(K_MAKE, lang, NULL); + repl = create_order(K_ALLY, lang, NULL); replace_order(&orders, orig, repl); CuAssertPtrEquals(tc, 0, orders); orders = orig; @@ -171,6 +195,25 @@ static void test_replace_order(CuTest *tc) { test_cleanup(); } +static void test_get_command(CuTest *tc) { + struct locale * lang; + order *ord; + char buf[64]; + + test_setup(); + lang = test_create_locale(); + ord = create_order(K_MAKE, lang, "iron"); + CuAssertStrEquals(tc, "make iron", get_command(ord, buf, sizeof(buf))); + ord->_noerror = true; + CuAssertStrEquals(tc, "!make iron", get_command(ord, buf, sizeof(buf))); + ord->_persistent = true; + CuAssertStrEquals(tc, "!@make iron", get_command(ord, buf, sizeof(buf))); + ord->_noerror = false; + CuAssertStrEquals(tc, "@make iron", get_command(ord, buf, sizeof(buf))); + free_order(ord); + test_cleanup(); +} + CuSuite *get_order_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -183,5 +226,6 @@ CuSuite *get_order_suite(void) SUITE_ADD_TEST(suite, test_replace_order); SUITE_ADD_TEST(suite, test_skip_token); SUITE_ADD_TEST(suite, test_getstrtoken); + SUITE_ADD_TEST(suite, test_get_command); return suite; } diff --git a/src/monsters.c b/src/monsters.c index 0d9857024..4edaeedea 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -493,18 +493,12 @@ static order *make_movement_order(unit * u, const region * target, int moves, if (plan == NULL) return NULL; - bytes = - (int)strlcpy(bufp, - (const char *)LOC(u->faction->locale, keyword(K_MOVE)), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - while (position != moves && plan[position + 1]) { region *prev = plan[position]; region *next = plan[++position]; direction_t dir = reldirection(prev, next); assert(dir != NODIRECTION && dir != D_SPECIAL); - if (size > 1) { + if (size > 1 && bufp != zOrder) { *bufp++ = ' '; --size; } @@ -516,7 +510,7 @@ static order *make_movement_order(unit * u, const region * target, int moves, } *bufp = 0; - return parse_order(zOrder, u->faction->locale); + return create_order(K_MOVE, u->faction->locale, zOrder); } void random_growl(const unit *u, region *target, int rand) diff --git a/src/piracy.c b/src/piracy.c index 80b1dd47a..3025d484c 100644 --- a/src/piracy.c +++ b/src/piracy.c @@ -66,6 +66,8 @@ static attrib *mk_piracy(const faction * pirate, const faction * target, } static bool validate_pirate(unit *u, order *ord) { + assert(u); + assert(ord); if (fval(u_race(u), RCF_SWIM | RCF_FLY)) return true; if (!u->ship) { @@ -128,6 +130,7 @@ void piracy_cmd(unit * u) int saff = 0; int *il; + assert(u->thisorder); if (!validate_pirate(u, u->thisorder)) { return; } diff --git a/src/piracy.test.c b/src/piracy.test.c index 40e66af18..33860e03f 100644 --- a/src/piracy.test.c +++ b/src/piracy.test.c @@ -137,6 +137,7 @@ static void test_piracy_cmd_errors(CuTest * tc) { u_set_ship(u, test_create_ship(u->region, st_boat)); u2 = test_create_unit(u->faction, u->region); + u2->thisorder = create_order(K_PIRACY, f->locale, ""); u_set_ship(u2, u->ship); test_clear_messages(f); From 868f4e6cef80afb4e4ee7d7a2d9b9f578a142450 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 25 Mar 2017 11:36:29 +0100 Subject: [PATCH 085/218] also apply noerror rules to msg_feedback. --- src/kernel/messages.c | 77 ++++++++++++++++++++------------------ src/kernel/messages.test.c | 1 + 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/kernel/messages.c b/src/kernel/messages.c index a157e276c..d3cd4f99b 100644 --- a/src/kernel/messages.c +++ b/src/kernel/messages.c @@ -78,14 +78,15 @@ variant v) struct message *msg_feedback(const struct unit *u, struct order *ord, const char *name, const char *sig, ...) { - va_list marker; const message_type *mtype = mt_find(name); - char paramname[64]; - const char *ic = sig; variant args[16]; variant var; memset(args, 0, sizeof(args)); + if (ord && ord->_noerror) { + return NULL; + } + if (!mtype) { log_warning("trying to create message of unknown type \"%s\"\n", name); if (!mt_find("missing_feedback")) { @@ -103,41 +104,46 @@ struct message *msg_feedback(const struct unit *u, struct order *ord, var.v = (void *)ord; arg_set(args, mtype, "command", var); - va_start(marker, sig); - while (*ic && !isalnum(*ic)) - ic++; - while (*ic) { - char *oc = paramname; - int i; + if (sig) { + const char *ic = sig; + va_list marker; - while (isalnum(*ic)) - *oc++ = *ic++; - *oc = '\0'; - - for (i = 0; i != mtype->nparameters; ++i) { - if (!strcmp(paramname, mtype->pnames[i])) - break; - } - if (i != mtype->nparameters) { - if (mtype->types[i]->vtype == VAR_VOIDPTR) { - args[i].v = va_arg(marker, void *); - } - else if (mtype->types[i]->vtype == VAR_INT) { - args[i].i = va_arg(marker, int); - } - else { - assert(!"unknown variant type"); - } - } - else { - log_error("invalid parameter %s for message type %s\n", paramname, mtype->name); - assert(!"program aborted."); - } + va_start(marker, sig); while (*ic && !isalnum(*ic)) ic++; - } - va_end(marker); + while (*ic) { + char paramname[64]; + char *oc = paramname; + int i; + while (isalnum(*ic)) + *oc++ = *ic++; + *oc = '\0'; + + for (i = 0; i != mtype->nparameters; ++i) { + if (!strcmp(paramname, mtype->pnames[i])) + break; + } + if (i != mtype->nparameters) { + if (mtype->types[i]->vtype == VAR_VOIDPTR) { + args[i].v = va_arg(marker, void *); + } + else if (mtype->types[i]->vtype == VAR_INT) { + args[i].i = va_arg(marker, int); + } + else { + assert(!"unknown variant type"); + } + } + else { + log_error("invalid parameter %s for message type %s\n", paramname, mtype->name); + assert(!"program aborted."); + } + while (*ic && !isalnum(*ic)) + ic++; + } + va_end(marker); + } return msg_create(mtype, args); } @@ -245,9 +251,6 @@ void addmessage(region * r, faction * f, const char *s, msg_t mtype, int level) message * msg_error(const unit * u, struct order *ord, int mno) { static char msgname[20]; - if (ord && ord->_noerror) { - return NULL; - } if (fval(u->faction, FFL_NPC)) { return NULL; } diff --git a/src/kernel/messages.test.c b/src/kernel/messages.test.c index 9cc3a138b..cd301756d 100644 --- a/src/kernel/messages.test.c +++ b/src/kernel/messages.test.c @@ -82,6 +82,7 @@ static void test_noerror(CuTest *tc) { CuAssertTrue(tc, u->thisorder->_persistent); CuAssertTrue(tc, u->thisorder->_noerror); CuAssertPtrEquals(tc, NULL, msg_error(u, u->thisorder, 100)); + CuAssertPtrEquals(tc, NULL, msg_feedback(u, u->thisorder, "error_unit_not_found", NULL)); test_cleanup(); } From 733c754e0f1cca7bb656cb5a92550ac962f48ce0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 25 Mar 2017 14:15:01 +0100 Subject: [PATCH 086/218] rename some configuration options. add them to the valid keys for eressea.ini, too. --- conf/e2/config.json | 4 +--- conf/e3/config.json | 4 +--- src/creport.c | 2 +- src/gmtool.c | 4 ++-- src/main.c | 2 ++ 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/conf/e2/config.json b/conf/e2/config.json index f9f9b2df0..46ee01497 100644 --- a/conf/e2/config.json +++ b/conf/e2/config.json @@ -21,9 +21,7 @@ "GiveRestriction": 3, "hunger.long": true, "init_spells": 0, - "world.era": 2, - "seed.population.min": 8, - "seed.population.max": 8, + "game.era": 2, "rules.reserve.twophase": true, "rules.give.max_men": -1, "rules.check_overload": false, diff --git a/conf/e3/config.json b/conf/e3/config.json index a42961e03..beb45f35d 100644 --- a/conf/e3/config.json +++ b/conf/e3/config.json @@ -51,9 +51,7 @@ "recruit.allow_merge": true, "study.expensivemigrants": true, "study.speedup": 2, - "world.era": 3, - "seed.population.min": 8, - "seed.population.max": 8, + "game.era": 3, "rules.reserve.twophase": true, "rules.owners.force_leave": false, "rules.wage.function": 2, diff --git a/src/creport.c b/src/creport.c index 14e6e8faa..113bb70ca 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1501,7 +1501,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom) static int rc_cache; if (era < 0) { - era = config_get_int("world.era", 1); + era = config_get_int("game.era", 1); } if (F == NULL) { perror(filename); diff --git a/src/gmtool.c b/src/gmtool.c index 148aafe6d..674e139f7 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -902,8 +902,8 @@ static void handlekey(state * st, int c) new_players = read_newfactions(sbuffer); } cnormalize(&st->cursor, &nx, &ny); - minpop = config_get_int("seed.population.min", 8); - maxpop = config_get_int("seed.population.max", minpop); + minpop = config_get_int("editor.population.min", 8); + maxpop = config_get_int("editor.population.max", minpop); if (maxpop > minpop) { n = rng_int() % (maxpop - minpop) + minpop; } diff --git a/src/main.c b/src/main.c index a9a8339d4..7b1c62c38 100644 --- a/src/main.c +++ b/src/main.c @@ -82,9 +82,11 @@ static const char * valid_keys[] = { "game.memcheck", "game.email", "game.mailcmd", + "game.era", "game.sender", "editor.color", "editor.codepage", + "editor.population.", "lua.", NULL }; From ce0c6a0d32abf597b132685ce0c227a624e1f7ff Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 25 Mar 2017 18:35:00 +0100 Subject: [PATCH 087/218] pdcurses version 3.4 warning suppression. --- src/platform.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform.h b/src/platform.h index 6ccbb8d6d..a56328485 100644 --- a/src/platform.h +++ b/src/platform.h @@ -1,5 +1,7 @@ #pragma once +#define _LP64 0 /* fix a warning in pdcurses 3.4 */ + #ifndef UNILIB_H #define UNILIB_H From d238e1819159513852d4aff18914b136d6ae83f9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 25 Mar 2017 18:36:27 +0100 Subject: [PATCH 088/218] fix duplicate definition --- src/platform.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform.h b/src/platform.h index a56328485..104ff28d7 100644 --- a/src/platform.h +++ b/src/platform.h @@ -1,6 +1,8 @@ #pragma once +#ifndef _LP64 #define _LP64 0 /* fix a warning in pdcurses 3.4 */ +#endif #ifndef UNILIB_H #define UNILIB_H From 7ee5a3624e4177b13ea63565cd63449fa4a3aa2f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Mar 2017 08:57:35 +0200 Subject: [PATCH 089/218] allow game.start in ini file --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index 7b1c62c38..e67982108 100644 --- a/src/main.c +++ b/src/main.c @@ -75,6 +75,7 @@ static void load_inifile(void) static const char * valid_keys[] = { "game.id", "game.name", + "game.start", "game.locale", "game.verbose", "game.report", From 03653a733881f49937c3be4efdad4ce6be4d11cb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Mar 2017 18:07:44 +0200 Subject: [PATCH 090/218] fix two live warnings (unicode trim and fleechance registration) --- src/attributes/attributes.c | 1 - src/laws.c | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index 0fe42a92e..c4925b9c0 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -94,7 +94,6 @@ void register_attributes(void) at_register(&at_woodcount); /* neue UNIT-Attribute */ - at_register(&at_fleechance); at_register(&at_siege); at_register(&at_effect); at_register(&at_private); diff --git a/src/laws.c b/src/laws.c index 736510cd2..9b3e9946a 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1610,10 +1610,12 @@ int display_cmd(unit * u, struct order *ord) free(*s); if (s2) { - *s = strdup(s2); - if (strlen(s2) >= DISPLAYSIZE) { - (*s)[DISPLAYSIZE] = 0; + char * str = strdup(s2); + unicode_utf8_trim(str); + if (strlen(str) >= DISPLAYSIZE) { + str[DISPLAYSIZE-1] = 0; } + *s = str; } else { *s = 0; From 6b4a8e677fead31a4e9b4ce37eeb1c3280c42a79 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Mar 2017 20:15:06 +0200 Subject: [PATCH 091/218] remove cmake submodule --- .gitmodules | 3 --- cmake | 1 - 2 files changed, 4 deletions(-) delete mode 160000 cmake diff --git a/.gitmodules b/.gitmodules index 7dff5ab6a..4d903c57f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "lunit"] path = lunit url = https://github.com/ennorehling/lunit.git -[submodule "cmake"] - path = cmake - url = https://github.com/ennorehling/cmake.git [submodule "dlmalloc"] path = dlmalloc url = https://github.com/ennorehling/dlmalloc.git diff --git a/cmake b/cmake deleted file mode 160000 index f1fb3943a..000000000 --- a/cmake +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f1fb3943ace59994d90d71a891b80033dc2700a2 From f8d49e07af0904f7f803aecf0823fd5afeac6e9a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Mar 2017 20:25:27 +0200 Subject: [PATCH 092/218] remove outdated custom CMake Modules. only keep what is not in CMake 3.6. --- CMakeLists.txt | 4 +- cmake/Modules/FindMSVC.cmake | 21 ++++++++++ cmake/Modules/FindSQLite3.cmake | 37 +++++++++++++++++ cmake/Modules/FindToLua.cmake | 71 +++++++++++++++++++++++++++++++++ s/cmake-init | 3 +- 5 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 cmake/Modules/FindMSVC.cmake create mode 100644 cmake/Modules/FindSQLite3.cmake create mode 100644 cmake/Modules/FindToLua.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 405b86a03..302e9065e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.6) if (WIN32) FILE(TO_CMAKE_PATH "${CMAKE_MODULE_PATH}" CMAKE_MODULE_PATH ) FILE(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH ) @@ -6,6 +6,8 @@ endif(WIN32) project (eressea-server C) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") + enable_testing() find_package (LibXml2) find_package (SQLite3) diff --git a/cmake/Modules/FindMSVC.cmake b/cmake/Modules/FindMSVC.cmake new file mode 100644 index 000000000..b93fed898 --- /dev/null +++ b/cmake/Modules/FindMSVC.cmake @@ -0,0 +1,21 @@ +MACRO (MSVC_CRT_SECURE_NO_WARNINGS) + IF (MSVC) + FOREACH (target ${ARGN}) + SET_TARGET_PROPERTIES (${target} PROPERTIES + COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS + ) + ENDFOREACH (target) + ENDIF (MSVC) +ENDMACRO (MSVC_CRT_SECURE_NO_WARNINGS) + +MACRO (MSVC_SET_WARNING_LEVEL level) + IF (MSVC) + IF(CMAKE_C_FLAGS MATCHES "/W[0-4]") + STRING(REGEX REPLACE "/W[0-4]" "/W${level}" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + ELSE() + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W${level}") + ENDIF() + ENDIF(MSVC) +ENDMACRO (MSVC_SET_WARNING_LEVEL) + +SET(MSVC_FOUND 1) diff --git a/cmake/Modules/FindSQLite3.cmake b/cmake/Modules/FindSQLite3.cmake new file mode 100644 index 000000000..c3689205d --- /dev/null +++ b/cmake/Modules/FindSQLite3.cmake @@ -0,0 +1,37 @@ +# Copyright (C) 2007-2009 LuaDist. +# Created by Peter Kapec +# Redistribution and use of this file is allowed according to the terms of the MIT license. +# For details see the COPYRIGHT file distributed with LuaDist. +# Note: +# Searching headers and libraries is very simple and is NOT as powerful as scripts +# distributed with CMake, because LuaDist defines directories to search for. +# Everyone is encouraged to contact the author with improvements. Maybe this file +# becomes part of CMake distribution sometimes. + +# - Find sqlite3 +# Find the native SQLITE3 headers and libraries. +# +# SQLITE3_INCLUDE_DIRS - where to find sqlite3.h, etc. +# SQLITE3_LIBRARIES - List of libraries when using sqlite. +# SQLITE3_FOUND - True if sqlite found. + +# Look for the header file. +FIND_PATH(SQLITE3_INCLUDE_DIR NAMES sqlite3.h) + +# Look for the library. +FIND_LIBRARY(SQLITE3_LIBRARY NAMES sqlite) + +# Handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if all listed variables are TRUE. +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLITE3 DEFAULT_MSG SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR) + +# Copy the results to the output variables. +IF(SQLITE3_FOUND) + SET(SQLITE3_LIBRARIES ${SQLITE3_LIBRARY}) + SET(SQLITE3_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIR}) +ELSE(SQLITE3_FOUND) + SET(SQLITE3_LIBRARIES) + SET(SQLITE3_INCLUDE_DIRS) +ENDIF(SQLITE3_FOUND) + +MARK_AS_ADVANCED(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES) diff --git a/cmake/Modules/FindToLua.cmake b/cmake/Modules/FindToLua.cmake new file mode 100644 index 000000000..52c721112 --- /dev/null +++ b/cmake/Modules/FindToLua.cmake @@ -0,0 +1,71 @@ +# - Try to find the ToLua library +# Once done this will define +# +# TOLUA_FOUND - System has ToLua +# TOLUA_INCLUDE_DIR - The ToLua include directory +# TOLUA_LIBRARIES - The libraries needed to use ToLua +# TOLUA_DEFINITIONS - Compiler switches required for using ToLua +# TOLUA_EXECUTABLE - The ToLua command line shell +# TOLUA_VERSION_STRING - the version of ToLua found (since CMake 2.8.8) + +#============================================================================= +# Copyright 2006-2009 Kitware, Inc. +# Copyright 2006 Alexander Neundorf +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# use pkg-config to get the directories and then use these values +# in the find_path() and find_library() calls +find_package(PkgConfig QUIET) +PKG_CHECK_MODULES(PC_TOLUA QUIET ToLua) +set(TOLUA_DEFINITIONS ${PC_TOLUA_CFLAGS_OTHER}) + +find_path(TOLUA_INCLUDE_DIR NAMES tolua.h + HINTS + ${PC_TOLUA_DIR}/include + ${PC_TOLUA_INCLUDEDIR} + ${PC_TOLUA_INCLUDE_DIRS} + ) +find_library(TOLUA_LIBRARY NAMES tolua + HINTS + ${PC_TOLUA_DIR}/lib + ${PC_TOLUA_LIBDIR} + ${PC_TOLUA_LIBRARY_DIRS} + ) +find_program(TOLUA_EXECUTABLE tolua + HINTS + ${PC_TOLUA_DIR}/bin + ${PC_TOLUA_LIBDIR} + ${PC_TOLUA_LIBRARY_DIRS} +) + +SET( TOLUA_LIBRARIES "${TOLUA_LIBRARY}" CACHE STRING "ToLua Libraries") + +if(PC_TOLUA_VERSION) + set(TOLUA_VERSION_STRING ${PC_TOLUA_VERSION}) +elseif(TOLUA_INCLUDE_DIR AND EXISTS "${TOLUA_INCLUDE_DIR}/tolua.h") + file(STRINGS "${TOLUA_INCLUDE_DIR}/tolua.h" tolua_version_str + REGEX "^#define[\t ]+TOLUA_VERSION[\t ]+\".*\"") + + string(REGEX REPLACE "^#define[\t ]+TOLUA_VERSION[\t ]+\"tolua ([^\"]*)\".*" "\\1" + TOLUA_VERSION_STRING "${tolua_version_str}") + unset(tolua_version_str) +endif() + +# handle the QUIETLY and REQUIRED arguments and set TOLUA_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ToLua + REQUIRED_VARS TOLUA_LIBRARY TOLUA_INCLUDE_DIR TOLUA_EXECUTABLE + VERSION_VAR TOLUA_VERSION_STRING) + +mark_as_advanced(TOLUA_INCLUDE_DIR TOLUA_LIBRARIES TOLUA_EXECUTABLE) + diff --git a/s/cmake-init b/s/cmake-init index 1ce7eccd3..f40ff67e8 100755 --- a/s/cmake-init +++ b/s/cmake-init @@ -29,8 +29,7 @@ if [ -d $HOME/usr ]; then fi DEST=$(dirname $ROOT)/server -ARGS=" -DCMAKE_MODULE_PATH=$ROOT/cmake/Modules \ - -DCMAKE_BUILD_TYPE=$BUILD \ +ARGS=" -DCMAKE_BUILD_TYPE=$BUILD \ -DCMAKE_LIBRARY_PATH=$LIBRARY_PATH \ -DCMAKE_INCLUDE_PATH=$INCLUDE_PATH \ -DCMAKE_PREFIX_PATH=$PREFIX_PATH \ From a3cdfef66889dafa04fe1ef64b5a09fcecdde227 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Mar 2017 21:10:30 +0200 Subject: [PATCH 093/218] Fix find_package calls for CMake < 3.0 --- CMakeLists.txt | 8 +- cmake/Modules/FindLua.cmake | 172 ++++++++++++++++++++++++++++++++ cmake/Modules/FindSQLite3.cmake | 88 ++++++++++------ s/cmake-init | 2 +- 4 files changed, 235 insertions(+), 35 deletions(-) create mode 100644 cmake/Modules/FindLua.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 302e9065e..aecdffb3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.6) +cmake_minimum_required(VERSION 2.8) if (WIN32) FILE(TO_CMAKE_PATH "${CMAKE_MODULE_PATH}" CMAKE_MODULE_PATH ) FILE(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH ) @@ -12,8 +12,10 @@ enable_testing() find_package (LibXml2) find_package (SQLite3) find_package (Curses) -find_package (Lua REQUIRED) -find_package (ToLua REQUIRED) +find_package (Lua 5.1 REQUIRED) +if (LUA_FOUND) +find_package (ToLua "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}" EXACT REQUIRED) +endif(LUA_FOUND) add_subdirectory (cJSON) add_subdirectory (storage) diff --git a/cmake/Modules/FindLua.cmake b/cmake/Modules/FindLua.cmake new file mode 100644 index 000000000..898ccbfd6 --- /dev/null +++ b/cmake/Modules/FindLua.cmake @@ -0,0 +1,172 @@ +#.rst: +# FindLua +# ------- +# +# +# +# Locate Lua library This module defines +# +# :: +# +# LUA_FOUND - if false, do not try to link to Lua +# LUA_LIBRARIES - both lua and lualib +# LUA_INCLUDE_DIR - where to find lua.h +# LUA_VERSION_STRING - the version of Lua found +# LUA_VERSION_MAJOR - the major version of Lua +# LUA_VERSION_MINOR - the minor version of Lua +# LUA_VERSION_PATCH - the patch version of Lua +# +# +# +# Note that the expected include convention is +# +# :: +# +# #include "lua.h" +# +# and not +# +# :: +# +# #include +# +# This is because, the lua location is not standardized and may exist in +# locations other than lua/ + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# Copyright 2013 Rolf Eike Beer +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +unset(_lua_include_subdirs) +unset(_lua_library_names) + +# this is a function only to have all the variables inside go away automatically +function(set_lua_version_vars) + set(LUA_VERSIONS5 5.3 5.2 5.1 5.0) + + if (Lua_FIND_VERSION_EXACT) + if (Lua_FIND_VERSION_COUNT GREATER 1) + set(lua_append_versions ${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}) + endif () + elseif (Lua_FIND_VERSION) + # once there is a different major version supported this should become a loop + if (NOT Lua_FIND_VERSION_MAJOR GREATER 5) + if (Lua_FIND_VERSION_COUNT EQUAL 1) + set(lua_append_versions ${LUA_VERSIONS5}) + else () + foreach (subver IN LISTS LUA_VERSIONS5) + if (NOT subver VERSION_LESS ${Lua_FIND_VERSION}) + list(APPEND lua_append_versions ${subver}) + endif () + endforeach () + endif () + endif () + else () + # once there is a different major version supported this should become a loop + set(lua_append_versions ${LUA_VERSIONS5}) + endif () + + foreach (ver IN LISTS lua_append_versions) + string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _ver "${ver}") + list(APPEND _lua_include_subdirs + include/lua${CMAKE_MATCH_1}${CMAKE_MATCH_2} + include/lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2} + include/lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2} + ) + list(APPEND _lua_library_names + lua${CMAKE_MATCH_1}${CMAKE_MATCH_2} + lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2} + lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2} + lua.${CMAKE_MATCH_1}.${CMAKE_MATCH_2} + ) + endforeach () + + set(_lua_include_subdirs "${_lua_include_subdirs}" PARENT_SCOPE) + set(_lua_library_names "${_lua_library_names}" PARENT_SCOPE) +endfunction(set_lua_version_vars) + +set_lua_version_vars() + +find_path(LUA_INCLUDE_DIR lua.h + HINTS + ENV LUA_DIR + PATH_SUFFIXES ${_lua_include_subdirs} include/lua include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) +unset(_lua_include_subdirs) + +find_library(LUA_LIBRARY + NAMES ${_lua_library_names} lua + HINTS + ENV LUA_DIR + PATH_SUFFIXES lib + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw + /opt/local + /opt/csw + /opt +) +unset(_lua_library_names) + +if (LUA_LIBRARY) + # include the math library for Unix + if (UNIX AND NOT APPLE AND NOT BEOS) + find_library(LUA_MATH_LIBRARY m) + set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}") + # For Windows and Mac, don't need to explicitly include the math library + else () + set(LUA_LIBRARIES "${LUA_LIBRARY}") + endif () +endif () + +if (LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") + # At least 5.[012] have different ways to express the version + # so all of them need to be tested. Lua 5.2 defines LUA_VERSION + # and LUA_RELEASE as joined by the C preprocessor, so avoid those. + file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_strings + REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*") + + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};") + if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$") + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};") + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};") + set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}") + else () + string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};") + if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$") + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};") + endif () + string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}") + string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}") + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}") + endif () + + unset(lua_version_strings) +endif() + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if +# all listed variables are TRUE +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua + REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR + VERSION_VAR LUA_VERSION_STRING) + +mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY) diff --git a/cmake/Modules/FindSQLite3.cmake b/cmake/Modules/FindSQLite3.cmake index c3689205d..910b05cea 100644 --- a/cmake/Modules/FindSQLite3.cmake +++ b/cmake/Modules/FindSQLite3.cmake @@ -1,37 +1,63 @@ -# Copyright (C) 2007-2009 LuaDist. -# Created by Peter Kapec -# Redistribution and use of this file is allowed according to the terms of the MIT license. -# For details see the COPYRIGHT file distributed with LuaDist. -# Note: -# Searching headers and libraries is very simple and is NOT as powerful as scripts -# distributed with CMake, because LuaDist defines directories to search for. -# Everyone is encouraged to contact the author with improvements. Maybe this file -# becomes part of CMake distribution sometimes. - -# - Find sqlite3 -# Find the native SQLITE3 headers and libraries. +# - Try to find the SQLite3 library +# Once done this will define # -# SQLITE3_INCLUDE_DIRS - where to find sqlite3.h, etc. -# SQLITE3_LIBRARIES - List of libraries when using sqlite. -# SQLITE3_FOUND - True if sqlite found. +# SQLITE3_FOUND - System has SQLite3 +# SQLITE3_INCLUDE_DIR - The SQLite3 include directory +# SQLITE3_LIBRARIES - The libraries needed to use SQLite3 +# SQLITE3_DEFINITIONS - Compiler switches required for using SQLite3 +# SQLITE3_EXECUTABLE - The SQLite3 command line shell +# SQLITE3_VERSION_STRING - the version of SQLite3 found (since CMake 2.8.8) -# Look for the header file. -FIND_PATH(SQLITE3_INCLUDE_DIR NAMES sqlite3.h) +#============================================================================= +# Copyright 2006-2009 Kitware, Inc. +# Copyright 2006 Alexander Neundorf +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) -# Look for the library. -FIND_LIBRARY(SQLITE3_LIBRARY NAMES sqlite) +# use pkg-config to get the directories and then use these values +# in the find_path() and find_library() calls +find_package(PkgConfig QUIET) +PKG_CHECK_MODULES(PC_SQLITE QUIET sqlite3) +set(SQLITE3_DEFINITIONS ${PC_SQLITE_CFLAGS_OTHER}) -# Handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if all listed variables are TRUE. -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLITE3 DEFAULT_MSG SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR) +find_path(SQLITE3_INCLUDE_DIR NAMES sqlite3.h + HINTS + ${PC_SQLITE_INCLUDEDIR} + ${PC_SQLITE_INCLUDE_DIRS} + ) -# Copy the results to the output variables. -IF(SQLITE3_FOUND) - SET(SQLITE3_LIBRARIES ${SQLITE3_LIBRARY}) - SET(SQLITE3_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIR}) -ELSE(SQLITE3_FOUND) - SET(SQLITE3_LIBRARIES) - SET(SQLITE3_INCLUDE_DIRS) -ENDIF(SQLITE3_FOUND) +find_library(SQLITE3_LIBRARIES NAMES sqlite3 + HINTS + ${PC_SQLITE_LIBDIR} + ${PC_SQLITE_LIBRARY_DIRS} + ) -MARK_AS_ADVANCED(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES) +find_program(SQLITE3_EXECUTABLE sqlite3) + +if(PC_SQLITE_VERSION) + set(SQLITE3_VERSION_STRING ${PC_SQLITE_VERSION}) +elseif(SQLITE3_INCLUDE_DIR AND EXISTS "${SQLITE3_INCLUDE_DIR}/sqlite3.h") + file(STRINGS "${SQLITE3_INCLUDE_DIR}/sqlite3.h" sqlite3_version_str + REGEX "^#define[\t ]+SQLITE_VERSION[\t ]+\".*\"") + + string(REGEX REPLACE "^#define[\t ]+SQLITE_VERSION[\t ]+\"([^\"]*)\".*" "\\1" + SQLITE3_VERSION_STRING "${sqlite3_version_str}") + unset(sqlite3_version_str) +endif() + +# handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLite3 + REQUIRED_VARS SQLITE3_LIBRARIES SQLITE3_INCLUDE_DIR + VERSION_VAR SQLITE3_VERSION_STRING) + +mark_as_advanced(SQLITE3_INCLUDE_DIR SQLITE3_LIBRARIES SQLITE3_EXECUTABLE) diff --git a/s/cmake-init b/s/cmake-init index f40ff67e8..d402f1543 100755 --- a/s/cmake-init +++ b/s/cmake-init @@ -10,6 +10,7 @@ ROOT=$(git rev-parse --show-toplevel) MACHINE=`$CC -dumpmachine` [ -z $MACHINE ] && MACHINE=`uname -m` BIN_DIR="$ROOT/build-$MACHINE-$CC-$BUILD" +rm -rf $BIN_DIR mkdir -p $BIN_DIR rm -f $BUILD ln -sf $BIN_DIR $BUILD @@ -31,7 +32,6 @@ fi DEST=$(dirname $ROOT)/server ARGS=" -DCMAKE_BUILD_TYPE=$BUILD \ -DCMAKE_LIBRARY_PATH=$LIBRARY_PATH \ - -DCMAKE_INCLUDE_PATH=$INCLUDE_PATH \ -DCMAKE_PREFIX_PATH=$PREFIX_PATH \ -DCMAKE_INSTALL_PREFIX=$DEST" From 3b3379ad4bb9c448fb79b503ca117f1ec59f1ae6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Mar 2017 21:30:46 +0200 Subject: [PATCH 094/218] work around bad version matchig in FindToLua.cmake --- CMakeLists.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aecdffb3a..892c5b4f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,10 +12,14 @@ enable_testing() find_package (LibXml2) find_package (SQLite3) find_package (Curses) -find_package (Lua 5.1 REQUIRED) -if (LUA_FOUND) -find_package (ToLua "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}" EXACT REQUIRED) -endif(LUA_FOUND) +find_package (ToLua REQUIRED) +if (TOLUA_FOUND) +if (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.2") +find_package (Lua 5.2 REQUIRED) +elseif (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.1") +find_package (Lua 5.2 REQUIRED) +endif() +endif(TOLUA_FOUND) add_subdirectory (cJSON) add_subdirectory (storage) From c4e15fd5ba267330075246ab4fa742335605b327 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Mar 2017 21:59:56 +0200 Subject: [PATCH 095/218] fix find_package call for Lua --- CMakeLists.txt | 8 ++++---- src/CMakeLists.txt | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 892c5b4f0..02146f1f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ endif(WIN32) project (eressea-server C) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/" ${CMAKE_MODULE_PATH}) enable_testing() find_package (LibXml2) @@ -14,10 +14,10 @@ find_package (SQLite3) find_package (Curses) find_package (ToLua REQUIRED) if (TOLUA_FOUND) -if (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.2") -find_package (Lua 5.2 REQUIRED) -elseif (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.1") +if (${TOLUA_VERSION_STRING} VERSION_GREATER "5.2") find_package (Lua 5.2 REQUIRED) +elseif (${TOLUA_VERSION_STRING} VERSION_GREATER "5.1") +find_package (Lua 5.1 REQUIRED) endif() endif(TOLUA_FOUND) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ebe914dfe..fe4613e7d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -187,10 +187,12 @@ target_link_libraries(eressea ${INIPARSER_LIBRARIES} ) +find_library(C_MATH_LIBRARY m) + add_executable(convert convert.c) target_link_libraries(convert game - ${LUA_MATH_LIBRARY} + ${C_MATH_LIBRARY} ${STORAGE_LIBRARIES} ${CLIBS_LIBRARIES} ${INIPARSER_LIBRARIES} From 75049d3bbc37c6226e8dc10baab0c6138ffd31d3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Mar 2017 22:07:18 +0200 Subject: [PATCH 096/218] unit.has_attrib should not require the attribute to be registered. --- src/CMakeLists.txt | 4 +--- src/bind_unit.c | 8 +++++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fe4613e7d..ebe914dfe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -187,12 +187,10 @@ target_link_libraries(eressea ${INIPARSER_LIBRARIES} ) -find_library(C_MATH_LIBRARY m) - add_executable(convert convert.c) target_link_libraries(convert game - ${C_MATH_LIBRARY} + ${LUA_MATH_LIBRARY} ${STORAGE_LIBRARIES} ${CLIBS_LIBRARIES} ${INIPARSER_LIBRARIES} diff --git a/src/bind_unit.c b/src/bind_unit.c index 8247e13d5..b95f43d4a 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -787,7 +787,13 @@ static int tolua_unit_get_curse(lua_State *L) { static int tolua_unit_has_attrib(lua_State *L) { unit *self = (unit *)tolua_tousertype(L, 1, 0); const char *name = tolua_tostring(L, 2, 0); - attrib * a = self->attribs ? a_find(self->attribs, at_find(name)) : NULL; + attrib * a = self->attribs; + while (a) { + if (strcmp(a->type->name, name) == 0) { + break; + } + a = a->nexttype; + } lua_pushboolean(L, a != NULL); return 1; } From d959fe657caa183753550877e4f5d222eeb996c4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Mar 2017 16:01:10 +0200 Subject: [PATCH 097/218] make --version exit immediately after (short) version info --- src/main.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main.c b/src/main.c index e67982108..eedb25cf1 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,5 @@ /* -Copyright (c) 1998-2015, Enno Rehling +Copyright (c) 1998-2017, Enno Rehling Katja Zedel @@ -165,7 +165,7 @@ static int verbosity_to_flags(int verbosity) { return flags; } -static int parse_args(int argc, char **argv, int *exitcode) +static int parse_args(int argc, char **argv) { int i; int log_stderr = LOG_CPERROR; @@ -178,10 +178,10 @@ static int parse_args(int argc, char **argv, int *exitcode) } else if (argi[1] == '-') { /* long format */ if (strcmp(argi + 2, "version") == 0) { - printf("\n%s PBEM host\n" - "Copyright (C) 1996-2005 C. Schlittchen, K. Zedel, E. Rehling, H. Peters.\n\n" - "Compilation: " __DATE__ " at " __TIME__ "\nVersion: %s\n\n", - game_name(), eressea_version()); + printf("Eressea version %s, " + "Copyright (C) 2017 Enno Rehling et al.\n", + eressea_version()); + return 1; #ifdef USE_CURSES } else if (strcmp(argi + 2, "color") == 0) { @@ -229,7 +229,6 @@ static int parse_args(int argc, char **argv, int *exitcode) usage(argv[0], NULL); return 1; default: - *exitcode = -1; usage(argv[0], argi); return 1; } @@ -300,8 +299,10 @@ int main(int argc, char **argv) dictionary *d = 0; setup_signal_handler(); /* parse arguments again, to override ini file */ - parse_args(argc, argv, &err); - + err = parse_args(argc, argv); + if (err!=0) { + return (err>0) ? 0 : err; + } d = parse_config(inifile); if (!d) { log_error("could not open ini configuration %s\n", inifile); From 2fd03a2489a0fbb8ac986af38cf332158ef1da0d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Mar 2017 16:11:45 +0200 Subject: [PATCH 098/218] fix string comparison for posix shell --- s/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s/build b/s/build index 4ee259573..818cb0268 100755 --- a/s/build +++ b/s/build @@ -33,7 +33,7 @@ fi echo "build eressea" cd $ROOT/$BUILD BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//') -if [ "$BRANCH"=="master" ] ; then +if [ "$BRANCH" = "master" ] ; then VERSION=$(git describe --match 'v*.*.*' --tags | sed 's/^v//') cmake -DERESSEA_VERSION="$VERSION" .. else From 6ded971c0ce32bd9bf77dba61dee8fafeb854d6e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Mar 2017 16:25:56 +0200 Subject: [PATCH 099/218] rename the MSVC module --- CMakeLists.txt | 15 ++++++++++----- cmake/Modules/{FindMSVC.cmake => MSVC.cmake} | 2 -- 2 files changed, 10 insertions(+), 7 deletions(-) rename cmake/Modules/{FindMSVC.cmake => MSVC.cmake} (96%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02146f1f2..cf1908f52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,15 +1,16 @@ cmake_minimum_required(VERSION 2.8) +project (eressea-server C) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/" ${CMAKE_MODULE_PATH}) + if (WIN32) FILE(TO_CMAKE_PATH "${CMAKE_MODULE_PATH}" CMAKE_MODULE_PATH ) FILE(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH ) endif(WIN32) -project (eressea-server C) +if (MSVC) +include(MSVC) +endif (MSVC) -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/" ${CMAKE_MODULE_PATH}) - -enable_testing() -find_package (LibXml2) find_package (SQLite3) find_package (Curses) find_package (ToLua REQUIRED) @@ -21,14 +22,18 @@ find_package (Lua 5.1 REQUIRED) endif() endif(TOLUA_FOUND) +enable_testing() + add_subdirectory (cJSON) add_subdirectory (storage) add_subdirectory (iniparser) add_subdirectory (clibs) add_subdirectory (process) add_subdirectory (src eressea) + install(DIRECTORY res conf DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.xml") install(DIRECTORY res conf DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.json") install(DIRECTORY scripts DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.lua") install(DIRECTORY lunit DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.lua") install(DIRECTORY share DESTINATION ${CMAKE_INSTALL_PREFIX}) + diff --git a/cmake/Modules/FindMSVC.cmake b/cmake/Modules/MSVC.cmake similarity index 96% rename from cmake/Modules/FindMSVC.cmake rename to cmake/Modules/MSVC.cmake index b93fed898..d32822627 100644 --- a/cmake/Modules/FindMSVC.cmake +++ b/cmake/Modules/MSVC.cmake @@ -17,5 +17,3 @@ MACRO (MSVC_SET_WARNING_LEVEL level) ENDIF() ENDIF(MSVC) ENDMACRO (MSVC_SET_WARNING_LEVEL) - -SET(MSVC_FOUND 1) From e8b7015c6c267b8f68801d60280f869628332efe Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Mar 2017 21:57:14 +0200 Subject: [PATCH 100/218] it seems CMAKE_INCLUDE_PATH is unused --- s/cmake-init | 1 + 1 file changed, 1 insertion(+) diff --git a/s/cmake-init b/s/cmake-init index d402f1543..9d529a433 100755 --- a/s/cmake-init +++ b/s/cmake-init @@ -34,6 +34,7 @@ ARGS=" -DCMAKE_BUILD_TYPE=$BUILD \ -DCMAKE_LIBRARY_PATH=$LIBRARY_PATH \ -DCMAKE_PREFIX_PATH=$PREFIX_PATH \ -DCMAKE_INSTALL_PREFIX=$DEST" +# -DCMAKE_INCLUDE_PATH=$INCLUDE_PATH git submodule update --init From 16910f8efd1595e25c5ff06046140f1b35ada632 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Mar 2017 16:41:59 +0200 Subject: [PATCH 101/218] accidentally deleted the LibXml2 find_package call, oops. --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index cf1908f52..d9ac81e80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ endif (MSVC) find_package (SQLite3) find_package (Curses) +find_package (LibXml2) find_package (ToLua REQUIRED) if (TOLUA_FOUND) if (${TOLUA_VERSION_STRING} VERSION_GREATER "5.2") From 5db3bb0baac9fd9550b2ccff7b8276b6aeb4c488 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Mar 2017 16:55:18 +0200 Subject: [PATCH 102/218] CMake changes in submodules --- cJSON | 2 +- iniparser | 2 +- storage | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cJSON b/cJSON index 43c04ad61..22a4fc9be 160000 --- a/cJSON +++ b/cJSON @@ -1 +1 @@ -Subproject commit 43c04ad61258ec3d54a2167eb3a43915bd003ab1 +Subproject commit 22a4fc9be31f0426e622f5bc9ebd7a1550845001 diff --git a/iniparser b/iniparser index ecf956b98..cf9951f35 160000 --- a/iniparser +++ b/iniparser @@ -1 +1 @@ -Subproject commit ecf956b9808c28c2db52e6b73930f57876dbb258 +Subproject commit cf9951f35f39fcc7240b518c9aa4c39617fa0e22 diff --git a/storage b/storage index 2117191d4..046699fe4 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit 2117191d4ad75e1eb14809878bc71d15b20a5d86 +Subproject commit 046699fe405b487a2812900b5a04c77438b3a58c From 693a6d9ce7dbe66a8d1a2fef38ce48a726876219 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Mar 2017 20:26:28 +0200 Subject: [PATCH 103/218] update submodules to a version that passes CI. --- iniparser | 2 +- storage | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iniparser b/iniparser index cf9951f35..62f6c0abc 160000 --- a/iniparser +++ b/iniparser @@ -1 +1 @@ -Subproject commit cf9951f35f39fcc7240b518c9aa4c39617fa0e22 +Subproject commit 62f6c0abc554fd6fcc0170068dfd3ccb645150d9 diff --git a/storage b/storage index 046699fe4..d807ef5ce 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit 046699fe405b487a2812900b5a04c77438b3a58c +Subproject commit d807ef5ce64b3425b31fb440e0b93a4d233f517a From a6518d87d1e581f0f367eec358ae6894a552092d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 28 Mar 2017 20:35:22 +0200 Subject: [PATCH 104/218] very latest iniparser --- iniparser | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iniparser b/iniparser index 62f6c0abc..540abd0ad 160000 --- a/iniparser +++ b/iniparser @@ -1 +1 @@ -Subproject commit 62f6c0abc554fd6fcc0170068dfd3ccb645150d9 +Subproject commit 540abd0adef2e173b2433a4d8b6c49af7ca675ad From 8d2687ab902d9d1a96346c873d832790ff9588c1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 29 Mar 2017 04:30:54 +0200 Subject: [PATCH 105/218] print version number at end of tests. --- s/runtests | 1 + tests/runtests.bat | 1 + 2 files changed, 2 insertions(+) diff --git a/s/runtests b/s/runtests index e42640de1..14b5a658b 100755 --- a/s/runtests +++ b/s/runtests @@ -15,6 +15,7 @@ cd $ROOT $ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests.lua $ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests-e2.lua $ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests-e3.lua +$ROOT/$BUILD/eressea/eressea --version rm -rf data reports orders.txt score score.alliances datum turn cd $OLDWPD diff --git a/tests/runtests.bat b/tests/runtests.bat index 41b5f8056..b6f70768f 100644 --- a/tests/runtests.bat +++ b/tests/runtests.bat @@ -8,6 +8,7 @@ SET SERVER=%BUILD%\eressea.exe %SERVER% ..\scripts\run-tests.lua %SERVER% -re2 ..\scripts\run-tests-e2.lua %SERVER% -re3 ..\scripts\run-tests-e3.lua +%SERVER% --version PAUSE RMDIR /s /q reports DEL score score.alliances datum turn From 29c2e0b8f49d96489b53b3437bf5dc9df5feb75b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 29 Mar 2017 17:59:39 +0200 Subject: [PATCH 106/218] additional testing for race-related production rules. --- scripts/tests/e2/init.lua | 1 + scripts/tests/e2/production.lua | 229 ++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 scripts/tests/e2/production.lua diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index 991014287..9a42c971a 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -1,3 +1,4 @@ +require 'tests.e2.production' require 'tests.e2.adamantium' require 'tests.e2.undead' require 'tests.e2.shiplanding' diff --git a/scripts/tests/e2/production.lua b/scripts/tests/e2/production.lua new file mode 100644 index 000000000..f120e6916 --- /dev/null +++ b/scripts/tests/e2/production.lua @@ -0,0 +1,229 @@ +require "lunit" + +module("tests.e2.production", package.seeall, lunit.testcase ) + +function setup() + eressea.game.reset() + eressea.settings.set("rules.food.flags", "4") -- food is free + eressea.settings.set("NewbieImmunity", "0") +end + +local function create_faction(race) + return faction.create(race .. '@eressea.de', race, "de") +end + +function test_laen_needs_mine() + -- some resources require a building + -- i.e. you cannot create laen without a mine + local r = region.create(0, 0, "mountain") + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + r:set_resource('laen', 100) + u:add_order("MACHE Laen") + u:set_skill('mining', 7) + turn_process() + assert_equal(0, u:get_item('laen')) + assert_equal(100, r:get_resource('laen')) + assert_equal(1, f:count_msg_type("error104")) -- requires building + + u.building = building.create(u.region, "mine") + u.building.working = true + u.building.size = 10 + turn_process() + assert_equal(1, u:get_item('laen')) + assert_equal(99, r:get_resource('laen')) + + turn_end() +end + +function test_mine_laen_bonus() + -- some buildings grant a bonus on the production skill + -- i.e. a mine adds +1 to mining + local r = region.create(0, 0, 'mountain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + r:set_resource('laen', 100) + assert_equal(100, r:get_resource('laen')) + u:add_order("MACHE Laen") + u:set_skill('mining', 6) + u.building = building.create(u.region, "mine") + u.building.working = true + u.building.size = 10 + u.number = 2 + turn_process() -- T6 is not enough for laen + assert_equal(0, u:get_item('laen')) + assert_equal(100, r:get_resource('laen')) + assert_equal(1, f:count_msg_type("manufacture_skills")) + + u:set_skill('mining', 13) + turn_process() -- T13 is enough, the +1 produces one extra Laen + assert_equal(4, u:get_item('laen')) -- FAIL (3) + assert_equal(96, r:get_resource('laen')) + + turn_end() +end + +function test_mine_iron_bonus() + -- some buildings grant a bonus on the production skill + -- i.e. a mine adds +1 to mining iron + -- + local r = region.create(0, 0, 'mountain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + r:set_resource('iron', 100) + assert_equal(100, r:get_resource('iron')) + u:add_order("MACHE Eisen") + u:set_skill('mining', 1) + u.building = building.create(u.region, "mine") + u.building.working = false + u.building.size = 10 + u.number = 2 + turn_process() -- iron can be made without a working mine + assert_equal(2, u:get_item('iron')) + assert_equal(98, r:get_resource('iron')) + + u.building.working = true + turn_process() + assert_equal(6, u:get_item('iron')) + assert_equal(96, r:get_resource('iron')) + + turn_end() +end + +function test_quarry_bonus() + -- a quarry grants +1 to quarrying, and saves 50% stone + -- + local r = region.create(0, 0, 'mountain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + r:set_resource('stone', 100) + assert_equal(100, r:get_resource('stone')) + u:add_order("MACHE Stein") + u:set_skill('quarrying', 1) + u.number = 2 + u.building = building.create(u.region, 'quarry') + u.building.working = false + u.building.size = 10 + turn_process() + assert_equal(2, u:get_item('stone')) + assert_equal(98, r:get_resource('stone')) + + u.building.working = true + turn_process() + assert_equal(6, u:get_item('stone')) + assert_equal(96, r:get_resource('stone')) + + turn_end() +end + +function test_smithy_bonus_iron() +-- a smithy adds +1 to weaponsmithing, and saves 50% iron + local r = region.create(0, 0, 'mountain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + u.building = building.create(u.region, 'smithy') + u.building.working = false + u.building.size = 10 + u:set_skill('weaponsmithing', 5) -- needs 3 + u:add_item('iron', 100) + u:add_order("MACHE Schwert") + turn_process() -- building disabled + assert_equal(1, u:get_item('sword')) + assert_equal(99, u:get_item('iron')) + + u.building.working = true + turn_process() -- building active + assert_equal(3, u:get_item('sword')) + assert_equal(98, u:get_item('iron')) + + turn_end() +end + +function test_smithy_bonus_mixed() +-- a smithy adds +1 to weaponsmithing, and saves 50% iron +-- it does not save any other resource, though. + local r = region.create(0, 0, 'mountain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + u.building = building.create(u.region, 'smithy') + u.building.working = false + u.building.size = 10 + u:set_skill('weaponsmithing', 5) -- needs 3 + u:add_item('iron', 100) + u:add_item('log', 100) + u:add_order("MACHE Kriegsaxt") + turn_process() -- building disabled + assert_equal(1, u:get_item('axe')) + assert_equal(99, u:get_item('iron')) + assert_equal(99, u:get_item('log')) + + u.building.working = true + turn_process() -- building active + assert_equal(3, u:get_item('axe')) + assert_equal(98, u:get_item('iron')) + assert_equal(97, u:get_item('log')) + + turn_end() +end + +function test_greatbow_needs_elf() +-- only elves can build a greatbow + local r = region.create(0, 0, 'mountain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + u:set_skill('weaponsmithing', 5) + u:add_item('mallorn', 2) + u:add_order("MACHE Elfenbogen") + turn_process() -- humans cannot do it + assert_equal(1, f:count_msg_type("error_cannotmake")) + assert_equal(0, u:get_item('greatbow')) + assert_equal(2, u:get_item('mallorn')) + + u.race = 'elf' + turn_process() -- but elves can + assert_equal(1, u:get_item('greatbow')) + assert_equal(0, u:get_item('mallorn')) +end + +function test_troll_quarrying_bonus() +-- Von Trollen abgebaute Steine werden nur zu 75% vom "Regionsvorrat" abgezogen. +-- Dieser Effekt ist kumulativ zu einem Steinbruch. + local r = region.create(0, 0, 'mountain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + r:set_resource("stone", 100) + u:set_skill('quarrying', 4) + u:add_order("MACHE Steine") + turn_process() -- humans get no bonus + write_report(f) + assert_equal(4, u:get_item('stone')) + assert_equal(96, r:get_resource('stone')) + + u.race = 'troll' + u:set_skill('quarrying', 2) + turn_process() -- trolls have +2 to quarrying, and save 25% + assert_equal(8, u:get_item('stone')) + assert_equal(93, r:get_resource('stone')) +end + +function test_dwarf_mining_bonus() +-- Von Zwergen abgebautes Eisen wird nur zu 60% vom "Regionsvorrat" abgezogen. +-- Dieser Effekt ist kumulativ zu einem Bergwerk (siehe hier und hier). + +end From 570a25f6dd13198e4eb5080800d13865b36b502f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 30 Mar 2017 19:08:33 +0200 Subject: [PATCH 107/218] split production rules by games --- scripts/tests/e2/init.lua | 1 + scripts/tests/e2/production.lua | 166 -------------------------- scripts/tests/e3/init.lua | 2 +- scripts/tests/{e3 => }/production.lua | 2 +- 4 files changed, 3 insertions(+), 168 deletions(-) rename scripts/tests/{e3 => }/production.lua (98%) diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index 9a42c971a..c75b05211 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -16,3 +16,4 @@ require 'tests.storage' require 'tests.magicbag' require 'tests.process' require 'tests.xmas' +require 'tests.production' diff --git a/scripts/tests/e2/production.lua b/scripts/tests/e2/production.lua index f120e6916..c6d074f50 100644 --- a/scripts/tests/e2/production.lua +++ b/scripts/tests/e2/production.lua @@ -12,172 +12,6 @@ local function create_faction(race) return faction.create(race .. '@eressea.de', race, "de") end -function test_laen_needs_mine() - -- some resources require a building - -- i.e. you cannot create laen without a mine - local r = region.create(0, 0, "mountain") - local f = create_faction('human') - local u = unit.create(f, r, 1) - - turn_begin() - r:set_resource('laen', 100) - u:add_order("MACHE Laen") - u:set_skill('mining', 7) - turn_process() - assert_equal(0, u:get_item('laen')) - assert_equal(100, r:get_resource('laen')) - assert_equal(1, f:count_msg_type("error104")) -- requires building - - u.building = building.create(u.region, "mine") - u.building.working = true - u.building.size = 10 - turn_process() - assert_equal(1, u:get_item('laen')) - assert_equal(99, r:get_resource('laen')) - - turn_end() -end - -function test_mine_laen_bonus() - -- some buildings grant a bonus on the production skill - -- i.e. a mine adds +1 to mining - local r = region.create(0, 0, 'mountain') - local f = create_faction('human') - local u = unit.create(f, r, 1) - - turn_begin() - r:set_resource('laen', 100) - assert_equal(100, r:get_resource('laen')) - u:add_order("MACHE Laen") - u:set_skill('mining', 6) - u.building = building.create(u.region, "mine") - u.building.working = true - u.building.size = 10 - u.number = 2 - turn_process() -- T6 is not enough for laen - assert_equal(0, u:get_item('laen')) - assert_equal(100, r:get_resource('laen')) - assert_equal(1, f:count_msg_type("manufacture_skills")) - - u:set_skill('mining', 13) - turn_process() -- T13 is enough, the +1 produces one extra Laen - assert_equal(4, u:get_item('laen')) -- FAIL (3) - assert_equal(96, r:get_resource('laen')) - - turn_end() -end - -function test_mine_iron_bonus() - -- some buildings grant a bonus on the production skill - -- i.e. a mine adds +1 to mining iron - -- - local r = region.create(0, 0, 'mountain') - local f = create_faction('human') - local u = unit.create(f, r, 1) - - turn_begin() - r:set_resource('iron', 100) - assert_equal(100, r:get_resource('iron')) - u:add_order("MACHE Eisen") - u:set_skill('mining', 1) - u.building = building.create(u.region, "mine") - u.building.working = false - u.building.size = 10 - u.number = 2 - turn_process() -- iron can be made without a working mine - assert_equal(2, u:get_item('iron')) - assert_equal(98, r:get_resource('iron')) - - u.building.working = true - turn_process() - assert_equal(6, u:get_item('iron')) - assert_equal(96, r:get_resource('iron')) - - turn_end() -end - -function test_quarry_bonus() - -- a quarry grants +1 to quarrying, and saves 50% stone - -- - local r = region.create(0, 0, 'mountain') - local f = create_faction('human') - local u = unit.create(f, r, 1) - - turn_begin() - r:set_resource('stone', 100) - assert_equal(100, r:get_resource('stone')) - u:add_order("MACHE Stein") - u:set_skill('quarrying', 1) - u.number = 2 - u.building = building.create(u.region, 'quarry') - u.building.working = false - u.building.size = 10 - turn_process() - assert_equal(2, u:get_item('stone')) - assert_equal(98, r:get_resource('stone')) - - u.building.working = true - turn_process() - assert_equal(6, u:get_item('stone')) - assert_equal(96, r:get_resource('stone')) - - turn_end() -end - -function test_smithy_bonus_iron() --- a smithy adds +1 to weaponsmithing, and saves 50% iron - local r = region.create(0, 0, 'mountain') - local f = create_faction('human') - local u = unit.create(f, r, 1) - - turn_begin() - u.building = building.create(u.region, 'smithy') - u.building.working = false - u.building.size = 10 - u:set_skill('weaponsmithing', 5) -- needs 3 - u:add_item('iron', 100) - u:add_order("MACHE Schwert") - turn_process() -- building disabled - assert_equal(1, u:get_item('sword')) - assert_equal(99, u:get_item('iron')) - - u.building.working = true - turn_process() -- building active - assert_equal(3, u:get_item('sword')) - assert_equal(98, u:get_item('iron')) - - turn_end() -end - -function test_smithy_bonus_mixed() --- a smithy adds +1 to weaponsmithing, and saves 50% iron --- it does not save any other resource, though. - local r = region.create(0, 0, 'mountain') - local f = create_faction('human') - local u = unit.create(f, r, 1) - - turn_begin() - u.building = building.create(u.region, 'smithy') - u.building.working = false - u.building.size = 10 - u:set_skill('weaponsmithing', 5) -- needs 3 - u:add_item('iron', 100) - u:add_item('log', 100) - u:add_order("MACHE Kriegsaxt") - turn_process() -- building disabled - assert_equal(1, u:get_item('axe')) - assert_equal(99, u:get_item('iron')) - assert_equal(99, u:get_item('log')) - - u.building.working = true - turn_process() -- building active - assert_equal(3, u:get_item('axe')) - assert_equal(98, u:get_item('iron')) - assert_equal(97, u:get_item('log')) - - turn_end() -end - function test_greatbow_needs_elf() -- only elves can build a greatbow local r = region.create(0, 0, 'mountain') diff --git a/scripts/tests/e3/init.lua b/scripts/tests/e3/init.lua index aa253157e..174452897 100644 --- a/scripts/tests/e3/init.lua +++ b/scripts/tests/e3/init.lua @@ -1,4 +1,3 @@ -require 'tests.e3.production' require 'tests.e3.castles' require 'tests.e3.stealth' require 'tests.e3.spells' @@ -11,3 +10,4 @@ require 'tests.common' -- require 'tests.report' require 'tests.magicbag' require 'tests.process' +require 'tests.production' diff --git a/scripts/tests/e3/production.lua b/scripts/tests/production.lua similarity index 98% rename from scripts/tests/e3/production.lua rename to scripts/tests/production.lua index 85fdeb638..5a1fcfc51 100644 --- a/scripts/tests/e3/production.lua +++ b/scripts/tests/production.lua @@ -1,6 +1,6 @@ require "lunit" -module("tests.e3.production", package.seeall, lunit.testcase ) +module("tests.production", package.seeall, lunit.testcase ) function setup() eressea.game.reset() From 818753079468306ebd7b1a03d6c38c879086a94a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 30 Mar 2017 19:15:49 +0200 Subject: [PATCH 108/218] disable a test that currently is not passing --- scripts/tests/e2/production.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/tests/e2/production.lua b/scripts/tests/e2/production.lua index c6d074f50..e166565a9 100644 --- a/scripts/tests/e2/production.lua +++ b/scripts/tests/e2/production.lua @@ -9,10 +9,10 @@ function setup() end local function create_faction(race) - return faction.create(race .. '@eressea.de', race, "de") + return faction.create(race, race .. '@example.com', "de") end -function test_greatbow_needs_elf() +function disable_test_greatbow_needs_elf() -- only elves can build a greatbow local r = region.create(0, 0, 'mountain') local f = create_faction('human') From 5479d9420627da811ff77002f50ba2d5479daa81 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 30 Mar 2017 20:40:03 +0200 Subject: [PATCH 109/218] develop branch gives different error message for greatbow. --- scripts/tests/e2/production.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/tests/e2/production.lua b/scripts/tests/e2/production.lua index e166565a9..96aa7529c 100644 --- a/scripts/tests/e2/production.lua +++ b/scripts/tests/e2/production.lua @@ -12,7 +12,7 @@ local function create_faction(race) return faction.create(race, race .. '@example.com', "de") end -function disable_test_greatbow_needs_elf() +function test_greatbow_needs_elf() -- only elves can build a greatbow local r = region.create(0, 0, 'mountain') local f = create_faction('human') @@ -23,7 +23,7 @@ function disable_test_greatbow_needs_elf() u:add_item('mallorn', 2) u:add_order("MACHE Elfenbogen") turn_process() -- humans cannot do it - assert_equal(1, f:count_msg_type("error_cannotmake")) + assert_equal(1, f:count_msg_type("error118")) assert_equal(0, u:get_item('greatbow')) assert_equal(2, u:get_item('mallorn')) From e50d5a812e4120c478bb56f5495e7359cd8a0733 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 30 Mar 2017 20:41:17 +0200 Subject: [PATCH 110/218] remove unused error message. --- res/core/messages.xml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/res/core/messages.xml b/res/core/messages.xml index 42b95bc4c..eb4b2a03a 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -5539,15 +5539,6 @@ "$unit($unit) in $region($region): '$order($command)' - Nur Elfen können diese Bögen herstellen." "$unit($unit) in $region($region): '$order($command)' - Only elves can make these bows." - - - - - - - "$unit($unit) in $region($region): '$order($command)' - Nur die EMail-Adresse angeben!" - "$unit($unit) in $region($region): '$order($command)' - Please provide only an email address!" - From 4115b321b3a305aef432434875ddab00e5e4da65 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 30 Mar 2017 21:00:35 +0200 Subject: [PATCH 111/218] add tests for additional (race-related) production rules. --- res/core/messages.xml | 4 +- scripts/tests/e2/production.lua | 17 ++++ scripts/tests/e3/init.lua | 1 + scripts/tests/e3/production.lua | 139 ++++++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 scripts/tests/e3/production.lua diff --git a/res/core/messages.xml b/res/core/messages.xml index eb4b2a03a..a12252d96 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -5536,8 +5536,8 @@ - "$unit($unit) in $region($region): '$order($command)' - Nur Elfen können diese Bögen herstellen." - "$unit($unit) in $region($region): '$order($command)' - Only elves can make these bows." + "$unit($unit) in $region($region): '$order($command)' - Diesen Gegenstand kann die Einheit nicht herstellen." + "$unit($unit) in $region($region): '$order($command)' - This unit cannot produce that." diff --git a/scripts/tests/e2/production.lua b/scripts/tests/e2/production.lua index 96aa7529c..52e035374 100644 --- a/scripts/tests/e2/production.lua +++ b/scripts/tests/e2/production.lua @@ -59,5 +59,22 @@ end function test_dwarf_mining_bonus() -- Von Zwergen abgebautes Eisen wird nur zu 60% vom "Regionsvorrat" abgezogen. -- Dieser Effekt ist kumulativ zu einem Bergwerk (siehe hier und hier). + local r = region.create(0, 0, 'mountain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + turn_begin() + r:set_resource('iron', 100) + u:set_skill('mining', 10) + u:add_order('MACHE Eisen') + turn_process() -- humans get no bonus + write_report(f) + assert_equal(10, u:get_item('iron')) + assert_equal(90, r:get_resource('iron')) + + u.race = 'dwarf' + u:set_skill('mining', 8) + turn_process() -- dwarves have +2 to mining, and save 40% + assert_equal(20, u:get_item('iron')) + assert_equal(84, r:get_resource('iron')) end diff --git a/scripts/tests/e3/init.lua b/scripts/tests/e3/init.lua index 389e9db90..6094d0a25 100644 --- a/scripts/tests/e3/init.lua +++ b/scripts/tests/e3/init.lua @@ -11,4 +11,5 @@ require 'tests.common' require 'tests.items' require 'tests.magicbag' require 'tests.process' +require 'tests.e3.production' require 'tests.production' diff --git a/scripts/tests/e3/production.lua b/scripts/tests/e3/production.lua new file mode 100644 index 000000000..d1ea18f72 --- /dev/null +++ b/scripts/tests/e3/production.lua @@ -0,0 +1,139 @@ +require "lunit" + +module("tests.e3.production", package.seeall, lunit.testcase ) + +function setup() + eressea.game.reset() + eressea.settings.set("rules.food.flags", "4") -- food is free + eressea.settings.set("NewbieImmunity", "0") +end + +local function create_faction(race) + return faction.create(race, race .. '@example.com', "de") +end + +function test_greatbow_needs_elf() +-- only elves can build a greatbow + local r = region.create(0, 0, 'mountain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + u:set_skill('weaponsmithing', 5) + u:add_item('mallorn', 2) + u:add_order("MACHE Elfenbogen") + turn_process() -- humans cannot do it + assert_equal(1, f:count_msg_type("error118")) + assert_equal(0, u:get_item('greatbow')) + assert_equal(2, u:get_item('mallorn')) + + u.race = 'elf' + turn_process() -- but elves can + assert_equal(1, u:get_item('greatbow')) + assert_equal(0, u:get_item('mallorn')) +end + +function test_troll_no_quarrying_bonus() +-- Trolle kriegen keinen Rohstoffbonus wie in E2 + local r = region.create(0, 0, 'mountain') + local f = create_faction('troll') + local u = unit.create(f, r, 1) + + turn_begin() + r:set_resource("stone", 100) + u:set_skill('quarrying', 2) -- +2 Rassenbonus + u:add_order("MACHE Steine") + turn_process() + write_report(f) + assert_equal(4, u:get_item('stone')) + assert_equal(96, r:get_resource('stone')) +end + +function test_dwarf_no_mining_bonus() +-- E3: Zwerge verlieren den Eisenabbaubonus + local r = region.create(0, 0, 'mountain') + local f = create_faction('dwarf') + local u = unit.create(f, r, 1) + + turn_begin() + r:set_resource('iron', 100) + u:set_skill('mining', 8) -- +2 skill bonus + u:add_order('MACHE Eisen') + turn_process() + write_report(f) + assert_equal(10, u:get_item('iron')) + assert_equal(90, r:get_resource('iron')) +end + +function test_dwarf_towershield() +-- Zwerge können als einzige Rasse Turmschilde, Schuppenpanzer +-- und Repetierarmbrüste bauen. + local r = region.create(0, 0, 'plain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + u:set_skill('armorer', 4) + u:add_item('iron', 1) + u:add_order("MACHE Turmschild") + turn_process() -- humans cannot do it + assert_equal(1, f:count_msg_type("error118")) + assert_equal(0, u:get_item('towershield')) + assert_equal(1, u:get_item('iron')) + + u.race = 'dwarf' + u:set_skill('armorer', 2) -- dwarf has bonus +2 + turn_process() -- but dwarves can + assert_equal(1, u:get_item('towershield')) + assert_equal(0, u:get_item('iron')) + +end + +function test_dwarf_scale() +-- Zwerge können als einzige Rasse Turmschilde, Schuppenpanzer +-- und Repetierarmbrüste bauen. + local r = region.create(0, 0, 'plain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + u:set_skill('armorer', 5) + u:add_item('iron', 2) + u:add_order("MACHE Schuppenpanzer") + turn_process() -- humans cannot do it + assert_equal(1, f:count_msg_type("error118")) + assert_equal(0, u:get_item('scale')) + assert_equal(2, u:get_item('iron')) + + u.race = 'dwarf' + u:set_skill('armorer', 3) -- dwarf has bonus +2 + turn_process() -- but dwarves can + assert_equal(1, u:get_item('scale')) + assert_equal(0, u:get_item('iron')) +end + +function test_dwarf_rep_xbow() +-- Zwerge können als einzige Rasse Turmschilde, Schuppenpanzer +-- und Repetierarmbrüste bauen. + local r = region.create(0, 0, 'plain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + u:set_skill('weaponsmithing', 5) + u:add_item('iron', 1) + u:add_item('log', 1) + u:add_order("MACHE Repetierarmbrust") + turn_process() -- humans cannot do it + assert_equal(1, f:count_msg_type("error118")) + assert_equal(0, u:get_item('rep_crossbow')) + assert_equal(1, u:get_item('iron')) + assert_equal(1, u:get_item('log')) + + u.race = 'dwarf' + u:set_skill('weaponsmithing', 3) -- dwarf has bonus +2 + turn_process() -- but dwarves can + assert_equal(1, u:get_item('rep_crossbow')) + assert_equal(0, u:get_item('iron')) + assert_equal(0, u:get_item('log')) +end From c49786d713fcb4338b7194272da660cb212270ca Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 30 Mar 2017 23:13:55 +0200 Subject: [PATCH 112/218] fix some memory leaks --- cJSON | 2 +- iniparser | 2 +- src/reports.test.c | 9 ++++++++- src/study.c | 2 ++ src/util/attrib.test.c | 1 + storage | 2 +- 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/cJSON b/cJSON index 22a4fc9be..43c04ad61 160000 --- a/cJSON +++ b/cJSON @@ -1 +1 @@ -Subproject commit 22a4fc9be31f0426e622f5bc9ebd7a1550845001 +Subproject commit 43c04ad61258ec3d54a2167eb3a43915bd003ab1 diff --git a/iniparser b/iniparser index 540abd0ad..ecf956b98 160000 --- a/iniparser +++ b/iniparser @@ -1 +1 @@ -Subproject commit 540abd0adef2e173b2433a4d8b6c49af7ca675ad +Subproject commit ecf956b9808c28c2db52e6b73930f57876dbb258 diff --git a/src/reports.test.c b/src/reports.test.c index fb3bd9c95..9d7944258 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -323,6 +323,7 @@ static void test_newbie_password_message(CuTest *tc) { prepare_report(&ctx, f); CuAssertIntEquals(tc, FFL_PWMSG, f->flags&FFL_PWMSG); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "changepasswd")); + finish_reports(&ctx); test_cleanup(); } @@ -359,6 +360,7 @@ static void test_prepare_travelthru(CuTest *tc) { CuAssertPtrEquals(tc, f2, ctx.f); CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, NULL, ctx.last); + finish_reports(&ctx); test_cleanup(); } @@ -384,6 +386,7 @@ static void test_get_addresses(CuTest *tc) { CuAssertTrue(tc, selist_contains(ctx.addresses, f1, NULL)); CuAssertTrue(tc, selist_contains(ctx.addresses, f2, NULL)); CuAssertIntEquals(tc, 3, selist_length(ctx.addresses)); + finish_reports(&ctx); test_cleanup(); } @@ -411,6 +414,7 @@ static void test_get_addresses_fstealth(CuTest *tc) { CuAssertTrue(tc, !selist_contains(ctx.addresses, f1, NULL)); CuAssertTrue(tc, selist_contains(ctx.addresses, f2, NULL)); CuAssertIntEquals(tc, 2, selist_length(ctx.addresses)); + finish_reports(&ctx); test_cleanup(); } @@ -441,6 +445,7 @@ static void test_get_addresses_travelthru(CuTest *tc) { CuAssertTrue(tc, !selist_contains(ctx.addresses, f1, NULL)); CuAssertTrue(tc, selist_contains(ctx.addresses, f2, NULL)); CuAssertIntEquals(tc, 2, selist_length(ctx.addresses)); + finish_reports(&ctx); test_cleanup(); } @@ -523,6 +528,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); + finish_reports(&ctx); test_cleanup(); } @@ -560,6 +566,7 @@ static void test_prepare_lighthouse_owners(CuTest *tc) { CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_lighthouse, r2->seen.mode); CuAssertIntEquals(tc, seen_neighbour, r3->seen.mode); + finish_reports(&ctx); test_cleanup(); } @@ -585,7 +592,6 @@ static void test_prepare_report(CuTest *tc) { CuAssertIntEquals(tc, seen_unit, r->seen.mode); finish_reports(&ctx); CuAssertIntEquals(tc, seen_none, r->seen.mode); - finish_reports(&ctx); r = test_create_region(2, 0, 0); CuAssertPtrEquals(tc, r, regions->next); @@ -593,6 +599,7 @@ static void test_prepare_report(CuTest *tc) { CuAssertPtrEquals(tc, regions, ctx.first); CuAssertPtrEquals(tc, r, ctx.last); CuAssertIntEquals(tc, seen_none, r->seen.mode); + finish_reports(&ctx); test_cleanup(); } diff --git a/src/study.c b/src/study.c index 27443e996..9ea0a860e 100644 --- a/src/study.c +++ b/src/study.c @@ -163,6 +163,8 @@ static void init_learning(struct attrib *a) static void done_learning(struct attrib *a) { + teaching_info *teach = (teaching_info *)a->data.v; + selist_free(teach->teachers); free(a->data.v); } diff --git a/src/util/attrib.test.c b/src/util/attrib.test.c index b44afeec2..c59b8ae24 100644 --- a/src/util/attrib.test.c +++ b/src/util/attrib.test.c @@ -127,6 +127,7 @@ static void test_attrib_rwstring(CuTest *tc) { data.strm.api->rewind(data.strm.handle); a_readstring(&a, NULL, &data); CuAssertStrEquals(tc, "Hello World", (const char *)a.data.v); + a_finalizestring(&a); mstream_done(&data.strm); gamedata_done(&data); test_cleanup(); diff --git a/storage b/storage index d807ef5ce..2117191d4 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit d807ef5ce64b3425b31fb440e0b93a4d233f517a +Subproject commit 2117191d4ad75e1eb14809878bc71d15b20a5d86 From 37f3c02cebb92e7fb63a36188abf510a6912c9ab Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 30 Mar 2017 23:18:50 +0200 Subject: [PATCH 113/218] do not write reports in tests. --- scripts/tests/e2/production.lua | 2 -- scripts/tests/e3/production.lua | 2 -- 2 files changed, 4 deletions(-) diff --git a/scripts/tests/e2/production.lua b/scripts/tests/e2/production.lua index 52e035374..7442d97ac 100644 --- a/scripts/tests/e2/production.lua +++ b/scripts/tests/e2/production.lua @@ -45,7 +45,6 @@ function test_troll_quarrying_bonus() u:set_skill('quarrying', 4) u:add_order("MACHE Steine") turn_process() -- humans get no bonus - write_report(f) assert_equal(4, u:get_item('stone')) assert_equal(96, r:get_resource('stone')) @@ -68,7 +67,6 @@ function test_dwarf_mining_bonus() u:set_skill('mining', 10) u:add_order('MACHE Eisen') turn_process() -- humans get no bonus - write_report(f) assert_equal(10, u:get_item('iron')) assert_equal(90, r:get_resource('iron')) diff --git a/scripts/tests/e3/production.lua b/scripts/tests/e3/production.lua index d1ea18f72..eac296e6a 100644 --- a/scripts/tests/e3/production.lua +++ b/scripts/tests/e3/production.lua @@ -44,7 +44,6 @@ function test_troll_no_quarrying_bonus() u:set_skill('quarrying', 2) -- +2 Rassenbonus u:add_order("MACHE Steine") turn_process() - write_report(f) assert_equal(4, u:get_item('stone')) assert_equal(96, r:get_resource('stone')) end @@ -60,7 +59,6 @@ function test_dwarf_no_mining_bonus() u:set_skill('mining', 8) -- +2 skill bonus u:add_order('MACHE Eisen') turn_process() - write_report(f) assert_equal(10, u:get_item('iron')) assert_equal(90, r:get_resource('iron')) end From 57ae21a823d1cff4a1d8c18bc377b115eaa50754 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Mar 2017 21:26:07 +0200 Subject: [PATCH 114/218] remove an obsolete always-true constant --- src/economy.c | 2 -- src/settings.h | 1 - 2 files changed, 3 deletions(-) diff --git a/src/economy.c b/src/economy.c index e3a6dc18d..83e4bf9d0 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1242,12 +1242,10 @@ static void create_potion(unit * u, const potion_type * ptype, int want) void make_item(unit * u, const item_type * itype, int want) { if (itype->construction && fval(itype->rtype, RTF_LIMITED)) { -#if GUARD_DISABLES_PRODUCTION == 1 if (is_guarded(u->region, u)) { cmistake(u, u->thisorder, 70, MSG_EVENT); return; } -#endif allocate_resource(u, itype->rtype, want); } else { diff --git a/src/settings.h b/src/settings.h index e7ec39305..86d5a5571 100644 --- a/src/settings.h +++ b/src/settings.h @@ -13,7 +13,6 @@ #define ENTERTAINFRACTION 20 #define TEACHDIFFERENCE 2 #define GUARD_DISABLES_RECRUIT 1 -#define GUARD_DISABLES_PRODUCTION 1 #define RESOURCE_QUANTITY 0.5 #define RECRUITFRACTION 40 /* 100/RECRUITFRACTION% */ #define COMBAT_TURNS 5 From d99090ac678b675cc36701cb36e8b5b2814a8a07 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Mar 2017 21:29:37 +0200 Subject: [PATCH 115/218] remove additional unused macro constants --- src/economy.c | 2 -- src/kernel/save.c | 2 -- src/laws.c | 27 --------------------------- src/settings.h | 3 --- 4 files changed, 34 deletions(-) diff --git a/src/economy.c b/src/economy.c index 83e4bf9d0..8a313a074 100644 --- a/src/economy.c +++ b/src/economy.c @@ -468,7 +468,6 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders) assert(rc); u_setrace(u, rc); -#if GUARD_DISABLES_RECRUIT /* 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(). */ @@ -476,7 +475,6 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders) cmistake(u, ord, 70, MSG_EVENT); return; } -#endif if (rc == get_race(RC_INSECT)) { gamedate date; diff --git a/src/kernel/save.c b/src/kernel/save.c index 105ad7324..cd944f345 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1121,9 +1121,7 @@ static ally **addally(const faction * f, ally ** sfp, int aid, int state) ally *sf; state &= ~HELP_OBSERVE; -#ifndef REGIONOWNERS state &= ~HELP_TRAVEL; -#endif state &= HelpMask(); if (state == 0) diff --git a/src/laws.c b/src/laws.c index 9b3e9946a..adf8b9f11 100644 --- a/src/laws.c +++ b/src/laws.c @@ -284,31 +284,6 @@ static double peasant_growth_factor(void) return config_get_flt("rules.peasants.growth.factor", 0.0001F * PEASANTGROWTH); } -#ifdef SLOWLUCK -int peasant_luck_effect(int peasants, int luck, int maxp, double variance) { - int n, births = 0; - double factor = peasant_growth_factor(); - for (n = peasants; n && luck; --n) { - int chances = 0; - - if (luck > 0) { - --luck; - chances += PEASANTLUCK; - } - - while (chances--) { - if (rng_double() < factor) { - /* Only raise with 75% chance if peasants have - * reached 90% of maxpopulation */ - if (peasants / (float)maxp < 0.9 || chance(PEASANTFORCE)) { - ++births; - } - } - } - } - return births; -} -#else static double peasant_luck_factor(void) { return config_get_flt("rules.peasants.peasantluck.factor", PEASANTLUCK); @@ -331,8 +306,6 @@ int peasant_luck_effect(int peasants, int luck, int maxp, double variance) return births; } -#endif - static void peasants(region * r, int rule) { int peasants = rpeasants(r); diff --git a/src/settings.h b/src/settings.h index 86d5a5571..72e179738 100644 --- a/src/settings.h +++ b/src/settings.h @@ -12,7 +12,6 @@ #define ENTERTAINFRACTION 20 #define TEACHDIFFERENCE 2 -#define GUARD_DISABLES_RECRUIT 1 #define RESOURCE_QUANTITY 0.5 #define RECRUITFRACTION 40 /* 100/RECRUITFRACTION% */ #define COMBAT_TURNS 5 @@ -31,8 +30,6 @@ */ #define MUSEUM_MODULE 1 -#undef REGIONOWNERS /* (WIP) region-owner uses HELP_TRAVEL to control entry to region */ - /* experimental gameplay features (that don't affect the savefile) */ /* TODO: move these settings to settings.h or into configuration files */ #define GOBLINKILL /* Goblin-Spezialklau kann toedlich enden */ From ed99f6018645d4868a20c8301a7b2615644b4d24 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Mar 2017 21:37:30 +0200 Subject: [PATCH 116/218] decluttering settings.h --- src/attributes/attributes.c | 2 +- src/economy.c | 16 ---------------- src/kernel/faction.c | 26 ++------------------------ src/kernel/faction.h | 2 -- src/kernel/unit.c | 6 +++--- src/settings.h | 12 +----------- 6 files changed, 7 insertions(+), 57 deletions(-) diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index c4925b9c0..f699fdb57 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -102,7 +102,6 @@ void register_attributes(void) at_register(&at_group); at_register(&at_building_generic_type); - at_register(&at_maxmagicians); at_register(&at_npcfaction); /* connection-typen */ @@ -114,6 +113,7 @@ void register_attributes(void) at_register(&at_germs); + at_deprecate("maxmagicians", a_readint); /* factions with differnt magician limits, probably unused */ at_deprecate("hurting", a_readint); /* an old arena attribute */ at_deprecate("xontormiaexpress", a_readint); /* required for old datafiles */ at_deprecate("orcification", a_readint); /* required for old datafiles */ diff --git a/src/economy.c b/src/economy.c index 8a313a074..fa8d6aa22 100644 --- a/src/economy.c +++ b/src/economy.c @@ -480,7 +480,6 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders) gamedate date; get_gamedate(turn, &date); if (date.season == 0 && r->terrain != newterrain(T_DESERT)) { -#ifdef INSECT_POTION bool usepotion = false; unit *u2; @@ -490,7 +489,6 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders) break; } if (!usepotion) -#endif { cmistake(u, ord, 98, MSG_EVENT); return; @@ -2016,20 +2014,6 @@ static void expandstealing(region * r, request * stealorders) if (u && u->region == r) { n = get_pooled(u, rsilver, GET_ALL, INT_MAX); } -#ifndef GOBLINKILL - if (oa[i].type.goblin) { /* Goblin-Spezialklau */ - int uct = 0; - unit *u2; - assert(effskill(oa[i].unit, SK_STEALTH) >= 4 - || !"this goblin\'s skill is too low"); - for (u2 = r->units; u2; u2 = u2->next) { - if (u2->faction == u->faction) { - uct += maintenance_cost(u2); - } - } - n -= uct * 2; - } -#endif if (n > 10 && rplane(r) && (rplane(r)->flags & PFL_NOALLIANCES)) { /* In Questen nur reduziertes Klauen */ n = 10; diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 03cea282f..ae60ce439 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -644,7 +644,7 @@ int skill_limit(faction * f, skill_t sk) m = max_magicians(f); } else if (sk == SK_ALCHEMY) { - m = config_get_int("rules.maxskills.alchemy", MAXALCHEMISTS); + m = config_get_int("rules.maxskills.alchemy", 3); } return m; } @@ -752,22 +752,6 @@ int count_maxmigrants(const faction * f) return 0; } -static void init_maxmagicians(struct attrib *a) -{ - a->data.i = MAXMAGICIANS; -} - -attrib_type at_maxmagicians = { - "maxmagicians", - init_maxmagicians, - NULL, - NULL, - a_writeint, - a_readint, - NULL, - ATF_UNIQUE -}; - int max_magicians(const faction * f) { static int rule, config, rc_cache; @@ -775,15 +759,9 @@ int max_magicians(const faction * f) int m; if (config_changed(&config)) { - rule = config_get_int("rules.maxskills.magic", MAXMAGICIANS); + rule = config_get_int("rules.maxskills.magic", 3); } m = rule; - if (f->attribs) { - attrib *a = a_find(f->attribs, &at_maxmagicians); - if (a) { - m = a->data.i; - } - } if (rc_changed(&rc_cache)) { rc_elf = get_race(RC_ELF); } diff --git a/src/kernel/faction.h b/src/kernel/faction.h index c6afc767c..edd812bf0 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -35,8 +35,6 @@ extern "C" { struct gamedata; struct selist; - extern struct attrib_type at_maxmagicians; - /* faction flags */ #define FFL_NEWID (1<<0) /* Die Partei hat bereits einmal ihre no gewechselt */ #define FFL_ISNEW (1<<1) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index ddc8e0e4a..9dbfbfe0e 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1724,13 +1724,13 @@ int unit_max_hp(const unit * u) int h; double p; static int config; - static int rule_stamina; + static bool rule_stamina; h = u_race(u)->hitpoints; if (config_changed(&config)) { - rule_stamina = config_get_int("rules.stamina", STAMINA_AFFECTS_HP); + rule_stamina = config_get_int("rules.stamina", 1)!=0; } - if (rule_stamina & 1) { + if (rule_stamina) { p = pow(effskill(u, SK_STAMINA, u->region) / 2.0, 1.5) * 0.2; h += (int)(h * p + 0.5); } diff --git a/src/settings.h b/src/settings.h index 72e179738..e8693a763 100644 --- a/src/settings.h +++ b/src/settings.h @@ -30,23 +30,13 @@ */ #define MUSEUM_MODULE 1 - /* experimental gameplay features (that don't affect the savefile) */ /* TODO: move these settings to settings.h or into configuration files */ -#define GOBLINKILL /* Goblin-Spezialklau kann toedlich enden */ -#define INSECT_POTION /* Spezialtrank fuer Insekten */ - #define TREESIZE (8) /* space used by trees (in #peasants) */ - #define PEASANTFORCE 0.75 /* Chance einer Vermehrung trotz 90% Auslastung */ - /* Gebaeudegroesse = Minimalbelagerer */ +/* Gebaeudegroesse = Minimalbelagerer */ #define SIEGEFACTOR 2 - /** Magic */ -#define MAXMAGICIANS 3 -#define MAXALCHEMISTS 3 - #define ENCCHANCE 10 /* %-Chance fuer einmalige Zufallsbegegnung */ #define BAGCAPACITY 20000 /* soviel passt in einen Bag of Holding */ #define PERSON_WEIGHT 1000 /* weight of a "normal" human unit */ -#define STAMINA_AFFECTS_HP 1<<0 From 967e70a4e15485f7091c1235e630f9161c83b85c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 18 Mar 2017 18:20:20 +0100 Subject: [PATCH 117/218] SMF_RIDING is unused. --- src/kernel/skills.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/kernel/skills.h b/src/kernel/skills.h index bca7dca50..2270d091c 100644 --- a/src/kernel/skills.h +++ b/src/kernel/skills.h @@ -28,7 +28,6 @@ extern "C" { /* skillmod_data::flags -- wann gilt der modifier? */ #define SMF_ALWAYS (1<<0) /* immer */ #define SMF_PRODUCTION (1<<1) /* fr Produktion - am gebude, an der einheit */ -#define SMF_RIDING (1<<2) /* Bonus fr berittene - an der rasse */ typedef struct skill { #ifdef LOMEM From 0ff9f1601cfb5a406602a1d0296c7e19c4f4fee8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 18 Mar 2017 18:24:02 +0100 Subject: [PATCH 118/218] de-clutter header file. --- src/kernel/build.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/kernel/build.h b/src/kernel/build.h index 7780a6cd2..b09dd8332 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -32,8 +32,6 @@ extern "C" { * wichtig */ - struct xml_tag; - typedef struct requirement { const struct resource_type *rtype; int number; @@ -63,8 +61,8 @@ extern "C" { } construction; void free_construction(struct construction *cons); - extern int destroy_cmd(struct unit *u, struct order *ord); - extern int leave_cmd(struct unit *u, struct order *ord); + int destroy_cmd(struct unit *u, struct order *ord); + int leave_cmd(struct unit *u, struct order *ord); void build_road(struct unit *u, int size, direction_t d); void create_ship(struct unit *u, const struct ship_type *newtype, @@ -74,16 +72,15 @@ extern "C" { struct building *getbuilding(const struct region *r); struct ship *getship(const struct region *r); - void reportevent(struct region *r, char *s); - void shash(struct ship *sh); void sunhash(struct ship *sh); - extern int roqf_factor(void); + int roqf_factor(void); int build(struct unit *u, const construction * ctype, int completed, int want); - extern int maxbuild(const struct unit *u, const construction * cons); - extern struct message *msg_materials_required(struct unit *u, - struct order *ord, const struct construction *ctype, int multi); + 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); + /** error messages that build may return: */ #define ELOWSKILL -1 #define ENEEDSKILL -2 From 329ab2be2a2ac6a330f9936c5cab4fca3fe619ff Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 1 Apr 2017 11:42:48 +0200 Subject: [PATCH 119/218] update to cmake-fixed submodules --- cJSON | 2 +- iniparser | 2 +- storage | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cJSON b/cJSON index 43c04ad61..22a4fc9be 160000 --- a/cJSON +++ b/cJSON @@ -1 +1 @@ -Subproject commit 43c04ad61258ec3d54a2167eb3a43915bd003ab1 +Subproject commit 22a4fc9be31f0426e622f5bc9ebd7a1550845001 diff --git a/iniparser b/iniparser index ecf956b98..22741d9ce 160000 --- a/iniparser +++ b/iniparser @@ -1 +1 @@ -Subproject commit ecf956b9808c28c2db52e6b73930f57876dbb258 +Subproject commit 22741d9ce9d19bf7b5f5a219b6ed0925259a4d1b diff --git a/storage b/storage index 2117191d4..d807ef5ce 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit 2117191d4ad75e1eb14809878bc71d15b20a5d86 +Subproject commit d807ef5ce64b3425b31fb440e0b93a4d233f517a From 4aa26343f62af69da948f72d4866e65cb22b6c28 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 1 Apr 2017 20:08:04 +0200 Subject: [PATCH 120/218] the LOMEM define has never been used, kill it. --- src/battle.h | 5 ----- src/economy.c | 7 ++++--- src/kernel/faction.h | 2 +- src/kernel/order.c | 5 ----- src/kernel/resources.h | 11 +---------- src/kernel/skills.h | 7 ------- 6 files changed, 6 insertions(+), 31 deletions(-) diff --git a/src/battle.h b/src/battle.h index 85e65cf66..4e20d00d8 100644 --- a/src/battle.h +++ b/src/battle.h @@ -123,13 +123,8 @@ extern "C" { typedef struct weapon { int count, used; const struct weapon_type *type; -# ifdef LOMEM - int attackskill : 8; - int defenseskill : 8; -# else int attackskill; int defenseskill; -# endif } weapon; /*** fighter::person::flags ***/ diff --git a/src/economy.c b/src/economy.c index fa8d6aa22..03ab07bcd 100644 --- a/src/economy.c +++ b/src/economy.c @@ -879,13 +879,14 @@ enum { AFL_LOWSKILL = 1 << 1 }; -struct message * get_modifiers(unit *u, const resource_mod *mod, variant *savep, int *skillp) { +struct message * get_modifiers(unit *u, const resource_type *rtype, variant *savep, int *skillp) { struct building *b = inside_building(u); const struct building_type *btype = building_is_active(b) ? b->type : NULL; int save_n = 1, save_d = 1; int skill = 0; + resource_mod *mod; - for (; mod->flags != 0; ++mod) { + for (mod = rtype->modifiers; mod && mod->flags != 0; ++mod) { if (mod->btype == NULL || mod->btype == btype) { if (mod->race == NULL || mod->race == u_race(u)) { if (mod->flags & RMF_SAVEMATERIAL) { @@ -940,7 +941,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) } if (rtype->modifiers) { - message *msg = get_modifiers(u, rtype->modifiers, &save_mod, &skill_mod); + message *msg = get_modifiers(u, rtype, &save_mod, &skill_mod); if (msg) { ADDMSG(&u->faction->msgs, msg); return; diff --git a/src/kernel/faction.h b/src/kernel/faction.h index edd812bf0..e0cd893a1 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -42,8 +42,8 @@ extern "C" { #define FFL_QUIT (1<<3) #define FFL_CURSED (1<<4) /* you're going to have a bad time */ #define FFL_DEFENDER (1<<10) -#define FFL_SELECT (1<<18) /* ehemals f->dh, u->dh, r->dh, etc... */ #define FFL_NOAID (1<<21) /* Hilfsflag Kampf */ +#define FFL_SELECT (1<<22) /* ehemals f->dh, u->dh, r->dh, etc... */ #define FFL_MARK (1<<23) /* f�r markierende algorithmen, die das * hinterher auch wieder l�schen m�ssen! * (FFL_SELECT muss man vorher initialisieren, diff --git a/src/kernel/order.c b/src/kernel/order.c index 9e7a45991..6fbb53040 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -44,13 +44,8 @@ static struct locale_data *locale_array[MAXLOCALES]; typedef struct order_data { const char *_str; -# ifdef LOMEM - int _refcount:20; - int _lindex:4; -# else int _refcount; int _lindex; -# endif keyword_t _keyword; } order_data; diff --git a/src/kernel/resources.h b/src/kernel/resources.h index 67cd48d43..d94f043fc 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -25,29 +25,20 @@ extern "C" { typedef struct rawmaterial { const struct resource_type *rtype; -#ifdef LOMEM - int amount:16; - int level:8; - int flags:8; - int base:8; - int divisor:8; - int startlevel:8; -#else int amount; int level; int flags; int base; int divisor; int startlevel; -#endif struct rawmaterial *next; } rawmaterial; typedef struct resource_mod { + int flags; variant value; const struct building_type *btype; const struct race *race; - unsigned int flags; } resource_mod; typedef struct rawmaterial_type { diff --git a/src/kernel/skills.h b/src/kernel/skills.h index 2270d091c..d294485cb 100644 --- a/src/kernel/skills.h +++ b/src/kernel/skills.h @@ -30,17 +30,10 @@ extern "C" { #define SMF_PRODUCTION (1<<1) /* fr Produktion - am gebude, an der einheit */ typedef struct skill { -#ifdef LOMEM - int id:8; - unsigned int level:8; - unsigned int weeks:8; - unsigned int old:8; -#else int id; int level; int weeks; int old; -#endif } skill; typedef int(*skillmod_fun) (const struct unit *, const struct region *, From e72155a563b0bf64ac752cb64622df1ac9e797df Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 2 Apr 2017 14:43:53 +0200 Subject: [PATCH 121/218] WIP: reimplemented production modifiers. The system itself seems to work, but some Lua tests are still failing. --- res/core/common/buildings.xml | 3 +- res/core/messages.xml | 9 ++ res/core/resources/iron.xml | 3 +- res/core/weapons/greatbow.xml | 2 +- res/e3a/armor/scale.xml | 2 +- res/e3a/armor/towershield.xml | 2 +- res/e3a/resources/iron.xml | 1 + res/e3a/weapons/greatbow.xml | 2 +- res/e3a/weapons/rep_crossbow.xml | 2 +- scripts/tests/production.lua | 27 ++++++ src/attributes/CMakeLists.txt | 1 - src/attributes/matmod.c | 41 --------- src/attributes/matmod.h | 37 -------- src/economy.c | 125 ++++++++++++++++---------- src/economy.test.c | 138 +++++++++++++++++++++++++++- src/kernel/build.c | 70 ++++++--------- src/kernel/build.h | 5 +- src/kernel/build.test.c | 30 +++---- src/kernel/building.c | 30 ------- src/kernel/building.h | 2 +- src/kernel/building.test.c | 1 - src/kernel/item.h | 5 -- src/kernel/resources.h | 11 ++- src/kernel/xmlreader.c | 148 +++++++++++++++---------------- 24 files changed, 385 insertions(+), 312 deletions(-) delete mode 100644 src/attributes/matmod.c delete mode 100644 src/attributes/matmod.h diff --git a/res/core/common/buildings.xml b/res/core/common/buildings.xml index 540e9f085..a799ce309 100644 --- a/res/core/common/buildings.xml +++ b/res/core/common/buildings.xml @@ -93,7 +93,6 @@ - @@ -102,6 +101,8 @@ + + diff --git a/res/core/messages.xml b/res/core/messages.xml index a12252d96..5d8a60ef0 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -5539,6 +5539,15 @@ "$unit($unit) in $region($region): '$order($command)' - Diesen Gegenstand kann die Einheit nicht herstellen." "$unit($unit) in $region($region): '$order($command)' - This unit cannot produce that." + + + + + + + "$unit($unit) in $region($region): '$order($command)' - Diese Rasse kann das nicht herstellen." + "$unit($unit) in $region($region): '$order($command)' - This race cannot produce that." + diff --git a/res/core/resources/iron.xml b/res/core/resources/iron.xml index 70d5c1080..1aff826fc 100644 --- a/res/core/resources/iron.xml +++ b/res/core/resources/iron.xml @@ -3,7 +3,8 @@ + - + diff --git a/res/core/weapons/greatbow.xml b/res/core/weapons/greatbow.xml index 32f07a41e..452ac0250 100644 --- a/res/core/weapons/greatbow.xml +++ b/res/core/weapons/greatbow.xml @@ -1,8 +1,8 @@ + - diff --git a/res/e3a/armor/scale.xml b/res/e3a/armor/scale.xml index 1038f4d6c..c8c6804de 100644 --- a/res/e3a/armor/scale.xml +++ b/res/e3a/armor/scale.xml @@ -1,8 +1,8 @@ + - diff --git a/res/e3a/armor/towershield.xml b/res/e3a/armor/towershield.xml index 38e4f0928..45958f175 100644 --- a/res/e3a/armor/towershield.xml +++ b/res/e3a/armor/towershield.xml @@ -1,8 +1,8 @@ + - diff --git a/res/e3a/resources/iron.xml b/res/e3a/resources/iron.xml index 01e0d8d6d..55f63ca67 100644 --- a/res/e3a/resources/iron.xml +++ b/res/e3a/resources/iron.xml @@ -3,6 +3,7 @@ + diff --git a/res/e3a/weapons/greatbow.xml b/res/e3a/weapons/greatbow.xml index 745d1793d..358a55f7d 100644 --- a/res/e3a/weapons/greatbow.xml +++ b/res/e3a/weapons/greatbow.xml @@ -4,9 +4,9 @@ * has lower damage --> + - diff --git a/res/e3a/weapons/rep_crossbow.xml b/res/e3a/weapons/rep_crossbow.xml index 02f0d865f..ffa1c0455 100644 --- a/res/e3a/weapons/rep_crossbow.xml +++ b/res/e3a/weapons/rep_crossbow.xml @@ -1,8 +1,8 @@ + - diff --git a/scripts/tests/production.lua b/scripts/tests/production.lua index f797f3d32..b470a2652 100644 --- a/scripts/tests/production.lua +++ b/scripts/tests/production.lua @@ -124,6 +124,33 @@ function test_quarry_bonus() turn_end() end +function test_smithy_no_bonus() +-- a smithy does not give a bonus to other skills +-- five cartmakers make 5 carts, no matter what + local r = region.create(0, 0, 'mountain') + local f = create_faction('human') + local u = unit.create(f, r, 1) + + turn_begin() + u.building = building.create(u.region, 'smithy') + u.building.working = false + u.building.size = 10 + u.number = 5 + u:set_skill('cartmaking', 1) -- needs 1 min + u:add_item('log', 100) + u:add_order("MACHE Wagen") + turn_process() -- building disabled + assert_equal(5, u:get_item('cart')) + assert_equal(75, u:get_item('log')) + + u.building.working = true + turn_process() -- building active + assert_equal(10, u:get_item('cart')) + assert_equal(50, u:get_item('log')) + + turn_end() +end + function test_smithy_bonus_iron() -- a smithy adds +1 to weaponsmithing, and saves 50% iron local r = region.create(0, 0, 'mountain') diff --git a/src/attributes/CMakeLists.txt b/src/attributes/CMakeLists.txt index d0aa252ee..8be9dc7ff 100644 --- a/src/attributes/CMakeLists.txt +++ b/src/attributes/CMakeLists.txt @@ -12,7 +12,6 @@ follow.c hate.c iceberg.c key.c -matmod.c moved.c movement.c dict.c diff --git a/src/attributes/matmod.c b/src/attributes/matmod.c deleted file mode 100644 index 0cf1955d8..000000000 --- a/src/attributes/matmod.c +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (c) 1998-2015, Enno Rehling -Katja Zedel - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -**/ - -#include -#include "matmod.h" - -#include -#include - -attrib_type at_matmod = { - "matmod", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - ATF_PRESERVE -}; - -attrib *make_matmod(mm_fun function) -{ - attrib *a = a_new(&at_matmod); - a->data.f = (void(*)(void))function; - return a; -} diff --git a/src/attributes/matmod.h b/src/attributes/matmod.h deleted file mode 100644 index 99171d338..000000000 --- a/src/attributes/matmod.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (c) 1998-2015, Enno Rehling -Katja Zedel - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -**/ - -#ifndef H_ATTRIBUTE_MATMOD -#define H_ATTRIBUTE_MATMOD - -#ifdef __cplusplus -extern "C" { -#endif - - struct resource_type; - struct unit; - typedef int(*mm_fun) (const struct unit * u, - const struct resource_type * rtype, int value); - - extern struct attrib_type at_matmod; - extern struct attrib *make_matmod(mm_fun function); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/economy.c b/src/economy.c index 03ab07bcd..69efe85cb 100644 --- a/src/economy.c +++ b/src/economy.c @@ -798,7 +798,69 @@ void economics(region * r) } -/* ------------------------------------------------------------- */ +static void mod_skill(const resource_mod *mod, skill_t sk, int *skill) { + skill_t msk; + assert(mod->type == RMT_PROD_SKILL); + msk = (skill_t)mod->value.sa[0]; + if (msk == NOSKILL || msk == sk) { + *skill += mod->value.sa[1]; + } +} + +static struct message * get_modifiers(unit *u, skill_t sk, const resource_type *rtype, variant *savep, int *skillp) { + struct building *b = inside_building(u); + const struct building_type *btype = building_is_active(b) ? b->type : NULL; + int save_n = 1, save_d = 1; + int skill = 0; + int need_race = 0, need_bldg = 0; + resource_mod *mod; + + if (btype && btype->modifiers) { + for (mod = btype->modifiers; mod && mod->type != RMT_END; ++mod) { + if (mod->type == RMT_PROD_SKILL) { + mod_skill(mod, sk, &skill); + } + } + } + + for (mod = rtype->modifiers; mod && mod->type != RMT_END; ++mod) { + if (mod->btype == NULL || mod->btype == btype) { + if (mod->race == NULL || mod->race == u_race(u)) { + switch (mod->type) { + case RMT_PROD_SAVE: + if (savep) { + save_n *= mod->value.sa[0]; + save_d *= mod->value.sa[1]; + } + break; + case RMT_PROD_SKILL: + mod_skill(mod, sk, &skill); + break; + case RMT_PROD_REQUIRE: + if (mod->race) need_race |= 1; + if (mod->btype) need_bldg |= 1; + break; + default: + /* is not a production modifier, ignore it */ + break; + } + } + } + if (mod->type == RMT_PROD_REQUIRE) { + if (mod->race) need_race |= 2; + if (mod->btype) need_bldg |= 2; + } + } + if (need_race == 2) { + return msg_error(u, u->thisorder, 117); + } + if (need_bldg == 2) { + return msg_error(u, u->thisorder, 104); + } + *skillp = skill; + if (savep) *savep = frac_make(save_n, save_d); + return NULL; +} static void manufacture(unit * u, const item_type * itype, int want) { @@ -806,22 +868,20 @@ static void manufacture(unit * u, const item_type * itype, int want) int skill; int minskill = itype->construction->minskill; skill_t sk = itype->construction->skill; + message *msg; + int skill_mod; - skill = effskill(u, sk, 0); - skill = - skillmod(itype->construction->attribs, u, u->region, sk, skill, SMF_PRODUCTION); - - if (skill < 0) { - /* an error occured */ - int err = -skill; - cmistake(u, u->thisorder, err, MSG_PRODUCE); + msg = get_modifiers(u, sk, itype->rtype, NULL, &skill_mod); + if (msg) { + ADDMSG(&u->faction->msgs, msg); return; } + skill = effskill(u, sk, 0); if (want == 0) { want = maxbuild(u, itype->construction); } - n = build(u, itype->construction, 0, want); + n = build(u, itype->construction, 0, want, skill_mod); switch (n) { case ENEEDSKILL: ADDMSG(&u->faction->msgs, @@ -879,38 +939,6 @@ enum { AFL_LOWSKILL = 1 << 1 }; -struct message * get_modifiers(unit *u, const resource_type *rtype, variant *savep, int *skillp) { - struct building *b = inside_building(u); - const struct building_type *btype = building_is_active(b) ? b->type : NULL; - int save_n = 1, save_d = 1; - int skill = 0; - resource_mod *mod; - - for (mod = rtype->modifiers; mod && mod->flags != 0; ++mod) { - if (mod->btype == NULL || mod->btype == btype) { - if (mod->race == NULL || mod->race == u_race(u)) { - if (mod->flags & RMF_SAVEMATERIAL) { - save_n *= mod->value.sa[0]; - save_d *= mod->value.sa[1]; - } - if (mod->flags & RMF_SKILL) { - skill += mod->value.i; - } - } - } else if (mod->flags & RMF_REQUIREDBUILDING) { - return msg_error(u, u->thisorder, 104); - } - } - *skillp = skill; - assert(save_n < SHRT_MAX); - assert(save_n > SHRT_MIN); - assert(save_d < SHRT_MAX); - assert(save_d > SHRT_MIN); - savep->sa[0] = (short)save_n; - savep->sa[1] = (short)save_d; - return NULL; -} - static void allocate_resource(unit * u, const resource_type * rtype, int want) { const item_type *itype = resource2item(rtype); @@ -921,12 +949,14 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) const resource_type *rring; int amount, skill, skill_mod = 0; variant save_mod; + skill_t sk; /* momentan kann man keine ressourcen abbauen, wenn man daf�r * Materialverbrauch hat: */ assert(itype != NULL && (itype->construction == NULL || itype->construction->materials == NULL)); + sk = itype->construction->skill; if (!rtype->raw) { int avail = limit_resource(r, rtype); if (avail <= 0) { @@ -941,7 +971,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) } if (rtype->modifiers) { - message *msg = get_modifiers(u, rtype, &save_mod, &skill_mod); + message *msg = get_modifiers(u, sk, rtype, &save_mod, &skill_mod); if (msg) { ADDMSG(&u->faction->msgs, msg); return; @@ -969,17 +999,14 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) } } - assert(itype->construction->skill != 0 - || "limited resource needs a required skill for making it"); - skill = effskill(u, itype->construction->skill, 0); + assert(sk != NOSKILL || "limited resource needs a required skill for making it"); + skill = effskill(u, sk, 0); if (skill == 0) { - skill_t sk = itype->construction->skill; add_message(&u->faction->msgs, msg_feedback(u, u->thisorder, "skill_needed", "skill", sk)); return; } if (skill < itype->construction->minskill) { - skill_t sk = itype->construction->skill; add_message(&u->faction->msgs, msg_feedback(u, u->thisorder, "manufacture_skills", "skill minskill product", sk, itype->construction->minskill, @@ -1204,7 +1231,7 @@ static void create_potion(unit * u, const potion_type * ptype, int want) if (want == 0) { want = maxbuild(u, ptype->itype->construction); } - built = build(u, ptype->itype->construction, 0, want); + built = build(u, ptype->itype->construction, 0, want, 0); switch (built) { case ELOWSKILL: case ENEEDSKILL: diff --git a/src/economy.test.c b/src/economy.test.c index a0a000ccd..842db45f8 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -345,7 +345,114 @@ static void test_income(CuTest *tc) test_cleanup(); } -static void test_make_item(CuTest *tc) { +static void test_modify_material(CuTest *tc) { + unit *u; + struct item_type *itype; + resource_type *rtype; + resource_mod *mod; + + test_setup(); + init_resources(); + + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + set_level(u, SK_WEAPONSMITH, 1); + + /* the unit's race gets 2x savings on iron used to produce goods */ + itype = test_create_itemtype("iron"); + rtype = itype->rtype; + mod = rtype->modifiers = calloc(2, sizeof(resource_mod)); + mod[0].type = RMT_USE_SAVE; + mod[0].value = frac_make(2, 1); + mod[0].race = u_race(u); + + itype = test_create_itemtype("sword"); + make_item(u, itype, 1); + CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error_cannotmake")); + CuAssertIntEquals(tc, 0, get_item(u, itype)); + test_clear_messages(u->faction); + itype->construction = calloc(1, sizeof(construction)); + itype->construction->skill = SK_WEAPONSMITH; + itype->construction->minskill = 1; + itype->construction->maxsize = 1; + itype->construction->reqsize = 1; + itype->construction->materials = calloc(2, sizeof(requirement)); + itype->construction->materials[0].rtype = rtype; + itype->construction->materials[0].number = 2; + + set_item(u, rtype->itype, 1); /* 1 iron should get us 1 sword */ + make_item(u, itype, 1); + CuAssertIntEquals(tc, 1, get_item(u, itype)); + CuAssertIntEquals(tc, 0, get_item(u, rtype->itype)); + + u_setrace(u, test_create_race("smurf")); + set_item(u, rtype->itype, 2); /* 2 iron should be required now */ + make_item(u, itype, 1); + CuAssertIntEquals(tc, 2, get_item(u, itype)); + CuAssertIntEquals(tc, 0, get_item(u, rtype->itype)); + + test_cleanup(); +} + +static void test_modify_skill(CuTest *tc) { + unit *u; + struct item_type *itype; + /* building_type *btype; */ + resource_type *rtype; + resource_mod *mod; + + test_setup(); + init_resources(); + + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + set_level(u, SK_WEAPONSMITH, 1); + + itype = test_create_itemtype("iron"); + rtype = itype->rtype; + + itype = test_create_itemtype("sword"); + make_item(u, itype, 1); + CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error_cannotmake")); + CuAssertIntEquals(tc, 0, get_item(u, itype)); + test_clear_messages(u->faction); + itype->construction = calloc(1, sizeof(construction)); + itype->construction->skill = SK_WEAPONSMITH; + itype->construction->minskill = 1; + itype->construction->maxsize = -1; + itype->construction->reqsize = 1; + itype->construction->materials = calloc(2, sizeof(requirement)); + itype->construction->materials[0].rtype = rtype; + itype->construction->materials[0].number = 1; + + /* our race gets a +1 bonus to the item's production skill */ + mod = itype->rtype->modifiers = calloc(2, sizeof(resource_mod)); + mod[0].type = RMT_PROD_SKILL; + mod[0].value.sa[0] = SK_WEAPONSMITH; + mod[0].value.sa[1] = 1; + mod[0].race = u_race(u); + + set_item(u, rtype->itype, 2); /* 2 iron should get us 2 swords */ + make_item(u, itype, 2); + CuAssertIntEquals(tc, 2, get_item(u, itype)); + CuAssertIntEquals(tc, 0, get_item(u, rtype->itype)); + + mod[0].value.sa[0] = NOSKILL; /* match any skill */ + set_item(u, rtype->itype, 2); + make_item(u, itype, 2); + CuAssertIntEquals(tc, 4, get_item(u, itype)); + CuAssertIntEquals(tc, 0, get_item(u, rtype->itype)); + + + u_setrace(u, test_create_race("smurf")); + set_item(u, rtype->itype, 2); + make_item(u, itype, 1); /* only enough skill to make 1 now */ + CuAssertIntEquals(tc, 5, get_item(u, itype)); + CuAssertIntEquals(tc, 1, get_item(u, rtype->itype)); + + test_cleanup(); +} + + +static void test_modify_production(CuTest *tc) { unit *u; struct item_type *itype; const struct resource_type *rt_silver; @@ -393,7 +500,7 @@ static void test_make_item(CuTest *tc) { CuAssertIntEquals(tc, 290, region_getresource(u->region, rtype)); /* used 10 stones to make 10 stones */ rtype->modifiers = calloc(2, sizeof(resource_mod)); - rtype->modifiers[0].flags = RMF_SAVEMATERIAL; + rtype->modifiers[0].type = RMT_PROD_SAVE; rtype->modifiers[0].race = u->_race; rtype->modifiers[0].value.sa[0] = (short)(0.5+100*d); rtype->modifiers[0].value.sa[1] = 100; @@ -413,13 +520,34 @@ static void test_make_item(CuTest *tc) { CuAssertIntEquals(tc, 28, get_item(u, itype)); CuAssertIntEquals(tc, 280, region_getresource(u->region, rtype)); /* 50% saving = 3 stones make 6 stones */ - rtype->modifiers[0].flags = RMF_REQUIREDBUILDING; + rtype->modifiers[0].type = RMT_PROD_REQUIRE; rtype->modifiers[0].race = NULL; rtype->modifiers[0].btype = bt_get_or_create("mine"); + test_clear_messages(u->faction); make_item(u, itype, 10); + CuAssertIntEquals(tc, 28, get_item(u, itype)); CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error104")); + rtype->modifiers[0].type = RMT_PROD_REQUIRE; + rtype->modifiers[0].race = test_create_race("smurf"); + rtype->modifiers[0].btype = NULL; + + test_clear_messages(u->faction); + make_item(u, itype, 10); + CuAssertIntEquals(tc, 28, get_item(u, itype)); + CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error117")); + + rtype->modifiers[1].type = RMT_PROD_REQUIRE; + rtype->modifiers[1].race = u_race(u); + rtype->modifiers[1].btype = NULL; + + test_clear_messages(u->faction); + make_item(u, itype, 10); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); + split_allocations(u->region); + CuAssertIntEquals(tc, 38, get_item(u, itype)); + test_cleanup(); } @@ -429,7 +557,9 @@ CuSuite *get_economy_suite(void) SUITE_ADD_TEST(suite, test_give_control_building); SUITE_ADD_TEST(suite, test_give_control_ship); SUITE_ADD_TEST(suite, test_income); - SUITE_ADD_TEST(suite, test_make_item); + SUITE_ADD_TEST(suite, test_modify_production); + SUITE_ADD_TEST(suite, test_modify_skill); + SUITE_ADD_TEST(suite, test_modify_material); SUITE_ADD_TEST(suite, test_steal_okay); SUITE_ADD_TEST(suite, test_steal_ocean); SUITE_ADD_TEST(suite, test_steal_nosteal); diff --git a/src/kernel/build.c b/src/kernel/build.c index 88ab35fd2..a8125d1a8 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -43,6 +43,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include @@ -67,9 +68,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -/* attributes inclues */ -#include - struct building *getbuilding(const struct region *r) { building *b = findbuilding(getid()); @@ -404,16 +402,26 @@ static int required(int size, int msize, int maxneed) return used; } -static int -matmod(const attrib * a, const unit * u, const resource_type * material, -int value) +static int matmod(const unit * u, const resource_type * rtype, int value) { - for (a = a_find((attrib *)a, &at_matmod); a && a->type == &at_matmod; - a = a->next) { - mm_fun fun = (mm_fun)a->data.f; - value = fun(u, material, value); - if (value < 0) - return value; /* pass errors to caller */ + if (rtype->modifiers) { + variant save = frac_make(1, 1); + const struct building_type *btype = NULL; + const struct race *rc = u_race(u); + resource_mod *mod; + if (u->building && inside_building(u)) { + btype = u->building->type; + } + for (mod = rtype->modifiers; mod->type != RMT_END; ++mod) { + if (mod->type == RMT_USE_SAVE) { + if (!mod->btype || mod->btype == btype) { + if (!mod->race || mod->race == rc) { + save = frac_mul(save, mod->value); + } + } + } + } + return value * save.sa[0] / save.sa[1]; } return value; } @@ -439,14 +447,8 @@ static int use_materials(unit *u, const construction *type, int n, int completed required(completed + n, type->reqsize, type->materials[c].number); int multi = 1; int canuse = 100; /* normalization */ - if (building_is_active(u->building) && inside_building(u)) { - canuse = matmod(u->building->type->attribs, u, rtype, canuse); - } - if (canuse < 0) { - return canuse; /* pass errors to caller */ - } - canuse = matmod(type->attribs, u, rtype, canuse); - + canuse = matmod(u, rtype, canuse); + assert(canuse >= 0); assert(canuse % 100 == 0 || !"only constant multipliers are implemented in build()"); multi = canuse / 100; @@ -468,14 +470,9 @@ static int count_materials(unit *u, const construction *type, int n, int complet const struct resource_type *rtype = type->materials[c].rtype; int need, prebuilt; int canuse = get_pooled(u, rtype, GET_DEFAULT, INT_MAX); + canuse = matmod(u, rtype, canuse); - if (building_is_active(u->building) && inside_building(u)) { - canuse = matmod(u->building->type->attribs, u, rtype, canuse); - } - - if (canuse < 0) - return canuse; /* pass errors to caller */ - canuse = matmod(type->attribs, u, rtype, canuse); + assert(canuse >= 0); if (type->reqsize > 1) { prebuilt = required(completed, type->reqsize, type->materials[c].number); @@ -503,7 +500,7 @@ static int count_materials(unit *u, const construction *type, int n, int complet * of the first object have already been finished. return the * actual size that could be built. */ -int build(unit * u, const construction * ctype, int completed, int want) +int build(unit * u, const construction * ctype, int completed, int want, int skill_mod) { const construction *type = ctype; int skills = INT_MAX; /* number of skill points remainig */ @@ -536,17 +533,8 @@ int build(unit * u, const construction * ctype, int completed, int want) if (basesk == 0) return ENEEDSKILL; - effsk = basesk; - if (building_is_active(u->building) && inside_building(u)) { - effsk = skillmod(u->building->type->attribs, u, u->region, type->skill, - effsk, SMF_PRODUCTION); - } - effsk = skillmod(type->attribs, u, u->region, type->skill, - effsk, SMF_PRODUCTION); - if (effsk < 0) - return effsk; /* pass errors to caller */ - if (effsk == 0) - return ENEEDSKILL; + effsk = basesk + skill_mod; + assert(effsk >= 0); skills = effsk * u->number; @@ -799,7 +787,7 @@ build_building(unit * u, const building_type * btype, int id, int want, order * } } } - built = build(u, btype->construction, built, n); + built = build(u, btype->construction, built, n, 0); switch (built) { case ECOMPLETE: @@ -884,7 +872,7 @@ 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); + int can = build(u, construction, size, want, 0); if ((n = construction->maxsize - sh->size) > 0 && can > 0) { if (can >= n) { diff --git a/src/kernel/build.h b/src/kernel/build.h index b09dd8332..bb1204af9 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -55,9 +55,6 @@ extern "C" { * last level of a building points to NULL, as do objects of * an unlimited size. */ - struct attrib *attribs; - /* stores skill modifiers and other attributes */ - } construction; void free_construction(struct construction *cons); @@ -76,7 +73,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 build(struct unit *u, 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 77efcfd73..34f645856 100644 --- a/src/kernel/build.test.c +++ b/src/kernel/build.test.c @@ -63,10 +63,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)); + CuAssertIntEquals(tc, ENOMATERIALS, build(u, &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)); + CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1, 0)); CuAssertIntEquals(tc, 1, i_get(u->items, itype)); teardown_build(&bf); } @@ -84,12 +84,12 @@ static void test_build_requires_building(CuTest *tc) { bf.cons.btype = btype = bt_get_or_create("hodor"); btype->maxcapacity = 1; btype->capacity = 1; - CuAssertIntEquals_Msg(tc, "must be inside a production building", EBUILDINGREQ, build(u, &bf.cons, 0, 1)); + CuAssertIntEquals_Msg(tc, "must be inside a production building", EBUILDINGREQ, build(u, &bf.cons, 0, 1, 0)); u->building = test_create_building(u->region, btype); fset(u->building, BLD_MAINTAINED); - CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1)); + CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1, 0)); btype->maxcapacity = 0; - CuAssertIntEquals_Msg(tc, "cannot build when production building capacity exceeded", EBUILDINGREQ, build(u, &bf.cons, 0, 1)); + CuAssertIntEquals_Msg(tc, "cannot build when production building capacity exceeded", EBUILDINGREQ, build(u, &bf.cons, 0, 1, 0)); teardown_build(&bf); } @@ -101,7 +101,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)); + CuAssertIntEquals(tc, ENEEDSKILL, build(u, &bf.cons, 1, 1, 0)); teardown_build(&bf); } @@ -114,7 +114,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)); + CuAssertIntEquals(tc, ELOWSKILL, build(u, &bf.cons, 0, 10, 0)); teardown_build(&bf); } @@ -128,7 +128,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)); + CuAssertIntEquals(tc, ECOMPLETE, build(u, &bf.cons, bf.cons.maxsize, 10, 0)); CuAssertIntEquals(tc, 1, i_get(u->items, rtype->itype)); teardown_build(&bf); } @@ -143,19 +143,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)); + CuAssertIntEquals(tc, 1, build(u, &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)); + CuAssertIntEquals(tc, 2, build(u, &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)); + CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 10, 0)); CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype)); teardown_build(&bf); } @@ -174,7 +174,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)); + CuAssertIntEquals(tc, 10, build(u, &bf.cons, 0, 20, 0)); CuAssertIntEquals(tc, 10, i_get(u->items, rtype->itype)); teardown_build(&bf); } @@ -193,16 +193,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)); + CuAssertIntEquals(tc, 2, build(u, &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)); + CuAssertIntEquals(tc, 4, build(u, &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)); + CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 20, 0)); CuAssertIntEquals(tc, 2, get_effect(u, ptype)); teardown_build(&bf); } diff --git a/src/kernel/building.c b/src/kernel/building.c index ef95fd782..3eef32cc4 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -55,7 +55,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* attributes includes */ #include -#include typedef struct building_typelist { struct building_typelist *next; @@ -99,9 +98,6 @@ bool bt_changed(int *cache) void bt_register(building_type * type) { - if (type->init) { - type->init(type); - } selist_push(&buildingtypes, (void *)type); ++bt_changes; } @@ -224,31 +220,6 @@ building *findbuilding(int i) return bfindhash(i); } -/* ** old building types ** */ - -static int sm_smithy(const unit * u, const region * r, skill_t sk, int value) -{ /* skillmod */ - if (sk == SK_WEAPONSMITH || sk == SK_ARMORER) { - if (u->region == r) - return value + 1; - } - return value; -} - -static int mm_smithy(const unit * u, const resource_type * rtype, int value) -{ /* material-mod */ - if (rtype == get_resourcetype(R_IRON)) - return value * 2; - return value; -} - -static void init_smithy(struct building_type *bt) -{ - a_add(&bt->attribs, make_skillmod(NOSKILL, SMF_PRODUCTION, sm_smithy, 1.0, - 0)); - a_add(&bt->attribs, make_matmod(mm_smithy)); -} - static const char *castle_name_i(const struct building_type *btype, const struct building *b, int bsize, const char *fname[]) { @@ -915,7 +886,6 @@ int cmp_current_owner(const building * b, const building * a) void register_buildings(void) { - register_function((pf_generic)init_smithy, "init_smithy"); register_function((pf_generic)castle_name, "castle_name"); register_function((pf_generic)castle_name_2, "castle_name_2"); register_function((pf_generic)fort_name, "fort_name"); diff --git a/src/kernel/building.h b/src/kernel/building.h index 6d66aa9ab..f9803cdbf 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -66,10 +66,10 @@ extern "C" { double auraregen; /* modifier for aura regeneration inside building */ struct maintenance *maintenance; /* array of requirements */ struct construction *construction; /* construction of 1 building-level */ + struct resource_mod *modifiers; /* modify production skills */ const char *(*name) (const struct building_type *, const struct building * b, int size); - void(*init) (struct building_type *); void(*age) (struct building *); double(*taxes) (const struct building *, int size); struct attrib *attribs; diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index 3f415a913..0296e3451 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -296,7 +296,6 @@ static void test_btype_defaults(CuTest *tc) { CuAssertPtrEquals(tc, 0, btype->maintenance); CuAssertPtrEquals(tc, 0, btype->construction); CuAssertTrue(tc, !btype->name); - CuAssertTrue(tc, !btype->init); CuAssertTrue(tc, !btype->age); CuAssertTrue(tc, !btype->taxes); CuAssertDblEquals(tc, 1.0, btype->auraregen, 0.0); diff --git a/src/kernel/item.h b/src/kernel/item.h index 9727e805f..51ebcd2a1 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -90,11 +90,6 @@ extern "C" { const resource_type *findresourcetype(const char *name, const struct locale *lang); - /* resource-limits for regions */ -#define RMF_SKILL 0x01 /* int, bonus on resource production skill */ -#define RMF_SAVEMATERIAL 0x02 /* fraction (sa[0]/sa[1]), multiplier on resource usage */ -#define RMF_REQUIREDBUILDING 0x04 /* building, required to build */ - /* bitfield values for item_type::flags */ #define ITF_NONE 0x0000 #define ITF_HERB 0x0001 /* this item is a herb */ diff --git a/src/kernel/resources.h b/src/kernel/resources.h index d94f043fc..1868dffc0 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -34,8 +34,17 @@ extern "C" { struct rawmaterial *next; } rawmaterial; + /* resource-limits for regions */ + typedef enum resource_modifier_type { + RMT_END, /* array terminator */ + RMT_PROD_SKILL, /* bonus on resource production skill */ + RMT_PROD_SAVE, /* fractional multiplier when produced */ + RMT_PROD_REQUIRE, /* building or race is required to produce this item */ + RMT_USE_SAVE, /* fractional multiplier when used to manufacture something */ + } resource_modifier_type; + typedef struct resource_mod { - int flags; + resource_modifier_type type; variant value; const struct building_type *btype; const struct race *race; diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 7cb871785..603231deb 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -120,6 +120,72 @@ static xmlChar *xml_cleanup_string(xmlChar * str) return str; } +static resource_mod * xml_readmodifiers(xmlXPathObjectPtr result, xmlNodePtr node) { + /* reading eressea/resources/resource/modifier */ + if (result->nodesetval != NULL && result->nodesetval->nodeNr > 0) { + int k; + resource_mod * modifiers = + calloc(result->nodesetval->nodeNr + 1, sizeof(resource_mod)); + for (k = 0; k != result->nodesetval->nodeNr; ++k) { + xmlNodePtr node = result->nodesetval->nodeTab[k]; + xmlChar *propValue; + building_type *btype = NULL; + const race *rc = NULL; + + propValue = xmlGetProp(node, BAD_CAST "race"); + if (propValue != NULL) { + rc = rc_find((const char *)propValue); + if (rc == NULL) + rc = rc_get_or_create((const char *)propValue); + xmlFree(propValue); + } + modifiers[k].race = rc; + + propValue = xmlGetProp(node, BAD_CAST "building"); + if (propValue != NULL) { + btype = bt_get_or_create((const char *)propValue); + xmlFree(propValue); + } + modifiers[k].btype = btype; + + propValue = xmlGetProp(node, BAD_CAST "type"); + assert(propValue != NULL); + if (strcmp((const char *)propValue, "skill") == 0) { + xmlChar *propSkill; + skill_t sk = NOSKILL; + + modifiers[k].type = RMT_PROD_SKILL; + propSkill = xmlGetProp(node, BAD_CAST "skill"); + if (propSkill) { + sk = findskill((const char *)propSkill); + xmlFree(propSkill); + } + modifiers[k].value.sa[0] = (short)sk; + modifiers[k].value.sa[1] = (short)xml_ivalue(node, "value", 0); + } + else if (strcmp((const char *)propValue, "material") == 0) { + modifiers[k].value = xml_fraction(node, "value"); + modifiers[k].type = RMT_PROD_SAVE; + } + else { + if (strcmp((const char *)propValue, "require") == 0) { + modifiers[k].type = RMT_PROD_REQUIRE; + } + else if (strcmp((const char *)propValue, "save") == 0) { + modifiers[k].type = RMT_USE_SAVE; + modifiers[k].value = xml_fraction(node, "value"); + } + else { + log_error("unknown type '%s' for resourcelimit-modifier", (const char *)propValue); + } + } + xmlFree(propValue); + } + return modifiers; + } + return NULL; +} + static void xml_readrequirements(xmlNodePtr * nodeTab, int nodeNr, requirement ** reqArray) { @@ -157,7 +223,6 @@ construction ** consPtr) xmlChar *propValue; construction *con; xmlXPathObjectPtr req; - int m; skill_t sk = NOSKILL; propValue = xmlGetProp(node, BAD_CAST "skill"); @@ -193,23 +258,6 @@ construction ** consPtr) xml_readrequirements(req->nodesetval->nodeTab, req->nodesetval->nodeNr, &con->materials); xmlXPathFreeObject(req); - - /* read construction/modifier */ - xpath->node = node; - req = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); - for (m = 0; m != req->nodesetval->nodeNr; ++m) { - xmlNodePtr node = req->nodesetval->nodeTab[m]; - - propValue = xmlGetProp(node, BAD_CAST "function"); - if (propValue != NULL) { - pf_generic foo = get_function((const char *)propValue); - a_add(&con->attribs, make_skillmod(NOSKILL, SMF_PRODUCTION, - (skillmod_fun)foo, 1.0, 0)); - xmlFree(propValue); - } - - } - xmlXPathFreeObject(req); } xpath->node = pushNode; } @@ -280,6 +328,12 @@ static int parse_buildings(xmlDocPtr doc) if (xml_bvalue(node, "fort", false)) btype->flags |= BTF_FORTIFICATION; + /* reading eressea/buildings/building/modifier */ + xpath->node = node; + result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); + btype->modifiers = xml_readmodifiers(result, node); + xmlXPathFreeObject(result); + /* reading eressea/buildings/building/construction */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); @@ -305,9 +359,6 @@ static int parse_buildings(xmlDocPtr doc) (const char *(*)(const struct building_type *, const struct building *, int))fun; } - else if (strcmp((const char *)propValue, "init") == 0) { - btype->init = (void(*)(struct building_type *))fun; - } else if (strcmp((const char *)propValue, "age") == 0) { btype->age = (void(*)(struct building *))fun; } @@ -344,10 +395,6 @@ static int parse_buildings(xmlDocPtr doc) mt->flags |= MTF_VARIABLE; } xmlXPathFreeObject(result); - - /* finally, initialize the new building type */ - if (btype->init) - btype->init(btype); } } xmlXPathFreeObject(buildings); @@ -951,58 +998,9 @@ static int parse_resources(xmlDocPtr doc) if (xml_bvalue(node, "limited", false)) { rtype->flags |= RTF_LIMITED; } - /* reading eressea/resources/resource/modifier */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); - if (result->nodesetval != NULL && result->nodesetval->nodeNr > 0) { - rtype->modifiers = - calloc(result->nodesetval->nodeNr + 1, sizeof(resource_mod)); - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - building_type *btype = NULL; - const race *rc = NULL; - - propValue = xmlGetProp(node, BAD_CAST "race"); - if (propValue != NULL) { - rc = rc_find((const char *)propValue); - if (rc == NULL) - rc = rc_get_or_create((const char *)propValue); - xmlFree(propValue); - } - rtype->modifiers[k].race = rc; - - propValue = xmlGetProp(node, BAD_CAST "building"); - if (propValue != NULL) { - btype = bt_get_or_create((const char *)propValue); - xmlFree(propValue); - } - rtype->modifiers[k].btype = btype; - - propValue = xmlGetProp(node, BAD_CAST "type"); - assert(propValue != NULL); - if (strcmp((const char *)propValue, "skill") == 0) { - rtype->modifiers[k].value.i = xml_ivalue(node, "value", 0); - rtype->modifiers[k].flags = RMF_SKILL; - } - else if (strcmp((const char *)propValue, "material") == 0) { - rtype->modifiers[k].value = xml_fraction(node, "value"); - rtype->modifiers[k].flags = RMF_SAVEMATERIAL; - } - else if (strcmp((const char *)propValue, "require") == 0) { - xmlChar *propBldg = xmlGetProp(node, BAD_CAST "building"); - if (propBldg != NULL) { - btype = bt_get_or_create((const char *)propBldg); - rtype->modifiers[k].btype = btype; - rtype->modifiers[k].flags = RMF_REQUIREDBUILDING; - xmlFree(propBldg); - } - } - else { - log_error("unknown type '%s' for resourcelimit-modifier '%s'\n", (const char *)propValue, rtype->_name); - } - xmlFree(propValue); - } - } + rtype->modifiers = xml_readmodifiers(result, node); xmlXPathFreeObject(result); /* reading eressea/resources/resource/resourcelimit/function */ xpath->node = node; From 8bb7cf887837eab9b1d44b872702c6fcbc434e02 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 2 Apr 2017 15:35:09 +0200 Subject: [PATCH 122/218] WIP: this error has a new message. --- scripts/tests/e2/production.lua | 2 +- scripts/tests/e3/init.lua | 28 ++++++++++++++-------------- scripts/tests/e3/production.lua | 8 ++++---- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/scripts/tests/e2/production.lua b/scripts/tests/e2/production.lua index 7442d97ac..1d31011af 100644 --- a/scripts/tests/e2/production.lua +++ b/scripts/tests/e2/production.lua @@ -23,7 +23,7 @@ function test_greatbow_needs_elf() u:add_item('mallorn', 2) u:add_order("MACHE Elfenbogen") turn_process() -- humans cannot do it - assert_equal(1, f:count_msg_type("error118")) + assert_equal(1, f:count_msg_type("error117")) assert_equal(0, u:get_item('greatbow')) assert_equal(2, u:get_item('mallorn')) diff --git a/scripts/tests/e3/init.lua b/scripts/tests/e3/init.lua index 6094d0a25..7206c80c4 100644 --- a/scripts/tests/e3/init.lua +++ b/scripts/tests/e3/init.lua @@ -1,15 +1,15 @@ -require 'tests.e3.castles' -require 'tests.e3.stealth' -require 'tests.e3.spells' +-- require 'tests.e3.castles' +-- require 'tests.e3.stealth' +-- require 'tests.e3.spells' require 'tests.e3.rules' -require 'tests.e3.parser' -require 'tests.e3.morale' -require 'tests.e3.items' -require 'tests.economy' -require 'tests.orders' -require 'tests.common' -require 'tests.items' -require 'tests.magicbag' -require 'tests.process' -require 'tests.e3.production' -require 'tests.production' +-- require 'tests.e3.parser' +-- require 'tests.e3.morale' +-- require 'tests.e3.items' +-- require 'tests.economy' +-- require 'tests.orders' +-- require 'tests.common' +-- require 'tests.items' +-- require 'tests.magicbag' +-- require 'tests.process' +-- require 'tests.e3.production' +-- require 'tests.production' diff --git a/scripts/tests/e3/production.lua b/scripts/tests/e3/production.lua index eac296e6a..3469b06c4 100644 --- a/scripts/tests/e3/production.lua +++ b/scripts/tests/e3/production.lua @@ -23,7 +23,7 @@ function test_greatbow_needs_elf() u:add_item('mallorn', 2) u:add_order("MACHE Elfenbogen") turn_process() -- humans cannot do it - assert_equal(1, f:count_msg_type("error118")) + assert_equal(1, f:count_msg_type("error117")) assert_equal(0, u:get_item('greatbow')) assert_equal(2, u:get_item('mallorn')) @@ -75,7 +75,7 @@ function test_dwarf_towershield() u:add_item('iron', 1) u:add_order("MACHE Turmschild") turn_process() -- humans cannot do it - assert_equal(1, f:count_msg_type("error118")) + assert_equal(1, f:count_msg_type("error117")) assert_equal(0, u:get_item('towershield')) assert_equal(1, u:get_item('iron')) @@ -99,7 +99,7 @@ function test_dwarf_scale() u:add_item('iron', 2) u:add_order("MACHE Schuppenpanzer") turn_process() -- humans cannot do it - assert_equal(1, f:count_msg_type("error118")) + assert_equal(1, f:count_msg_type("error117")) assert_equal(0, u:get_item('scale')) assert_equal(2, u:get_item('iron')) @@ -123,7 +123,7 @@ function test_dwarf_rep_xbow() u:add_item('log', 1) u:add_order("MACHE Repetierarmbrust") turn_process() -- humans cannot do it - assert_equal(1, f:count_msg_type("error118")) + assert_equal(1, f:count_msg_type("error117")) assert_equal(0, u:get_item('rep_crossbow')) assert_equal(1, u:get_item('iron')) assert_equal(1, u:get_item('log')) From 7c680481de5f5a6d9d3fcdbb5443722788832ba0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 2 Apr 2017 15:43:14 +0200 Subject: [PATCH 123/218] iron golems can build dwarf armor in E3. --- res/e3a/armor/scale.xml | 1 + res/e3a/armor/towershield.xml | 1 + scripts/tests/e3/rules.lua | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/res/e3a/armor/scale.xml b/res/e3a/armor/scale.xml index c8c6804de..4d3e38e8a 100644 --- a/res/e3a/armor/scale.xml +++ b/res/e3a/armor/scale.xml @@ -1,6 +1,7 @@ + diff --git a/res/e3a/armor/towershield.xml b/res/e3a/armor/towershield.xml index 45958f175..aebbfc682 100644 --- a/res/e3a/armor/towershield.xml +++ b/res/e3a/armor/towershield.xml @@ -1,6 +1,7 @@ + diff --git a/scripts/tests/e3/rules.lua b/scripts/tests/e3/rules.lua index c01132b58..60adf77d1 100644 --- a/scripts/tests/e3/rules.lua +++ b/scripts/tests/e3/rules.lua @@ -824,8 +824,8 @@ function test_golem_use_four_iron() process_orders() - assert_equal(2, u1.number) assert_equal(4, u1:get_item("towershield")) + assert_equal(2, u1.number) end function test_silver_weight_stops_movement() From 50eb35edf6f67d635a06d8775fa49ac9fc6dd23f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 2 Apr 2017 15:50:29 +0200 Subject: [PATCH 124/218] unused variable --- cJSON | 2 +- iniparser | 2 +- src/economy.c | 2 -- storage | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cJSON b/cJSON index 22a4fc9be..43c04ad61 160000 --- a/cJSON +++ b/cJSON @@ -1 +1 @@ -Subproject commit 22a4fc9be31f0426e622f5bc9ebd7a1550845001 +Subproject commit 43c04ad61258ec3d54a2167eb3a43915bd003ab1 diff --git a/iniparser b/iniparser index 22741d9ce..ecf956b98 160000 --- a/iniparser +++ b/iniparser @@ -1 +1 @@ -Subproject commit 22741d9ce9d19bf7b5f5a219b6ed0925259a4d1b +Subproject commit ecf956b9808c28c2db52e6b73930f57876dbb258 diff --git a/src/economy.c b/src/economy.c index 69efe85cb..1ef9ca8c2 100644 --- a/src/economy.c +++ b/src/economy.c @@ -865,7 +865,6 @@ static struct message * get_modifiers(unit *u, skill_t sk, const resource_type * static void manufacture(unit * u, const item_type * itype, int want) { int n; - int skill; int minskill = itype->construction->minskill; skill_t sk = itype->construction->skill; message *msg; @@ -877,7 +876,6 @@ static void manufacture(unit * u, const item_type * itype, int want) return; } - skill = effskill(u, sk, 0); if (want == 0) { want = maxbuild(u, itype->construction); } diff --git a/storage b/storage index d807ef5ce..2117191d4 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit d807ef5ce64b3425b31fb440e0b93a4d233f517a +Subproject commit 2117191d4ad75e1eb14809878bc71d15b20a5d86 From d7f69dfa277803821739457875dd3360beb68957 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 2 Apr 2017 19:21:37 +0200 Subject: [PATCH 125/218] enum type clarification --- src/kernel/skills.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/kernel/skills.h b/src/kernel/skills.h index d294485cb..03b182bef 100644 --- a/src/kernel/skills.h +++ b/src/kernel/skills.h @@ -30,7 +30,7 @@ extern "C" { #define SMF_PRODUCTION (1<<1) /* fr Produktion - am gebude, an der einheit */ typedef struct skill { - int id; + skill_t id; int level; int weeks; int old; @@ -46,23 +46,25 @@ extern "C" { int bonus; int flags; } skillmod_data; + extern struct attrib_type at_skillmod; - extern int rc_skillmod(const struct race *rc, const struct region *r, + + int rc_skillmod(const struct race *rc, const struct region *r, skill_t sk); - extern int skillmod(const struct attrib *a, const struct unit *u, + int skillmod(const struct attrib *a, const struct unit *u, const struct region *r, skill_t sk, int value, int flags); - extern struct attrib *make_skillmod(skill_t sk, unsigned int flags, + struct attrib *make_skillmod(skill_t sk, unsigned int flags, skillmod_fun special, double multiplier, int bonus); - extern int level_days(int level); - extern int level(int days); + int level_days(int level); + int level(int days); #define skill_level(level) (level) - extern void reduce_skill(struct unit *u, skill * sv, unsigned int change); - extern int skill_weeks(int level); - extern int skill_compare(const skill * sk, const skill * sc); + void reduce_skill(struct unit *u, skill * sv, unsigned int change); + int skill_weeks(int level); + int skill_compare(const skill * sk, const skill * sc); - extern void sk_set(skill * sv, int level); + void sk_set(skill * sv, int level); #ifdef __cplusplus } From c6a8a76e313752b71764e8277fdc5a89e144fb37 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 2 Apr 2017 20:17:39 +0200 Subject: [PATCH 126/218] strip skillmod down to the essentials. --- iniparser | 2 +- src/kernel/skills.c | 10 +++------- src/kernel/skills.h | 14 +++----------- src/kernel/unit.c | 5 +++-- src/kernel/unit.test.c | 8 ++++---- src/spells/combatspells.c | 2 +- storage | 2 +- 7 files changed, 16 insertions(+), 27 deletions(-) diff --git a/iniparser b/iniparser index ecf956b98..22741d9ce 160000 --- a/iniparser +++ b/iniparser @@ -1 +1 @@ -Subproject commit ecf956b9808c28c2db52e6b73930f57876dbb258 +Subproject commit 22741d9ce9d19bf7b5f5a219b6ed0925259a4d1b diff --git a/src/kernel/skills.c b/src/kernel/skills.c index 488800115..b951b77ba 100644 --- a/src/kernel/skills.c +++ b/src/kernel/skills.c @@ -62,8 +62,7 @@ attrib_type at_skillmod = { ATF_PRESERVE }; -attrib *make_skillmod(skill_t sk, unsigned int flags, skillmod_fun special, - double multiplier, int bonus) +attrib *make_skillmod(skill_t sk, skillmod_fun special, double multiplier, int bonus) { attrib *a = a_new(&at_skillmod); skillmod_data *smd = (skillmod_data *)a->data.v; @@ -72,22 +71,19 @@ attrib *make_skillmod(skill_t sk, unsigned int flags, skillmod_fun special, smd->special = special; smd->bonus = bonus; smd->multiplier = multiplier; - smd->flags = flags; return a; } int -skillmod(const attrib * a, const unit * u, const region * r, skill_t sk, -int value, int flags) +skillmod(const unit * u, const region * r, skill_t sk, int value) { + const attrib * a = u->attribs; for (a = a_find((attrib *)a, &at_skillmod); a && a->type == &at_skillmod; a = a->next) { skillmod_data *smd = (skillmod_data *)a->data.v; if (smd->skill != NOSKILL && smd->skill != sk) continue; - if (flags != SMF_ALWAYS && (smd->flags & flags) == 0) - continue; if (smd->special) { value = smd->special(u, r, sk, value); if (value < 0) diff --git a/src/kernel/skills.h b/src/kernel/skills.h index 03b182bef..1261a7ea9 100644 --- a/src/kernel/skills.h +++ b/src/kernel/skills.h @@ -25,10 +25,6 @@ struct attrib_type; extern "C" { #endif - /* skillmod_data::flags -- wann gilt der modifier? */ -#define SMF_ALWAYS (1<<0) /* immer */ -#define SMF_PRODUCTION (1<<1) /* fr Produktion - am gebude, an der einheit */ - typedef struct skill { skill_t id; int level; @@ -44,17 +40,13 @@ extern "C" { double multiplier; int number; int bonus; - int flags; } skillmod_data; extern struct attrib_type at_skillmod; - int rc_skillmod(const struct race *rc, const struct region *r, - skill_t sk); - int skillmod(const struct attrib *a, const struct unit *u, - const struct region *r, skill_t sk, int value, int flags); - struct attrib *make_skillmod(skill_t sk, unsigned int flags, - skillmod_fun special, double multiplier, int bonus); + int rc_skillmod(const struct race *rc, const struct region *r, skill_t sk); + int skillmod(const struct unit *u, const struct region *r, skill_t sk, int value); + struct attrib *make_skillmod(skill_t sk, skillmod_fun special, double multiplier, int bonus); int level_days(int level); int level(int days); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 9dbfbfe0e..ab5f72f35 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1333,8 +1333,9 @@ int get_modifier(const unit * u, skill_t sk, int level, const region * r, bool n skill += rc_skillmod(u_race(u), r, sk); skill += att_modification(u, sk); - - skill = skillmod(u->attribs, u, r, sk, skill, SMF_ALWAYS); + if (u->attribs) { + skill = skillmod(u, r, sk, skill); + } if (fval(u, UFL_HUNGER)) { if (sk == SK_SAILING && skill > 2) { diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index caa8a9b5c..d8aaae6ec 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -256,19 +256,19 @@ static void test_skillmod(CuTest *tc) { set_level(u, SK_ARMORER, 5); CuAssertIntEquals(tc, 5, effskill(u, SK_ARMORER, 0)); - a_add(&u->attribs, a = make_skillmod(SK_ARMORER, SMF_ALWAYS, 0, 2.0, 0)); + a_add(&u->attribs, a = make_skillmod(SK_ARMORER, 0, 2.0, 0)); CuAssertIntEquals(tc, 10, effskill(u, SK_ARMORER, 0)); a_remove(&u->attribs, a); - a_add(&u->attribs, a = make_skillmod(NOSKILL, SMF_ALWAYS, 0, 2.0, 0)); /* NOSKILL means any skill */ + a_add(&u->attribs, a = make_skillmod(NOSKILL, 0, 2.0, 0)); /* NOSKILL means any skill */ CuAssertIntEquals(tc, 10, effskill(u, SK_ARMORER, 0)); a_remove(&u->attribs, a); - a_add(&u->attribs, a = make_skillmod(SK_ARMORER, SMF_ALWAYS, 0, 0, 2)); + a_add(&u->attribs, a = make_skillmod(SK_ARMORER, 0, 0, 2)); CuAssertIntEquals(tc, 7, effskill(u, SK_ARMORER, 0)); a_remove(&u->attribs, a); - a_add(&u->attribs, a = make_skillmod(SK_ARMORER, SMF_ALWAYS, cb_skillmod, 0, 0)); + a_add(&u->attribs, a = make_skillmod(SK_ARMORER, cb_skillmod, 0, 0)); CuAssertIntEquals(tc, 8, effskill(u, SK_ARMORER, 0)); a_remove(&u->attribs, a); diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c index 37191d177..8544a4a2d 100644 --- a/src/spells/combatspells.c +++ b/src/spells/combatspells.c @@ -556,7 +556,7 @@ int sp_mindblast_temp(struct castorder * co) skill_t sk = random_skill(du, true); if (sk != NOSKILL) { int n = 1 + rng_int() % maxloss; - attrib *a = make_skillmod(sk, SMF_ALWAYS, NULL, 0.0, n); + attrib *a = make_skillmod(sk, NULL, 0.0, n); /* neat: you can add a whole lot of these to a unit, they stack */ a_add(&du->attribs, a); } diff --git a/storage b/storage index 2117191d4..d807ef5ce 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit 2117191d4ad75e1eb14809878bc71d15b20a5d86 +Subproject commit d807ef5ce64b3425b31fb440e0b93a4d233f517a From 989ff65ca9c3407a9cd5670b2e51e166ba690ac4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 8 Apr 2017 22:07:12 +0200 Subject: [PATCH 127/218] BUG 2318: disable ponnuki --- scripts/eressea/e2/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/eressea/e2/init.lua b/scripts/eressea/e2/init.lua index 722078741..9407b2390 100644 --- a/scripts/eressea/e2/init.lua +++ b/scripts/eressea/e2/init.lua @@ -9,7 +9,7 @@ return { require('eressea.wedding'), require('eressea.embassy'), require('eressea.tunnels'), - require('eressea.ponnuki'), +-- require('eressea.ponnuki'), require('eressea.astral'), -- require('eressea.locales'), require('eressea.jsreport'), From aeeb13bb53becc7d1e25cd65ff1615dc782fbe01 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 9 Apr 2017 13:35:55 +0200 Subject: [PATCH 128/218] BUG 2318: Go, Ponnuki, Go! https://bugs.eressea.de/view.php?id=2318 --- scripts/eressea/ponnuki.lua | 23 ++++++++++++++++------- src/kernel/config.c | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/scripts/eressea/ponnuki.lua b/scripts/eressea/ponnuki.lua index 96bb0b5f1..29f882ab5 100644 --- a/scripts/eressea/ponnuki.lua +++ b/scripts/eressea/ponnuki.lua @@ -14,8 +14,10 @@ local function ponnuki_brain(u) u:add_notice("Eine Botschaft von " .. tostring(u) .. ": " ..jokes[i]) local d = math.random(6) local r = u.region:next(d-1) - u:clear_orders() - u:add_order("NACH " .. directions[d]) + if r.terrain == 'glacier' then + u:clear_orders() + u:add_order("NACH " .. directions[d]) + end end function ponnuki.init() @@ -26,11 +28,18 @@ function ponnuki.init() local home = get_region(-67, -5) local f = get_faction(666) if home and f then - u = unit.create(f, home, 1, "illusion") - u.id = atoi36("ponn") - u.name = "Ponnuki" - u.info = "Go, Ponnuki, Go!" - u:set_racename("Ritter von Go") + if home.terrain~="glacier" then + home.terrain="glacier" + home.name = 'Magrathea' + end + u = unit.create(f, home, 1, "template") + if u then + u.id = atoi36("ponn") + u.name = "Ponnuki" + u.info = "Go, Ponnuki, Go!" + u.race_name = "Ritter von Go" + print(u:show()) + end else eressea.log.error("Ponnuki cannot find Magrathea") end diff --git a/src/kernel/config.c b/src/kernel/config.c index 4b3ab5a91..1d005c9c1 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -121,7 +121,7 @@ const char *parameters[MAXPARAMS] = { "TEMP", "FLIEHE", "GEBAEUDE", - "GIB", /* F�r HELFE */ + "GIB", /* HELFE GIB */ "KAEMPFE", "DURCHREISE", "BEWACHE", From 0b226ba75e3d8c1b20b5d101d0dd734074c0916c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 10 Apr 2017 17:32:32 +0200 Subject: [PATCH 129/218] fix farsi names containing nzwj symbol. --- src/util/unicode.c | 5 +++-- src/util/unicode.test.c | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/util/unicode.c b/src/util/unicode.c index 161983ba7..10d43f947 100644 --- a/src/util/unicode.c +++ b/src/util/unicode.c @@ -57,7 +57,7 @@ int unicode_utf8_trim(utf8_t *buf) if (op == buf && iswspace(wc)) { ++result; } - else if (iswprint(wc)) { + else if (wc>255 || !iscntrl(wc)) { if (op != ip) { memmove(op, ip, size); } @@ -67,7 +67,8 @@ int unicode_utf8_trim(utf8_t *buf) lc = op; ts = 0; } - } else { + } + else { ++result; } ip += size; diff --git a/src/util/unicode.test.c b/src/util/unicode.test.c index 7c1c1031a..7cada9da6 100644 --- a/src/util/unicode.test.c +++ b/src/util/unicode.test.c @@ -123,6 +123,17 @@ static void test_unicode_compare(CuTest *tc) CuAssertIntEquals(tc, 1, unicode_utf8_strcasecmp("bacdefg123", "ABCDEFG123")); } +static void test_unicode_farsi_nzwj(CuTest *tc) { + const char str[] = { 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaf, + 0xdb, 0x8c, 0xd9, 0x86, 0x20, 0xd9, 0x85, 0xd8, 0xad, 0xd9, 0x85, 0xd8, + 0xaf, 0x20, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, + 0x8e, 0xe2, 0x80, 0x8e, 0x00 }; + char name[64]; + strcpy(name, str); + CuAssertIntEquals(tc, 0, unicode_utf8_trim(name)); + CuAssertStrEquals(tc, str, name); +} + CuSuite *get_unicode_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -132,5 +143,6 @@ CuSuite *get_unicode_suite(void) SUITE_ADD_TEST(suite, test_unicode_utf8_to_other); SUITE_ADD_TEST(suite, test_unicode_utf8_to_ucs); SUITE_ADD_TEST(suite, test_unicode_compare); + SUITE_ADD_TEST(suite, test_unicode_farsi_nzwj); return suite; } From 742fa423b3a05935d5c3531836c16d03201eb8bc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 16 Apr 2017 12:36:59 +0200 Subject: [PATCH 130/218] do not log an ERROR when a familiar as no equipment --- src/spells.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spells.c b/src/spells.c index fcee1b51b..10815708d 100644 --- a/src/spells.c +++ b/src/spells.c @@ -523,7 +523,7 @@ static void make_familiar(unit * familiar, unit * mage) equip_items(&familiar->items, eq); } else { - log_error("could not perform initialization for familiar %s.\n", rc->_name); + log_info("could not perform initialization for familiar %s.\n", rc->_name); } /* triggers: */ From 51c2df62caa1d272f11a3b40dccb0572a7174f3f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 16 Apr 2017 15:52:34 +0200 Subject: [PATCH 131/218] fixing new coverity scan defects 167039 Dereference after null check 167038 Unchecked return value --- src/kernel/region.c | 5 +++-- src/laws.c | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/kernel/region.c b/src/kernel/region.c index 2a54a2eaa..0e45c59bb 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -1505,6 +1505,7 @@ int owner_change(const region * r) bool is_mourning(const region * r, int in_turn) { int change = owner_change(r); - return (change == in_turn - 1 && r->land->ownership->last_owner && r->land->ownership->owner - && r->land->ownership->last_owner != r->land->ownership->owner); + return (change == in_turn - 1 && r->land && + r->land->ownership->last_owner && r->land->ownership->owner && + r->land->ownership->last_owner != r->land->ownership->owner); } diff --git a/src/laws.c b/src/laws.c index adf8b9f11..af96a309c 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1584,7 +1584,9 @@ int display_cmd(unit * u, struct order *ord) free(*s); if (s2) { char * str = strdup(s2); - unicode_utf8_trim(str); + if (unicode_utf8_trim(str) != 0) { + log_info("trimming info: %s", s2); + } if (strlen(str) >= DISPLAYSIZE) { str[DISPLAYSIZE-1] = 0; } @@ -1626,7 +1628,9 @@ static int rename_cmd(unit * u, order * ord, char **s, const char *s2) /* TODO: Validate to make sure people don't have illegal characters in * names, phishing-style? () come to mind. */ strlcpy(name, s2, sizeof(name)); - unicode_utf8_trim(name); + if (unicode_utf8_trim(name) != 0) { + log_info("trimming name: %s", s2); + } free(*s); *s = strdup(name); From b06e93db7a5cec57b440f04b3fbc3b1045ab8d40 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Apr 2017 16:50:15 +0200 Subject: [PATCH 132/218] BUG 2317: wyrms in E2 didn't move --- res/eressea/races.xml | 2 +- src/monsters.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/eressea/races.xml b/res/eressea/races.xml index 6deefacc9..986e2b85f 100644 --- a/res/eressea/races.xml +++ b/res/eressea/races.xml @@ -701,7 +701,7 @@ - + diff --git a/src/monsters.c b/src/monsters.c index 4edaeedea..21a3583af 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -738,7 +738,7 @@ void plan_monsters(faction * f) order *long_order = NULL; /* Ab hier nur noch Befehle fr NPC-Einheiten. */ - if (!is_monsters(u->faction)) + if (u->faction!=f) continue; /* Befehle mssen jede Runde neu gegeben werden: */ From 635ec6d6c6a631e05b7f18fff730207ebecc3d6e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Apr 2017 20:11:44 +0200 Subject: [PATCH 133/218] Fix a crash in TARNE this was complicated to test, and I had to rewrite how races and their names are registered by test_create_locale. --- src/kernel/config.c | 38 ++++++++++++++++++------------- src/kernel/config.h | 1 + src/kernel/race.c | 19 +++++++++++----- src/kernel/race.h | 6 +++-- src/kernel/unit.test.c | 39 +++++++++++++------------------- src/spy.c | 2 +- src/spy.test.c | 51 ++++++++++++++++++++++++++++++++++++------ src/tests.c | 15 +++++++++++-- 8 files changed, 114 insertions(+), 57 deletions(-) diff --git a/src/kernel/config.c b/src/kernel/config.c index 1d005c9c1..02ed9894d 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -365,13 +365,26 @@ void init_options_translation(const struct locale * lang) { } } -void init_locale(struct locale *lang) +void init_races(struct locale *lang) { - variant var; - int i; const struct race *rc; void **tokens; + tokens = get_translations(lang, UT_RACES); + for (rc = races; rc; rc = rc->next) { + const char *name; + variant var; + var.v = (void *)rc; + name = locale_string(lang, rc_name_s(rc, NAME_PLURAL), false); + if (name) addtoken((struct tnode **)tokens, name, var); + name = locale_string(lang, rc_name_s(rc, NAME_SINGULAR), false); + if (name) addtoken((struct tnode **)tokens, name, var); + } +} + +static void init_magic(struct locale *lang) +{ + void **tokens; tokens = get_translations(lang, UT_MAGIC); if (tokens) { const char *str = config_get("rules.magic.playerschools"); @@ -383,7 +396,9 @@ void init_locale(struct locale *lang) sstr = strdup(str); tok = strtok(sstr, " "); while (tok) { + variant var; const char *name; + int i; for (i = 0; i != MAXMAGIETYP; ++i) { if (strcmp(tok, magic_school[i]) == 0) break; } @@ -400,21 +415,14 @@ void init_locale(struct locale *lang) } free(sstr); } - +} +void init_locale(struct locale *lang) +{ + init_magic(lang); init_directions(lang); init_keywords(lang); init_skills(lang); - - tokens = get_translations(lang, UT_RACES); - for (rc = races; rc; rc = rc->next) { - const char *name; - var.v = (void *)rc; - name = locale_string(lang, rc_name_s(rc, NAME_PLURAL), false); - if (name) addtoken((struct tnode **)tokens, name, var); - name = locale_string(lang, rc_name_s(rc, NAME_SINGULAR), false); - if (name) addtoken((struct tnode **)tokens, name, var); - } - + init_races(lang); init_parameters(lang); init_options_translation(lang); diff --git a/src/kernel/config.h b/src/kernel/config.h index a4378332d..f80214fde 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -56,6 +56,7 @@ extern "C" { /* returns a value between [0..xpct_2], generated with two dice */ void init_locale(struct locale *lang); + void init_races(struct locale *lang); int forbiddenid(int id); int newcontainerid(void); diff --git a/src/kernel/race.c b/src/kernel/race.c index 8a8cc906e..a2c37d87d 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -65,7 +65,7 @@ race *races; int num_races = 0; static int rc_changes = 1; -static const char *racenames[MAXRACES] = { +const char *racenames[MAXRACES] = { "dwarf", "elf", NULL, "goblin", "human", "troll", "demon", "insect", "halfling", "cat", "aquarian", "orc", "snotling", "undead", NULL, "youngdragon", "dragon", "wyrm", "ent", "catdragon", "dracoid", @@ -168,6 +168,7 @@ const struct race *findrace(const char *s, const struct locale *lang) const struct race *get_race(race_t rt) { const char * name; + assert(rt >= 0); assert(rt < MAXRACES); name = racenames[rt]; if (!name) { @@ -484,11 +485,9 @@ void rc_set_param(struct race *rc, const char *key, const char *value) { } } -const char* rc_name(const race * rc, name_t n, char *name, size_t size) { +const char* rc_key(const char *rcname, name_t n, char *name, size_t size) +{ const char * postfix = 0; - if (!rc) { - return NULL; - } switch (n) { case NAME_SINGULAR: postfix = ""; break; case NAME_PLURAL: postfix = "_p"; break; @@ -497,12 +496,20 @@ const char* rc_name(const race * rc, name_t n, char *name, size_t size) { default: assert(!"invalid name_t enum in rc_name_s"); } if (postfix) { - snprintf(name, size, "race::%s%s", rc->_name, postfix); + snprintf(name, size, "race::%s%s", rcname, postfix); return name; } return NULL; } +const char* rc_name(const race * rc, name_t n, char *name, size_t size) +{ + if (!rc) { + return NULL; + } + return rc_key(rc->_name, n, name, size); +} + const char *rc_name_s(const race * rc, name_t n) { static char name[64]; /* FIXME: static return value */ diff --git a/src/kernel/race.h b/src/kernel/race.h index fcd78ae19..5c320ea05 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -50,8 +50,6 @@ extern "C" { struct rcoption; struct item_type; - extern int num_races; - typedef enum { RC_DWARF, /* 0 - Zwerg */ RC_ELF, @@ -103,6 +101,9 @@ extern "C" { NORACE = -1 } race_t; + extern int num_races; + extern const char *racenames[MAXRACES]; + typedef struct att { int type; union { @@ -180,6 +181,7 @@ extern "C" { typedef enum name_t { NAME_SINGULAR, NAME_PLURAL, NAME_DEFINITIVE, NAME_CATEGORY } name_t; const char * rc_name_s(const race *rc, name_t n); + const char * rc_key(const char *rcname, name_t n, char *name, size_t size); const char * rc_name(const race *rc, name_t n, char *name, size_t size); void rc_set_param(struct race *rc, const char *key, const char *value); diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index d8aaae6ec..23668fd5f 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -153,23 +153,18 @@ static void test_unit_name(CuTest *tc) { static void test_unit_name_from_race(CuTest *tc) { unit *u; - struct locale *lang; - test_cleanup(); - test_create_world(); - u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0)); + test_setup(); + u = test_create_unit(test_create_faction(test_create_race("human")), test_create_region(0, 0, NULL)); renumber_unit(u, 666); unit_setname(u, NULL); - lang = get_or_create_locale("de"); - locale_setstring(lang, rc_name_s(u->_race, NAME_SINGULAR), "Mensch"); - locale_setstring(lang, rc_name_s(u->_race, NAME_PLURAL), "Menschen"); - CuAssertStrEquals(tc, "Mensch (ii)", unitname(u)); - CuAssertStrEquals(tc, "Mensch", unit_getname(u)); + CuAssertStrEquals(tc, "human (ii)", unitname(u)); + CuAssertStrEquals(tc, "human", unit_getname(u)); u->number = 2; - CuAssertStrEquals(tc, "Menschen (ii)", unitname(u)); - CuAssertStrEquals(tc, "Menschen", unit_getname(u)); + CuAssertStrEquals(tc, "human_p (ii)", unitname(u)); + CuAssertStrEquals(tc, "human_p", unit_getname(u)); test_cleanup(); } @@ -177,18 +172,20 @@ static void test_unit_name_from_race(CuTest *tc) { static void test_update_monster_name(CuTest *tc) { unit *u; struct locale *lang; + race *rc; - test_cleanup(); - test_create_world(); - u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0)); - lang = get_or_create_locale("de"); - locale_setstring(lang, rc_name_s(u->_race, NAME_SINGULAR), "Mensch"); - locale_setstring(lang, rc_name_s(u->_race, NAME_PLURAL), "Menschen"); + test_setup(); + rc = test_create_race("human"); + lang = test_create_locale(); + u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); unit_setname(u, "Hodor"); CuAssertTrue(tc, !unit_name_equals_race(u)); - unit_setname(u, "Menschling"); + unit_setname(u, "humanitarian"); + CuAssertTrue(tc, !unit_name_equals_race(u)); + + unit_setname(u, "huma"); CuAssertTrue(tc, !unit_name_equals_race(u)); unit_setname(u, rc_name_s(u->_race, NAME_SINGULAR)); @@ -197,12 +194,6 @@ static void test_update_monster_name(CuTest *tc) { unit_setname(u, rc_name_s(u->_race, NAME_PLURAL)); CuAssertTrue(tc, unit_name_equals_race(u)); - unit_setname(u, "Mensch"); - CuAssertTrue(tc, unit_name_equals_race(u)); - - unit_setname(u, "Menschen"); - CuAssertTrue(tc, unit_name_equals_race(u)); - test_cleanup(); } diff --git a/src/spy.c b/src/spy.c index 08662ea8e..10f467ad9 100644 --- a/src/spy.c +++ b/src/spy.c @@ -255,7 +255,7 @@ int setstealth_cmd(unit * u, struct order *ord) for (i = 0; allowed[i] != NORACE; ++i) if (get_race(allowed[i]) == trace) break; - if (get_race(allowed[i]) == trace) { + if (allowed[i]!=NORACE && get_race(allowed[i]) == trace) { u->irace = trace; if (u_race(u)->flags & RCF_SHAPESHIFTANY && get_racename(u->attribs)) set_racename(&u->attribs, NULL); diff --git a/src/spy.test.c b/src/spy.test.c index 190cb09a5..11c8c1ff1 100644 --- a/src/spy.test.c +++ b/src/spy.test.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -130,21 +131,55 @@ static void test_sabotage_other_fail(CuTest *tc) { static void test_setstealth_cmd(CuTest *tc) { unit *u; const struct locale *lang; - + test_setup(); - u = test_create_unit(test_create_faction(0), test_create_region(0,0,0)); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); lang = u->faction->locale; - u->flags = UFL_ANON_FACTION|UFL_SIEGE; + u->flags = UFL_ANON_FACTION | UFL_SIEGE; u->thisorder = create_order(K_SETSTEALTH, lang, "%s %s", - LOC(lang, parameters[P_FACTION]), - LOC(lang, parameters[P_NOT])); + LOC(lang, parameters[P_FACTION]), + LOC(lang, parameters[P_NOT])); setstealth_cmd(u, u->thisorder); CuAssertIntEquals(tc, UFL_SIEGE, u->flags); free_order(u->thisorder); u->thisorder = create_order(K_SETSTEALTH, lang, "%s", - LOC(lang, parameters[P_FACTION])); + LOC(lang, parameters[P_FACTION])); setstealth_cmd(u, u->thisorder); - CuAssertIntEquals(tc, UFL_SIEGE|UFL_ANON_FACTION, u->flags); + CuAssertIntEquals(tc, UFL_SIEGE | UFL_ANON_FACTION, u->flags); + test_cleanup(); +} + +static void test_setstealth_demon(CuTest *tc) { + unit *u; + struct locale *lang; + struct race *rc; + + test_setup(); + lang = test_create_locale(); + rc = test_create_race("demon"); + u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); + rc = test_create_race("dwarf"); + init_races(lang); + u->thisorder = create_order(K_SETSTEALTH, lang, racename(lang, u, rc)); + setstealth_cmd(u, u->thisorder); + CuAssertPtrEquals(tc, (void *)rc, (void *)u->irace); + test_cleanup(); +} + +static void test_setstealth_demon_bad(CuTest *tc) { + unit *u; + struct locale *lang; + struct race *rc; + + test_setup(); + lang = test_create_locale(); + rc = test_create_race("demon"); + u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); + rc = test_create_race("smurf"); + init_races(lang); + u->thisorder = create_order(K_SETSTEALTH, lang, racename(lang, u, rc)); + setstealth_cmd(u, u->thisorder); + CuAssertPtrEquals(tc, NULL, (void *)u->irace); test_cleanup(); } @@ -180,6 +215,8 @@ CuSuite *get_spy_suite(void) SUITE_ADD_TEST(suite, test_all_spy_message); SUITE_ADD_TEST(suite, test_sabotage_self); SUITE_ADD_TEST(suite, test_setstealth_cmd); + SUITE_ADD_TEST(suite, test_setstealth_demon); + SUITE_ADD_TEST(suite, test_setstealth_demon_bad); SUITE_ADD_TEST(suite, test_sabotage_other_fail); SUITE_ADD_TEST(suite, test_sabotage_other_success); return suite; diff --git a/src/tests.c b/src/tests.c index faa8f6e2e..a9b4878b6 100644 --- a/src/tests.c +++ b/src/tests.c @@ -96,8 +96,19 @@ struct locale * test_create_locale(void) { locale_setstring(loc, "stone_p", "Steine"); locale_setstring(loc, "plain", "Ebene"); locale_setstring(loc, "ocean", "Ozean"); - locale_setstring(loc, "race::human", "Mensch"); - locale_setstring(loc, "race::human_p", "Menschen"); + for (i = 0; i < MAXRACES; ++i) { + if (racenames[i]) { + char name[64]; + rc_key(racenames[i], NAME_PLURAL, name, sizeof(name)); + if (!locale_getstring(loc, name)) { + locale_setstring(loc, name, name + 6); + } + rc_key(racenames[i], NAME_SINGULAR, name, sizeof(name)); + if (!locale_getstring(loc, name)) { + locale_setstring(loc, name, name + 6); + } + } + } for (i = 0; i < MAXSKILLS; ++i) { if (!locale_getstring(loc, mkname("skill", skillnames[i]))) locale_setstring(loc, mkname("skill", skillnames[i]), skillnames[i]); From 9fcab4ccb82a4e33c52e02c42f1a6aa0e1d1b8dc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Apr 2017 20:18:37 +0200 Subject: [PATCH 134/218] do not hard-code list of allowed races for demons. --- src/spy.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/spy.c b/src/spy.c index 10f467ad9..391313aa3 100644 --- a/src/spy.c +++ b/src/spy.c @@ -247,15 +247,7 @@ int setstealth_cmd(unit * u, struct order *ord) if (trace) { /* demons can cloak as other player-races */ if (u_race(u) == get_race(RC_DAEMON)) { - race_t allowed[] = { RC_DWARF, RC_ELF, RC_ORC, RC_GOBLIN, RC_HUMAN, - RC_TROLL, RC_DAEMON, RC_INSECT, RC_HALFLING, RC_CAT, RC_AQUARIAN, - NORACE - }; - int i; - for (i = 0; allowed[i] != NORACE; ++i) - if (get_race(allowed[i]) == trace) - break; - if (allowed[i]!=NORACE && get_race(allowed[i]) == trace) { + if (playerrace(trace)) { u->irace = trace; if (u_race(u)->flags & RCF_SHAPESHIFTANY && get_racename(u->attribs)) set_racename(&u->attribs, NULL); From 055fdceff9a7c1fa8a6c5795e28621f4f220ca35 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Apr 2017 20:44:55 +0200 Subject: [PATCH 135/218] fix gcc build --- src/kernel/unit.test.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 23668fd5f..096da9d62 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -171,12 +171,10 @@ static void test_unit_name_from_race(CuTest *tc) { static void test_update_monster_name(CuTest *tc) { unit *u; - struct locale *lang; race *rc; test_setup(); rc = test_create_race("human"); - lang = test_create_locale(); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); unit_setname(u, "Hodor"); From 91fc9f9a1ecb37b777fc657b11388ba634f2fb1c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 22 Apr 2017 13:52:45 +0200 Subject: [PATCH 136/218] enable ponnuki --- scripts/eressea/e2/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/eressea/e2/init.lua b/scripts/eressea/e2/init.lua index 9407b2390..722078741 100644 --- a/scripts/eressea/e2/init.lua +++ b/scripts/eressea/e2/init.lua @@ -9,7 +9,7 @@ return { require('eressea.wedding'), require('eressea.embassy'), require('eressea.tunnels'), --- require('eressea.ponnuki'), + require('eressea.ponnuki'), require('eressea.astral'), -- require('eressea.locales'), require('eressea.jsreport'), From bda395d374d009613df666d4d0794567c21a3c26 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 22 Apr 2017 18:57:57 +0200 Subject: [PATCH 137/218] shell wants ==, not = for string compares? --- s/build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/s/build b/s/build index 818cb0268..b3db6d11b 100755 --- a/s/build +++ b/s/build @@ -33,8 +33,9 @@ fi echo "build eressea" cd $ROOT/$BUILD BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//') -if [ "$BRANCH" = "master" ] ; then +if [ "$BRANCH"=="master" ] ; then VERSION=$(git describe --match 'v*.*.*' --tags | sed 's/^v//') +echo "master $VERSION" cmake -DERESSEA_VERSION="$VERSION" .. else REV=$(git rev-parse --short HEAD) From 1eb189cf47cc1e327a7c82596264d046cd7d6396 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 22 Apr 2017 18:57:57 +0200 Subject: [PATCH 138/218] shell wants spaces around = for string compares? --- s/build | 1 + 1 file changed, 1 insertion(+) diff --git a/s/build b/s/build index 818cb0268..e47ecf903 100755 --- a/s/build +++ b/s/build @@ -35,6 +35,7 @@ cd $ROOT/$BUILD BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//') if [ "$BRANCH" = "master" ] ; then VERSION=$(git describe --match 'v*.*.*' --tags | sed 's/^v//') +echo "$BRANCH $VERSION" cmake -DERESSEA_VERSION="$VERSION" .. else REV=$(git rev-parse --short HEAD) From 7f9c85384a68be8954d9357d66d6b4b3cf239e80 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 22 Apr 2017 19:06:38 +0200 Subject: [PATCH 139/218] build script madness, again --- s/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s/build b/s/build index f019c98d5..e47ecf903 100755 --- a/s/build +++ b/s/build @@ -33,7 +33,7 @@ fi echo "build eressea" cd $ROOT/$BUILD BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//') -if [ "$BRANCH"=="master" ] ; then +if [ "$BRANCH" = "master" ] ; then VERSION=$(git describe --match 'v*.*.*' --tags | sed 's/^v//') echo "$BRANCH $VERSION" cmake -DERESSEA_VERSION="$VERSION" .. From 1cd8a5323248abd27f219198f68b70a895ce9b04 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 22 Apr 2017 19:07:47 +0200 Subject: [PATCH 140/218] whitespace framing equals --- s/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s/build b/s/build index f019c98d5..e47ecf903 100755 --- a/s/build +++ b/s/build @@ -33,7 +33,7 @@ fi echo "build eressea" cd $ROOT/$BUILD BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//') -if [ "$BRANCH"=="master" ] ; then +if [ "$BRANCH" = "master" ] ; then VERSION=$(git describe --match 'v*.*.*' --tags | sed 's/^v//') echo "$BRANCH $VERSION" cmake -DERESSEA_VERSION="$VERSION" .. From 45f8f73ede7ae90183d0757a78487ff59fd1236c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 23 Apr 2017 16:13:28 +0200 Subject: [PATCH 141/218] broaden valgrind suppression for strtold --- share/debian-7_8.supp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/share/debian-7_8.supp b/share/debian-7_8.supp index 99eefafa4..f6fabe6e7 100644 --- a/share/debian-7_8.supp +++ b/share/debian-7_8.supp @@ -50,11 +50,4 @@ obj:/usr/lib/x86_64-linux-gnu/liblua5.2.so.0.0.0 obj:/usr/lib/x86_64-linux-gnu/liblua5.2.so.0.0.0 fun:lua_isnumber - fun:class_index_event - obj:/usr/lib/x86_64-linux-gnu/liblua5.2.so.0.0.0 - obj:/usr/lib/x86_64-linux-gnu/liblua5.2.so.0.0.0 - obj:/usr/lib/x86_64-linux-gnu/liblua5.2.so.0.0.0 - obj:/usr/lib/x86_64-linux-gnu/liblua5.2.so.0.0.0 - obj:/usr/lib/x86_64-linux-gnu/liblua5.2.so.0.0.0 - obj:/usr/lib/x86_64-linux-gnu/liblua5.2.so.0.0.0 } From 8b02c540fd1fbc25caaa09058d380282d0ff68f4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 25 Apr 2017 13:27:13 +0200 Subject: [PATCH 142/218] re-enable accidentally disabled tests --- scripts/tests/e3/init.lua | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/scripts/tests/e3/init.lua b/scripts/tests/e3/init.lua index 7206c80c4..6094d0a25 100644 --- a/scripts/tests/e3/init.lua +++ b/scripts/tests/e3/init.lua @@ -1,15 +1,15 @@ --- require 'tests.e3.castles' --- require 'tests.e3.stealth' --- require 'tests.e3.spells' +require 'tests.e3.castles' +require 'tests.e3.stealth' +require 'tests.e3.spells' require 'tests.e3.rules' --- require 'tests.e3.parser' --- require 'tests.e3.morale' --- require 'tests.e3.items' --- require 'tests.economy' --- require 'tests.orders' --- require 'tests.common' --- require 'tests.items' --- require 'tests.magicbag' --- require 'tests.process' --- require 'tests.e3.production' --- require 'tests.production' +require 'tests.e3.parser' +require 'tests.e3.morale' +require 'tests.e3.items' +require 'tests.economy' +require 'tests.orders' +require 'tests.common' +require 'tests.items' +require 'tests.magicbag' +require 'tests.process' +require 'tests.e3.production' +require 'tests.production' From f2d839220679b4a191aefa263f4388ef240c8a57 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 25 Apr 2017 16:47:26 +0200 Subject: [PATCH 143/218] add tests for correct castle stage names. --- scripts/tests/e2/buildings.lua | 53 +++++++++++++++++++ scripts/tests/e2/init.lua | 1 + .../tests/e3/{castles.lua => buildings.lua} | 21 +++++++- scripts/tests/e3/init.lua | 2 +- 4 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 scripts/tests/e2/buildings.lua rename scripts/tests/e3/{castles.lua => buildings.lua} (80%) diff --git a/scripts/tests/e2/buildings.lua b/scripts/tests/e2/buildings.lua new file mode 100644 index 000000000..4797643e1 --- /dev/null +++ b/scripts/tests/e2/buildings.lua @@ -0,0 +1,53 @@ +require "lunit" + +module("tests.e2.buildings", package.seeall, lunit.testcase ) + +function setup() + eressea.game.reset() + eressea.settings.set("rules.food.flags", "4") +end + +function teardown() + eressea.settings.set("rules.food.flags", "0") +end + +function test_castle_names() + local r = region.create(0, 0, "plain") + local b = building.create(r, "castle") + + assert_equal("site", b:get_typename(1)) + assert_equal("tradepost", b:get_typename(2)) + assert_equal("tradepost", b:get_typename(9)) + assert_equal("fortification", b:get_typename(10)) + assert_equal("fortification", b:get_typename(49)) + assert_equal("tower", b:get_typename(50)) + assert_equal("tower", b:get_typename(249)) + assert_equal("castle", b:get_typename(250)) + assert_equal("castle", b:get_typename(1249)) + assert_equal("fortress", b:get_typename(1250)) + assert_equal("fortress", b:get_typename(6249)) + assert_equal("citadel", b:get_typename(6250)) +end + +function test_build_castle_stages() + local r = region.create(0,0, "plain") + local f = faction.create("human") + local u = unit.create(f, r, 1000) + local b = building.create(r, "castle") + + u:add_item("stone", 1000) + + u:set_skill("building", 1) + u:clear_orders() + + u:add_order("MACHE BURG " .. itoa36(b.id)) + process_orders() + assert_equal(10, b.size) + + u:set_skill("building", 3) + u:clear_orders() + + u:add_order("MACHE BURG " .. itoa36(b.id)) + process_orders() + assert_equal(250, b.size) +end diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index 705fd5013..46afc966a 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -1,3 +1,4 @@ +require 'tests.e2.buildings' require 'tests.e2.production' require 'tests.e2.adamantium' require 'tests.e2.undead' diff --git a/scripts/tests/e3/castles.lua b/scripts/tests/e3/buildings.lua similarity index 80% rename from scripts/tests/e3/castles.lua rename to scripts/tests/e3/buildings.lua index c5641c68e..709e7df74 100644 --- a/scripts/tests/e3/castles.lua +++ b/scripts/tests/e3/buildings.lua @@ -1,6 +1,6 @@ require "lunit" -module("tests.e3.castles", package.seeall, lunit.testcase ) +module("tests.e3.buildings", package.seeall, lunit.testcase ) function setup() eressea.game.reset() @@ -11,6 +11,23 @@ function teardown() eressea.settings.set("rules.food.flags", "0") end +function test_castle_names() + local r = region.create(0, 0, "plain") + local b = building.create(r, "castle") + + assert_equal("site", b:get_typename(1)) + assert_equal("site", b:get_typename(9)) + assert_equal("fortification", b:get_typename(10)) + assert_equal("fortification", b:get_typename(49)) + assert_equal("tower", b:get_typename(50)) + assert_equal("tower", b:get_typename(249)) + assert_equal("castle", b:get_typename(250)) + assert_equal("castle", b:get_typename(1249)) + assert_equal("fortress", b:get_typename(1250)) + assert_equal("fortress", b:get_typename(6249)) + assert_equal("citadel", b:get_typename(6250)) +end + function test_build_watch() local r = region.create(0, 0, "plain") local f = faction.create("human", "e3build@eressea.de", "de") @@ -33,7 +50,7 @@ function test_build_watch() assert_equal(10, u.building.size) end -function test_watch() +function test_watch_names() local r = region.create(0, 0, "plain") local b = building.create(r, "watch") diff --git a/scripts/tests/e3/init.lua b/scripts/tests/e3/init.lua index 6094d0a25..06e03d9b4 100644 --- a/scripts/tests/e3/init.lua +++ b/scripts/tests/e3/init.lua @@ -1,4 +1,4 @@ -require 'tests.e3.castles' +require 'tests.e3.buildings' require 'tests.e3.stealth' require 'tests.e3.spells' require 'tests.e3.rules' From a313e78de5d8a44b11c6825621ad3411d3a8f7a1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Apr 2017 21:44:24 +0200 Subject: [PATCH 144/218] move building names from function to construction data. --- res/buildings/castle-2.xml | 13 ++--- res/buildings/castle.xml | 15 +++-- res/e3a/buildings.xml | 7 +-- src/economy.c | 4 +- src/eressea.c | 1 - src/kernel/build.c | 52 +++++++++--------- src/kernel/build.h | 16 +++++- src/kernel/build.test.c | 3 +- src/kernel/building.c | 110 +++++++++++++------------------------ src/kernel/building.h | 1 - src/kernel/xmlreader.c | 26 ++++++--- 11 files changed, 115 insertions(+), 133 deletions(-) diff --git a/res/buildings/castle-2.xml b/res/buildings/castle-2.xml index 7b015d199..989832940 100644 --- a/res/buildings/castle-2.xml +++ b/res/buildings/castle-2.xml @@ -1,23 +1,22 @@ - - + - + - + - + - + - + diff --git a/res/buildings/castle.xml b/res/buildings/castle.xml index 6e9140222..78ce7066c 100644 --- a/res/buildings/castle.xml +++ b/res/buildings/castle.xml @@ -1,25 +1,24 @@ - - + - + - + - + - + - + - + diff --git a/res/e3a/buildings.xml b/res/e3a/buildings.xml index 9eeca952f..27b94dbbe 100644 --- a/res/e3a/buildings.xml +++ b/res/e3a/buildings.xml @@ -4,15 +4,14 @@ - - + - + - + diff --git a/src/economy.c b/src/economy.c index 1ef9ca8c2..87e31b97c 100644 --- a/src/economy.c +++ b/src/economy.c @@ -888,7 +888,7 @@ static void manufacture(unit * u, const item_type * itype, int want) case EBUILDINGREQ: ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "building_needed", "building", - itype->construction->btype->_name)); + itype->construction->extra.btype->_name)); return; case ELOWSKILL: ADDMSG(&u->faction->msgs, @@ -1239,7 +1239,7 @@ static void create_potion(unit * u, const potion_type * ptype, int want) case EBUILDINGREQ: ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "building_needed", "building", - ptype->itype->construction->btype->_name)); + ptype->itype->construction->extra.btype->_name)); break; case ECOMPLETE: assert(0); diff --git a/src/eressea.c b/src/eressea.c index 2d53c2511..a9dddd130 100755 --- a/src/eressea.c +++ b/src/eressea.c @@ -70,7 +70,6 @@ void game_init(void) register_spells(); register_names(); register_resources(); - register_buildings(); register_itemfunctions(); #if MUSEUM_MODULE register_museum(); diff --git a/src/kernel/build.c b/src/kernel/build.c index a8125d1a8..36d72b109 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -502,20 +502,20 @@ static int count_materials(unit *u, const construction *type, int n, int complet */ int build(unit * u, const construction * ctype, int completed, int want, int skill_mod) { - const construction *type = ctype; + const construction *con = ctype; int skills = INT_MAX; /* number of skill points remainig */ int basesk = 0; int made = 0; if (want <= 0) return 0; - if (type == NULL) + if (con == NULL) return ENOMATERIALS; - if (type->improvement == NULL && completed == type->maxsize) + if (con->improvement == NULL && completed == con->maxsize) return ECOMPLETE; - if (type->btype != NULL) { + if (con->type==CONS_ITEM && con->extra.btype) { building *b; - if (!u->building || u->building->type != type->btype) { + if (!u->building || u->building->type != con->extra.btype) { return EBUILDINGREQ; } b = inside_building(u); @@ -524,12 +524,12 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski } } - if (type->skill != NOSKILL) { + if (con->skill != NOSKILL) { int effsk; int dm = get_effect(u, oldpotiontype[P_DOMORE]); assert(u->number); - basesk = effskill(u, type->skill, 0); + basesk = effskill(u, con->skill, 0); if (basesk == 0) return ENEEDSKILL; @@ -557,13 +557,13 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski * type->improvement==type means build another object of the same time * while material lasts type->improvement==x means build x when type * is finished */ - while (type && type->improvement && - type->improvement != type && - type->maxsize > 0 && type->maxsize <= completed) { - completed -= type->maxsize; - type = type->improvement; + while (con && con->improvement && + con->improvement != con && + con->maxsize > 0 && con->maxsize <= completed) { + completed -= con->maxsize; + con = con->improvement; } - if (type == NULL) { + if (con == NULL) { if (made == 0) return ECOMPLETE; break; /* completed */ @@ -574,15 +574,15 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski * (enno): Nein, das ist f�r Dinge, bei denen die n�chste Ausbaustufe * die gleiche wie die vorherige ist. z.b. gegenst�nde. */ - if (type->maxsize > 0) { - completed = completed % type->maxsize; + if (con->maxsize > 0) { + completed = completed % con->maxsize; } else { completed = 0; - assert(type->reqsize >= 1); + assert(con->reqsize >= 1); } - if (basesk < type->minskill) { + if (basesk < con->minskill) { if (made == 0) return ELOWSKILL; else @@ -590,15 +590,15 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski } /* n = maximum buildable size */ - if (type->minskill > 1) { - n = skills / type->minskill; + if (con->minskill > 1) { + n = skills / con->minskill; } else { n = skills; } /* Flinkfingerring wirkt nicht auf Mengenbegrenzte (magische) * Talente */ - if (skill_limit(u->faction, type->skill) == INT_MAX) { + if (skill_limit(u->faction, con->skill) == INT_MAX) { const resource_type *ring = get_resourcetype(R_RING_OF_NIMBLEFINGER); item *itm = ring ? *i_find(&u->items, ring->itype) : 0; int i = itm ? itm->number : 0; @@ -610,26 +610,26 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski if (want < n) n = want; - if (type->maxsize > 0) { - n = MIN(type->maxsize - completed, n); - if (type->improvement == NULL) { + if (con->maxsize > 0) { + n = MIN(con->maxsize - completed, n); + if (con->improvement == NULL) { want = n; } } - n = count_materials(u, type, n, completed); + n = count_materials(u, con, n, completed); if (n <= 0) { if (made == 0) return ENOMATERIALS; else break; } - err = use_materials(u, type, n, completed); + err = use_materials(u, con, n, completed); if (err < 0) { return err; } made += n; - skills -= n * type->minskill; + skills -= n * con->minskill; want -= n; completed = completed + n; } diff --git a/src/kernel/build.h b/src/kernel/build.h index bb1204af9..323003efd 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -37,15 +37,27 @@ extern "C" { int number; } requirement; + typedef enum construct_t { + CONS_OTHER, + CONS_ITEM, + CONS_BUILDING + } construct_t; + typedef struct construction { + construct_t type; skill_t skill; /* skill req'd per point of size */ int minskill; /* skill req'd per point of size */ int maxsize; /* maximum size of this type */ int reqsize; /* size of object using up 1 set of requirement. */ requirement *materials; /* material req'd to build one object */ - const struct building_type *btype; - /* building type required to make this thing */ + + union { + /* CONS_BUILDING: */ + char * name; /* building level name */ + /* CONS_ITEM: */ + const struct building_type *btype; /* building required to build item */ + } extra; struct construction *improvement; /* next level, if upgradable. if more than one of these items diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c index 34f645856..c3fa07e65 100644 --- a/src/kernel/build.test.c +++ b/src/kernel/build.test.c @@ -81,7 +81,8 @@ static void test_build_requires_building(CuTest *tc) { rtype = bf.cons.materials[0].rtype; i_change(&u->items, rtype->itype, 1); set_level(u, SK_ARMORER, 2); - bf.cons.btype = btype = bt_get_or_create("hodor"); + bf.cons.type = CONS_ITEM; + bf.cons.extra.btype = btype = bt_get_or_create("hodor"); btype->maxcapacity = 1; btype->capacity = 1; CuAssertIntEquals_Msg(tc, "must be inside a production building", EBUILDINGREQ, build(u, &bf.cons, 0, 1, 0)); diff --git a/src/kernel/building.c b/src/kernel/building.c index 3eef32cc4..40f09a6ad 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -157,27 +157,52 @@ attrib_type at_building_generic_type = { ATF_UNIQUE }; +/* TECH DEBT: simplest thing that works for E3 dwarf/halfling faction rules */ +static int adjust_size(const building *b, int bsize) { + assert(b); + if (config_get_int("rules.dwarf_castles", 0) + && strcmp(b->type->_name, "castle") == 0) { + unit *u = building_owner(b); + if (u && u->faction->race == get_race(RC_HALFLING)) { + return bsize * 5 / 4; + } + } + return bsize; +} + /* Returns the (internal) name for a building of given size and type. Especially, returns the correct * name if it depends on the size (as for Eressea castles). */ const char *buildingtype(const building_type * btype, const building * b, int bsize) { - const char *s; + const construction *con; + assert(btype); - s = btype->_name; - if (btype->name) { - s = btype->name(btype, b, bsize); - } if (b && b->attribs) { if (is_building_type(btype, "generic")) { const attrib *a = a_find(b->attribs, &at_building_generic_type); if (a) { - s = (const char *)a->data.v; + return (const char *)a->data.v; } } } - return s; + if (btype->name) { + return btype->name(btype, b, bsize); + } + if (btype->construction->extra.name) { + if (b) { + assert(b->type == btype); + bsize = adjust_size(b, bsize); + } + for (con = btype->construction; con; con = con->improvement) { + bsize -= con->maxsize; + if (!con->improvement || bsize <0) { + return con->extra.name; + } + } + } + return btype->_name; } #define BMAXHASH 7919 @@ -219,55 +244,6 @@ building *findbuilding(int i) { return bfindhash(i); } - -static const char *castle_name_i(const struct building_type *btype, - const struct building *b, int bsize, const char *fname[]) -{ - int i = bt_effsize(btype, b, bsize); - - return fname[i]; -} - -static const char *castle_name_2(const struct building_type *btype, - const struct building *b, int bsize) -{ - const char *fname[] = { - "site", - "fortification", - "tower", - "castle", - "fortress", - "citadel" - }; - return castle_name_i(btype, b, bsize, fname); -} - -static const char *castle_name(const struct building_type *btype, - const struct building *b, int bsize) -{ - const char *fname[] = { - "site", - "tradepost", - "fortification", - "tower", - "castle", - "fortress", - "citadel" - }; - return castle_name_i(btype, b, bsize, fname); -} - -static const char *fort_name(const struct building_type *btype, - const struct building *b, int bsize) -{ - const char *fname[] = { - "scaffolding", - "guardhouse", - "guardtower", - }; - return castle_name_i(btype, b, bsize, fname); -} - /* for finding out what was meant by a particular building string */ static local_names *bnames; @@ -486,24 +462,19 @@ int buildingeffsize(const building * b, int img) int bt_effsize(const building_type * btype, const building * b, int bsize) { - int i = bsize, n = 0; + int n = 0; const construction *cons = btype->construction; - /* TECH DEBT: simplest thing that works for E3 dwarf/halfling faction rules */ - if (b && config_get_int("rules.dwarf_castles", 0) - && strcmp(btype->_name, "castle") == 0) { - unit *u = building_owner(b); - if (u && u->faction->race == get_race(RC_HALFLING)) { - i = bsize * 10 / 8; - } + if (b) { + bsize = adjust_size(b, bsize); } if (!cons || !cons->improvement) { return 0; } - while (cons && cons->maxsize != -1 && i >= cons->maxsize) { - i -= cons->maxsize; + while (cons && cons->maxsize != -1 && bsize >= cons->maxsize) { + bsize -= cons->maxsize; cons = cons->improvement; ++n; } @@ -883,10 +854,3 @@ int cmp_current_owner(const building * b, const building * a) } return -1; } - -void register_buildings(void) -{ - register_function((pf_generic)castle_name, "castle_name"); - register_function((pf_generic)castle_name_2, "castle_name_2"); - register_function((pf_generic)fort_name, "fort_name"); -} diff --git a/src/kernel/building.h b/src/kernel/building.h index f9803cdbf..f7c0c1cdc 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -84,7 +84,6 @@ extern "C" { bool bt_changed(int *cache); const building_type *bt_find(const char *name); void free_buildingtypes(void); - void register_buildings(void); void bt_register(struct building_type *type); int bt_effsize(const struct building_type *btype, const struct building *b, int bsize); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 603231deb..9f2b2fc51 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -214,7 +214,7 @@ xml_readrequirements(xmlNodePtr * nodeTab, int nodeNr, requirement ** reqArray) void xml_readconstruction(xmlXPathContextPtr xpath, xmlNodeSetPtr nodeSet, -construction ** consPtr) +construction ** consPtr, construct_t type) { xmlNodePtr pushNode = xpath->node; int k; @@ -241,15 +241,25 @@ construction ** consPtr) *consPtr = con = (construction *)calloc(sizeof(construction), 1); consPtr = &con->improvement; + con->type = type; con->skill = sk; con->maxsize = xml_ivalue(node, "maxsize", -1); con->minskill = xml_ivalue(node, "minskill", -1); con->reqsize = xml_ivalue(node, "reqsize", 1); - propValue = xmlGetProp(node, BAD_CAST "building"); - if (propValue != NULL) { - con->btype = bt_get_or_create((const char *)propValue); - xmlFree(propValue); + if (type == CONS_ITEM) { + propValue = xmlGetProp(node, BAD_CAST "building"); + if (propValue != NULL) { + con->extra.btype = bt_get_or_create((const char *)propValue); + xmlFree(propValue); + } + } + else if (type == CONS_BUILDING) { + propValue = xmlGetProp(node, BAD_CAST "name"); + if (propValue != NULL) { + con->extra.name = strdup((const char *)propValue); + xmlFree(propValue); + } } /* read construction/requirement */ @@ -337,7 +347,7 @@ static int parse_buildings(xmlDocPtr doc) /* reading eressea/buildings/building/construction */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); - xml_readconstruction(xpath, result->nodesetval, &btype->construction); + xml_readconstruction(xpath, result->nodesetval, &btype->construction, CONS_BUILDING); xmlXPathFreeObject(result); /* reading eressea/buildings/building/function */ @@ -572,7 +582,7 @@ static int parse_ships(xmlDocPtr doc) /* reading eressea/ships/ship/construction */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); - xml_readconstruction(xpath, result->nodesetval, &st->construction); + xml_readconstruction(xpath, result->nodesetval, &st->construction, CONS_OTHER); xmlXPathFreeObject(result); for (child = node->children; child; child = child->next) { @@ -858,7 +868,7 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) /* reading item/construction */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); - xml_readconstruction(xpath, result->nodesetval, &itype->construction); + xml_readconstruction(xpath, result->nodesetval, &itype->construction, CONS_ITEM); xmlXPathFreeObject(result); /* reading item/weapon */ From 16267c447e56a1b1c6c0d1c1fb4c0c9d0fab8d37 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 27 Apr 2017 19:08:10 +0200 Subject: [PATCH 145/218] extract taxes into separate function (WIP) --- src/kernel/building.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 40f09a6ad..262836f3a 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -784,6 +784,16 @@ bool is_owner_building(const struct building * b) return false; } +double building_taxes(const building *b, int bsize) { + assert(b); + if (!b->type->taxes) return 0; + else { + int level = buildingeffsize(b, false); + return b->type->taxes(b, level); + } +} + + int cmp_taxes(const building * b, const building * a) { faction *f = region_get_owner(b->region); @@ -793,10 +803,8 @@ int cmp_taxes(const building * b, const building * a) return -1; } else if (a) { - int newsize = buildingeffsize(b, false); - double newtaxes = b->type->taxes(b, newsize); - int oldsize = buildingeffsize(a, false); - double oldtaxes = a->type->taxes(a, oldsize); + double newtaxes = building_taxes(b, b->size); + double oldtaxes = building_taxes(a, a->size); if (newtaxes < oldtaxes) return -1; From 1112890293f5275243e24d01a406f13ce3a6d36f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 28 Apr 2017 20:10:20 +0200 Subject: [PATCH 146/218] use building_taxes everywhere. make it return an integer, not double. --- src/economy.c | 4 ++-- src/kernel/building.c | 28 +++++++++++++--------------- src/kernel/building.h | 3 ++- src/kernel/region.h | 2 +- src/morale.c | 2 +- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/economy.c b/src/economy.c index 87e31b97c..63d47cebe 100644 --- a/src/economy.c +++ b/src/economy.c @@ -2949,8 +2949,8 @@ static void peasant_taxes(region * r) maxsize = buildingeffsize(b, false); if (maxsize > 0) { - double taxfactor = money * b->type->taxes(b, maxsize); - double morale = MORALE_TAX_FACTOR * money * region_get_morale(r); + double taxfactor = money / building_taxes(b, maxsize); + double morale = money * region_get_morale(r) / MORALE_TAX_FACTOR; if (taxfactor > morale) { taxfactor = morale; } diff --git a/src/kernel/building.c b/src/kernel/building.c index 262836f3a..ffaab81cb 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -784,12 +784,12 @@ bool is_owner_building(const struct building * b) return false; } -double building_taxes(const building *b, int bsize) { +int building_taxes(const building *b, int bsize) { assert(b); if (!b->type->taxes) return 0; else { int level = buildingeffsize(b, false); - return b->type->taxes(b, level); + return (int)(0.5+1/b->type->taxes(b, level)); } } @@ -803,12 +803,12 @@ int cmp_taxes(const building * b, const building * a) return -1; } else if (a) { - double newtaxes = building_taxes(b, b->size); - double oldtaxes = building_taxes(a, a->size); + int newtaxes = building_taxes(b, b->size); + int oldtaxes = building_taxes(a, a->size); - if (newtaxes < oldtaxes) + if (newtaxes > oldtaxes) return -1; - else if (newtaxes > oldtaxes) + else if (newtaxes < oldtaxes) return 1; else if (b->size < a->size) return -1; @@ -840,20 +840,18 @@ int cmp_current_owner(const building * b, const building * a) if (!u || u->faction != f) return -1; if (a) { - int newsize = buildingeffsize(b, false); - double newtaxes = b->type->taxes(b, newsize); - int oldsize = buildingeffsize(a, false); - double oldtaxes = a->type->taxes(a, oldsize); + int newtaxes = building_taxes(b, b->size); + int oldtaxes = building_taxes(a, a->size); - if (newtaxes > oldtaxes) { + if (newtaxes < oldtaxes) { return 1; } - if (newtaxes < oldtaxes) { + if (newtaxes > oldtaxes) { return -1; } - if (newsize != oldsize) { - return newsize - oldsize; - } + //if (newsize != oldsize) { + // return newsize - oldsize; + //} return (b->size - a->size); } else { diff --git a/src/kernel/building.h b/src/kernel/building.h index f7c0c1cdc..6414011bf 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -71,7 +71,7 @@ extern "C" { const char *(*name) (const struct building_type *, const struct building * b, int size); void(*age) (struct building *); - double(*taxes) (const struct building *, int size); + double(*taxes) (const struct building *, int level); struct attrib *attribs; } building_type; @@ -139,6 +139,7 @@ extern "C" { int cmp_taxes(const struct building *b, const struct building *bother); int cmp_current_owner(const struct building *b, const struct building *bother); + int building_taxes(const building *b, int bsize); /* old functions, still in build.c: */ int buildingeffsize(const building * b, int imaginary); diff --git a/src/kernel/region.h b/src/kernel/region.h index 9fa1a2daa..75c9a76db 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -66,7 +66,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. struct faction; struct gamedata; -#define MORALE_TAX_FACTOR 0.005 /* 0.5% tax per point of morale */ +#define MORALE_TAX_FACTOR 200 /* 0.5% tax per point of morale, 1 silver per 200 */ #define MORALE_MAX 10 /* Maximum morale allowed */ #define MORALE_DEFAULT 1 /* Morale of peasants when they are conquered for the first time */ #define MORALE_TAKEOVER 0 /* Morale of peasants after they lose their lord */ diff --git a/src/morale.c b/src/morale.c index 67108333e..1f0edc837 100644 --- a/src/morale.c +++ b/src/morale.c @@ -46,7 +46,7 @@ void morale_update(region *r) { building *b = largestbuilding(r, &cmp_taxes, false); if (b) { int bsize = buildingeffsize(b, false); - maxmorale = (int)(0.5 + b->type->taxes(b, bsize + 1) / MORALE_TAX_FACTOR); + maxmorale = (int)(0.5 + b->type->taxes(b, bsize + 1) * MORALE_TAX_FACTOR); } if (morale < maxmorale) { if (stability > MORALE_COOLDOWN && r->land->ownership->owner From bdc7457a08adb9627e097cf1446175fc314cf587 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 28 Apr 2017 21:29:42 +0200 Subject: [PATCH 147/218] additional testing for largestbuilding and comparisons. --- src/economy.c | 2 +- src/guard.c | 2 +- src/kernel/building.c | 35 +++++++----- src/kernel/building.test.c | 110 +++++++++++++++++++++++++++++++++++-- src/kernel/region.c | 4 +- src/morale.c | 2 +- 6 files changed, 132 insertions(+), 23 deletions(-) diff --git a/src/economy.c b/src/economy.c index 63d47cebe..9f9a6815e 100644 --- a/src/economy.c +++ b/src/economy.c @@ -575,7 +575,7 @@ void give_control(unit * u, unit * u2) assert(u->building == u2->building); if (f == u->faction) { - building *b = largestbuilding(r, &cmp_current_owner, false); + building *b = largestbuilding(r, cmp_current_owner, false); if (b == u->building) { friendly_takeover(r, u2->faction); } diff --git a/src/guard.c b/src/guard.c index 55f189b6c..118ede5fc 100644 --- a/src/guard.c +++ b/src/guard.c @@ -112,7 +112,7 @@ static bool is_guardian_r(const unit * guard) if (guard->building && rule_region_owners() && guard == building_owner(guard->building)) { faction *owner = region_get_owner(guard->region); if (owner == guard->faction) { - building *bowner = largestbuilding(guard->region, &cmp_taxes, false); + building *bowner = largestbuilding(guard->region, cmp_taxes, false); if (bowner == guard->building) { return true; } diff --git a/src/kernel/building.c b/src/kernel/building.c index ffaab81cb..77718e2ea 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -523,10 +523,10 @@ static unit *building_owner_ex(const building * bld, const struct faction * last } if (!heir && config_token("rules.region_owner_pay_building", bld->type->_name)) { if (rule_region_owners()) { - u = building_owner(largestbuilding(bld->region, &cmp_taxes, false)); + u = building_owner(largestbuilding(bld->region, cmp_taxes, false)); } else { - u = building_owner(largestbuilding(bld->region, &cmp_wage, false)); + u = building_owner(largestbuilding(bld->region, cmp_wage, false)); } if (u) { heir = u; @@ -643,9 +643,12 @@ bool is_building_type(const struct building_type *btype, const char *name) { building *largestbuilding(const region * r, cmp_building_cb cmp_gt, bool imaginary) { - building *b, *best = NULL; + building *b, *best = r->buildings; - for (b = rbuildings(r); b; b = b->next) { + if (!best) { + return NULL; + } + for (b = best->next; b; b = b->next) { if (cmp_gt(b, best) <= 0) continue; if (!imaginary) { @@ -673,7 +676,7 @@ static const int wagetable[7][4] = { static int default_wage(const region * r, const faction * f, const race * rc, int in_turn) { - building *b = largestbuilding(r, &cmp_wage, false); + building *b = largestbuilding(r, cmp_wage, false); int esize = 0; double wage; static int ct_cache; @@ -786,11 +789,14 @@ bool is_owner_building(const struct building * b) int building_taxes(const building *b, int bsize) { assert(b); - if (!b->type->taxes) return 0; - else { + if (b->type->taxes) { int level = buildingeffsize(b, false); - return (int)(0.5+1/b->type->taxes(b, level)); + double tax = b->type->taxes(b, level); + if (tax > 0) { + return (int)(0.5 + 1 / tax); + } } + return 0; } @@ -817,8 +823,9 @@ int cmp_taxes(const building * b, const building * a) else { if (u && u->faction == f) { u = building_owner(a); - if (u && u->faction == f) - return -1; + if (u && u->faction == f) { + return 0; + } return 1; } } @@ -827,7 +834,7 @@ int cmp_taxes(const building * b, const building * a) return 1; } } - return -1; + return 0; } int cmp_current_owner(const building * b, const building * a) @@ -843,10 +850,10 @@ int cmp_current_owner(const building * b, const building * a) int newtaxes = building_taxes(b, b->size); int oldtaxes = building_taxes(a, a->size); - if (newtaxes < oldtaxes) { + if (newtaxes > oldtaxes) { return 1; } - if (newtaxes > oldtaxes) { + if (newtaxes < oldtaxes) { return -1; } //if (newsize != oldsize) { @@ -858,5 +865,5 @@ int cmp_current_owner(const building * b, const building * a) return 1; } } - return -1; + return 0; } diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index 0296e3451..233212026 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -427,10 +427,86 @@ static void test_cmp_castle_size(CuTest *tc) { u_set_building(u2, b2); b1->size = 5; b2->size = 10; - CuAssertTrue(tc, cmp_castle_size(b1, b2)<0); - CuAssertTrue(tc, cmp_castle_size(b2, b1)>0); - CuAssertTrue(tc, cmp_castle_size(b1, NULL)>0); - CuAssertTrue(tc, cmp_castle_size(NULL, b1)<0); + CuAssertTrue(tc, cmp_castle_size(b1, b2) < 0); + CuAssertTrue(tc, cmp_castle_size(b2, b1) > 0); + CuAssertTrue(tc, cmp_castle_size(b1, b1) == 0); + test_cleanup(); +} + +static double tax_cb(const building *b, int level) { + UNUSED_ARG(level); + return b->size * 0.01; +} + +static void test_cmp_wage(CuTest *tc) { + region *r; + building *b1, *b2; + building_type *btype; + + test_setup(); + btype = test_create_buildingtype("castle"); + btype->taxes = tax_cb; + r = test_create_region(0, 0, 0); + b1 = test_create_building(r, btype); + b2 = test_create_building(r, btype); + b1->size = 5; + b2->size = 10; + CuAssertPtrEquals(tc, b2, largestbuilding(r, cmp_wage, false)); + CuAssertTrue(tc, cmp_wage(b1, b2) < 0); + CuAssertTrue(tc, cmp_wage(b2, b1) > 0); + CuAssertTrue(tc, cmp_wage(b1, b1) == 0); + test_cleanup(); +} + +static void test_cmp_taxes(CuTest *tc) { + region *r; + building *b1, *b2; + building_type *btype; + unit *u1, *u2; + + test_setup(); + btype = test_create_buildingtype("castle"); + btype->taxes = tax_cb; + r = test_create_region(0, 0, 0); + b1 = test_create_building(r, btype); + b2 = test_create_building(r, btype); + b1->size = 5; + b2->size = 10; + u1 = test_create_unit(test_create_faction(0), r); + u_set_building(u1, b1); + u2 = test_create_unit(test_create_faction(0), r); + u_set_building(u2, b2); + CuAssertPtrEquals(tc, b2, largestbuilding(r, cmp_taxes, false)); + CuAssertTrue(tc, cmp_taxes(b1, b2) < 0); + CuAssertTrue(tc, cmp_taxes(b2, b1) > 0); + CuAssertTrue(tc, cmp_taxes(b1, b1) == 0); + test_cleanup(); +} + +static void test_cmp_current_owner(CuTest *tc) { + region *r; + building *b1, *b2; + building_type *btype; + unit *u1, *u2; + + test_setup(); + config_set("rules.region_owners", "1"); + btype = test_create_buildingtype("castle"); + btype->taxes = tax_cb; + r = test_create_region(0, 0, 0); + b1 = test_create_building(r, btype); + b2 = test_create_building(r, btype); + b1->size = 5; + b2->size = 10; + u1 = test_create_unit(test_create_faction(0), r); + u_set_building(u1, b1); + u2 = test_create_unit(test_create_faction(0), r); + u_set_building(u2, b2); + region_set_owner(r, u1->faction, turn); + CuAssertPtrEquals(tc, b1, largestbuilding(r, cmp_current_owner, false)); + CuAssertTrue(tc, cmp_current_owner(b2, b1) < 0); + CuAssertTrue(tc, cmp_current_owner(b1, b2) > 0); + CuAssertTrue(tc, cmp_current_owner(b1, b1) == 0); test_cleanup(); } @@ -459,10 +535,36 @@ static void test_building_effsize(CuTest *tc) { test_cleanup(); } +static int cmp_size(const building *lhs, const building *rhs) { + return lhs->size - rhs->size; +} + +static void test_largestbuilding(CuTest *tc) { + region *r; + building *b1, *b2; + test_setup(); + r = test_create_region(0, 0, NULL); + CuAssertPtrEquals(tc, NULL, largestbuilding(r, cmp_size, false)); + b1 = test_create_building(r, NULL); + b2 = test_create_building(r, NULL); + b1->size = 1; + b2->size = 1; + CuAssertPtrEquals(tc, b1, largestbuilding(r, cmp_size, false)); + b1->size = 2; + CuAssertPtrEquals(tc, b1, largestbuilding(r, cmp_size, false)); + b2->size = 3; + CuAssertPtrEquals(tc, b2, largestbuilding(r, cmp_size, false)); + test_cleanup(); +} + CuSuite *get_building_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_largestbuilding); SUITE_ADD_TEST(suite, test_cmp_castle_size); + SUITE_ADD_TEST(suite, test_cmp_taxes); + SUITE_ADD_TEST(suite, test_cmp_wage); + SUITE_ADD_TEST(suite, test_cmp_current_owner); SUITE_ADD_TEST(suite, test_register_building); SUITE_ADD_TEST(suite, test_btype_defaults); SUITE_ADD_TEST(suite, test_building_set_owner); diff --git a/src/kernel/region.c b/src/kernel/region.c index 0e45c59bb..492d6e438 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -1398,8 +1398,8 @@ faction *update_owners(region * r) faction *f = NULL; assert(rule_region_owners()); if (r->land) { - building *bowner = largestbuilding(r, &cmp_current_owner, false); - building *blargest = largestbuilding(r, &cmp_taxes, false); + building *bowner = largestbuilding(r, cmp_current_owner, false); + building *blargest = largestbuilding(r, cmp_taxes, false); if (blargest) { if (!bowner || bowner->size < blargest->size) { /* region owners update? */ diff --git a/src/morale.c b/src/morale.c index 1f0edc837..47476fdf8 100644 --- a/src/morale.c +++ b/src/morale.c @@ -43,7 +43,7 @@ void morale_update(region *r) { if (r->land->ownership && r->land->ownership->owner) { int stability = turn - r->land->ownership->morale_turn; int maxmorale = MORALE_DEFAULT; - building *b = largestbuilding(r, &cmp_taxes, false); + building *b = largestbuilding(r, cmp_taxes, false); if (b) { int bsize = buildingeffsize(b, false); maxmorale = (int)(0.5 + b->type->taxes(b, bsize + 1) * MORALE_TAX_FACTOR); From dee10e8d0d883f05f0806f60acc3518d387a2a0e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 28 Apr 2017 21:58:27 +0200 Subject: [PATCH 148/218] remove suspicious disabled code --- src/kernel/building.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 77718e2ea..15ef34416 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -856,9 +856,6 @@ int cmp_current_owner(const building * b, const building * a) if (newtaxes < oldtaxes) { return -1; } - //if (newsize != oldsize) { - // return newsize - oldsize; - //} return (b->size - a->size); } else { From 3f8de76b9d20a178cd08fd89d155c1c2feea05fb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Apr 2017 13:37:34 +0200 Subject: [PATCH 149/218] fix largestbuilding, broken in prev commit. --- src/kernel/building.c | 7 ++----- src/kernel/building.test.c | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 77718e2ea..90bfced16 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -643,12 +643,9 @@ bool is_building_type(const struct building_type *btype, const char *name) { building *largestbuilding(const region * r, cmp_building_cb cmp_gt, bool imaginary) { - building *b, *best = r->buildings; + building *b, *best = NULL; - if (!best) { - return NULL; - } - for (b = best->next; b; b = b->next) { + for (b = r->buildings; b; b = b->next) { if (cmp_gt(b, best) <= 0) continue; if (!imaginary) { diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index 233212026..bbe8447b5 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -536,7 +536,8 @@ static void test_building_effsize(CuTest *tc) { } static int cmp_size(const building *lhs, const building *rhs) { - return lhs->size - rhs->size; + assert(lhs); + return rhs ? lhs->size - rhs->size : 1; } static void test_largestbuilding(CuTest *tc) { From 3b9a6e45a1a9790dda3fa49402b8e57d53df7823 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Apr 2017 13:53:28 +0200 Subject: [PATCH 150/218] turns out: btype->age is never used. --- src/kernel/building.h | 1 - src/kernel/building.test.c | 1 - src/kernel/xmlreader.c | 3 --- src/laws.c | 4 ---- 4 files changed, 9 deletions(-) diff --git a/src/kernel/building.h b/src/kernel/building.h index 6414011bf..fd4c38ee7 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -70,7 +70,6 @@ extern "C" { const char *(*name) (const struct building_type *, const struct building * b, int size); - void(*age) (struct building *); double(*taxes) (const struct building *, int level); struct attrib *attribs; } building_type; diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index bbe8447b5..5cee76813 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -296,7 +296,6 @@ static void test_btype_defaults(CuTest *tc) { CuAssertPtrEquals(tc, 0, btype->maintenance); CuAssertPtrEquals(tc, 0, btype->construction); CuAssertTrue(tc, !btype->name); - CuAssertTrue(tc, !btype->age); CuAssertTrue(tc, !btype->taxes); CuAssertDblEquals(tc, 1.0, btype->auraregen, 0.0); CuAssertIntEquals(tc, -1, btype->maxsize); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 9f2b2fc51..8d4c51176 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -369,9 +369,6 @@ static int parse_buildings(xmlDocPtr doc) (const char *(*)(const struct building_type *, const struct building *, int))fun; } - else if (strcmp((const char *)propValue, "age") == 0) { - btype->age = (void(*)(struct building *))fun; - } else if (strcmp((const char *)propValue, "taxes") == 0) { btype->taxes = (double(*)(const struct building *, int))fun; } diff --git a/src/laws.c b/src/laws.c index af96a309c..3ab17f1ab 100644 --- a/src/laws.c +++ b/src/laws.c @@ -2883,10 +2883,6 @@ static building *age_building(building * b) a_age(&b->attribs, b); handle_event(b->attribs, "timer", b); - if (b->type->age) { - b->type->age(b); - } - return b; } From 7a289ceb860df735b953856cd4ee6db70a53fe9b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Apr 2017 19:21:48 +0200 Subject: [PATCH 151/218] simplify building_taxes, eliminate dead lua callbacks. --- res/buildings/castle-2.xml | 3 +- res/e3a/buildings.xml | 3 +- scripts/eressea/e3/rules.lua | 10 ------- src/economy.c | 8 +++--- src/helpers.c | 56 ------------------------------------ src/kernel/building.c | 21 +++++--------- src/kernel/building.h | 4 +-- src/kernel/building.test.c | 23 ++++++++------- src/kernel/xmlreader.c | 4 +-- src/laws.test.c | 6 +--- src/morale.c | 3 +- 11 files changed, 31 insertions(+), 110 deletions(-) diff --git a/res/buildings/castle-2.xml b/res/buildings/castle-2.xml index 989832940..7e64f88af 100644 --- a/res/buildings/castle-2.xml +++ b/res/buildings/castle-2.xml @@ -1,6 +1,5 @@ - - + diff --git a/res/e3a/buildings.xml b/res/e3a/buildings.xml index 27b94dbbe..8641fd89e 100644 --- a/res/e3a/buildings.xml +++ b/res/e3a/buildings.xml @@ -3,8 +3,7 @@ - - + diff --git a/scripts/eressea/e3/rules.lua b/scripts/eressea/e3/rules.lua index e7a54ff41..e49e03438 100644 --- a/scripts/eressea/e3/rules.lua +++ b/scripts/eressea/e3/rules.lua @@ -1,13 +1,3 @@ -function building_taxes(b, blevel) - btype = b.type - if btype=="castle" then - return blevel * 0.01 - elseif btype=="watch" then - return blevel * 0.005 - end - return 0.0 -end - -- the "raindance" spell function raindance(r, mage, level, force) if (create_curse(mage, r, "blessedharvest", force, 1+force*2, 100 * force)) then diff --git a/src/economy.c b/src/economy.c index 9f9a6815e..1a4cc5b18 100644 --- a/src/economy.c +++ b/src/economy.c @@ -2929,7 +2929,7 @@ static void peasant_taxes(region * r) unit *u; building *b; int money; - int maxsize; + int level; f = region_get_owner(r); if (f == NULL || is_mourning(r, turn)) { @@ -2947,9 +2947,9 @@ static void peasant_taxes(region * r) if (u == NULL || u->faction != f) return; - maxsize = buildingeffsize(b, false); - if (maxsize > 0) { - double taxfactor = money / building_taxes(b, maxsize); + level = buildingeffsize(b, false); + if (level > 0) { + double taxfactor = money * level / building_taxes(b); double morale = money * region_get_morale(r) / MORALE_TAX_FACTOR; if (taxfactor > morale) { taxfactor = morale; diff --git a/src/helpers.c b/src/helpers.c index 402ecdd48..59695e9b4 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -352,58 +352,6 @@ lua_wage(const region * r, const faction * f, const race * rc, int in_turn) return result; } -static void lua_agebuilding(building * b) -{ - lua_State *L = (lua_State *)global.vm_state; - char fname[64]; - - strlcpy(fname, "age_", sizeof(fname)); - strlcat(fname, b->type->_name, sizeof(fname)); - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, (void *)b, TOLUA_CAST "building"); - - if (lua_pcall(L, 1, 0, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("agebuilding(%s) calling '%s': %s.\n", buildingname(b), fname, error); - lua_pop(L, 1); - } - } - else { - log_error("agebuilding(%s) calling '%s': not a function.\n", buildingname(b), fname); - lua_pop(L, 1); - } -} - -static double lua_building_taxes(building * b, int level) -{ - lua_State *L = (lua_State *)global.vm_state; - const char *fname = "building_taxes"; - double result = 0.0F; - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, (void *)b, TOLUA_CAST "building"); - lua_pushinteger(L, level); - - if (lua_pcall(L, 2, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("building_taxes(%s) calling '%s': %s.\n", buildingname(b), fname, error); - lua_pop(L, 1); - } - else { - result = (double)lua_tonumber(L, -1); - lua_pop(L, 1); - } - } - else { - log_error("building_taxes(%s) calling '%s': not a function.\n", buildingname(b), fname); - lua_pop(L, 1); - } - return result; -} - static int lua_maintenance(const unit * u) { lua_State *L = (lua_State *)global.vm_state; @@ -526,10 +474,6 @@ void register_tolua_helpers(void) at_register(&at_direction); at_register(&at_building_action); - register_function((pf_generic)lua_building_taxes, - TOLUA_CAST "lua_building_taxes"); - register_function((pf_generic)lua_agebuilding, - TOLUA_CAST "lua_agebuilding"); register_function((pf_generic)lua_callspell, TOLUA_CAST "lua_castspell"); register_function((pf_generic)lua_initfamiliar, TOLUA_CAST "lua_initfamiliar"); diff --git a/src/kernel/building.c b/src/kernel/building.c index 2cbd8e74d..2107551de 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -469,7 +469,7 @@ int bt_effsize(const building_type * btype, const building * b, int bsize) bsize = adjust_size(b, bsize); } - if (!cons || !cons->improvement) { + if (!cons) { return 0; } @@ -784,16 +784,9 @@ bool is_owner_building(const struct building * b) return false; } -int building_taxes(const building *b, int bsize) { +int building_taxes(const building *b) { assert(b); - if (b->type->taxes) { - int level = buildingeffsize(b, false); - double tax = b->type->taxes(b, level); - if (tax > 0) { - return (int)(0.5 + 1 / tax); - } - } - return 0; + return b->type->taxes; } @@ -806,8 +799,8 @@ int cmp_taxes(const building * b, const building * a) return -1; } else if (a) { - int newtaxes = building_taxes(b, b->size); - int oldtaxes = building_taxes(a, a->size); + int newtaxes = building_taxes(b); + int oldtaxes = building_taxes(a); if (newtaxes > oldtaxes) return -1; @@ -844,8 +837,8 @@ int cmp_current_owner(const building * b, const building * a) if (!u || u->faction != f) return -1; if (a) { - int newtaxes = building_taxes(b, b->size); - int oldtaxes = building_taxes(a, a->size); + int newtaxes = building_taxes(b); + int oldtaxes = building_taxes(a); if (newtaxes > oldtaxes) { return 1; diff --git a/src/kernel/building.h b/src/kernel/building.h index fd4c38ee7..edb46edfd 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -63,6 +63,7 @@ extern "C" { variant magres; /* how well it resists against spells */ int magresbonus; /* bonus it gives the target against spells */ int fumblebonus; /* bonus that reduces fumbling */ + int taxes; /* receive $1 tax per `taxes` in region */ double auraregen; /* modifier for aura regeneration inside building */ struct maintenance *maintenance; /* array of requirements */ struct construction *construction; /* construction of 1 building-level */ @@ -70,7 +71,6 @@ extern "C" { const char *(*name) (const struct building_type *, const struct building * b, int size); - double(*taxes) (const struct building *, int level); struct attrib *attribs; } building_type; @@ -138,7 +138,7 @@ extern "C" { int cmp_taxes(const struct building *b, const struct building *bother); int cmp_current_owner(const struct building *b, const struct building *bother); - int building_taxes(const building *b, int bsize); + int building_taxes(const building *b); /* old functions, still in build.c: */ int buildingeffsize(const building * b, int imaginary); diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index 5cee76813..2b546cd79 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -432,11 +432,6 @@ static void test_cmp_castle_size(CuTest *tc) { test_cleanup(); } -static double tax_cb(const building *b, int level) { - UNUSED_ARG(level); - return b->size * 0.01; -} - static void test_cmp_wage(CuTest *tc) { region *r; building *b1, *b2; @@ -444,7 +439,7 @@ static void test_cmp_wage(CuTest *tc) { test_setup(); btype = test_create_buildingtype("castle"); - btype->taxes = tax_cb; + btype->taxes = 100; r = test_create_region(0, 0, 0); b1 = test_create_building(r, btype); b2 = test_create_building(r, btype); @@ -465,7 +460,7 @@ static void test_cmp_taxes(CuTest *tc) { test_setup(); btype = test_create_buildingtype("castle"); - btype->taxes = tax_cb; + btype->taxes = 100; r = test_create_region(0, 0, 0); b1 = test_create_building(r, btype); b2 = test_create_building(r, btype); @@ -490,13 +485,19 @@ static void test_cmp_current_owner(CuTest *tc) { test_setup(); config_set("rules.region_owners", "1"); - btype = test_create_buildingtype("castle"); - btype->taxes = tax_cb; r = test_create_region(0, 0, 0); + btype = test_create_buildingtype("watch"); + btype->construction->maxsize = 1; + btype->taxes = 200; b1 = test_create_building(r, btype); + btype = test_create_buildingtype("castle"); + btype->construction->maxsize = 1; + btype->taxes = 100; b2 = test_create_building(r, btype); - b1->size = 5; - b2->size = 10; + b1->size = 1; + CuAssertIntEquals(tc, 1, buildingeffsize(b1, false)); + b2->size = 1; + CuAssertIntEquals(tc, 1, buildingeffsize(b2, false)); u1 = test_create_unit(test_create_faction(0), r); u_set_building(u1, b1); u2 = test_create_unit(test_create_faction(0), r); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 8d4c51176..e29f2811c 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -320,6 +320,7 @@ static int parse_buildings(xmlDocPtr doc) btype->magresbonus = xml_ivalue(node, "magresbonus", btype->magresbonus); btype->fumblebonus = xml_ivalue(node, "fumblebonus", btype->fumblebonus); btype->auraregen = xml_fvalue(node, "auraregen", btype->auraregen); + btype->taxes = xml_ivalue(node, "taxes", btype->taxes); if (xml_bvalue(node, "nodestroy", false)) btype->flags |= BTF_INDESTRUCTIBLE; @@ -369,9 +370,6 @@ static int parse_buildings(xmlDocPtr doc) (const char *(*)(const struct building_type *, const struct building *, int))fun; } - else if (strcmp((const char *)propValue, "taxes") == 0) { - btype->taxes = (double(*)(const struct building *, int))fun; - } else { log_error("unknown function type '%s' for building %s\n", (const char *)propValue, btype->_name); } diff --git a/src/laws.test.c b/src/laws.test.c index ce8ca2c19..36aafb4cb 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -525,10 +525,6 @@ struct pay_fixture { unit *u2; }; -static double level_taxes(const building * b, int level) { - return b->size * level * 2.0; -} - static void setup_pay_cmd(struct pay_fixture *fix) { faction *f; region *r; @@ -540,7 +536,7 @@ static void setup_pay_cmd(struct pay_fixture *fix) { r = findregion(0, 0); assert(r && f); btcastle = test_create_buildingtype("castle"); - btcastle->taxes = level_taxes; + btcastle->taxes = 100; b = test_create_building(r, btcastle); assert(b); fix->u1 = test_create_unit(f, r); diff --git a/src/morale.c b/src/morale.c index 47476fdf8..8b0a8c6ee 100644 --- a/src/morale.c +++ b/src/morale.c @@ -46,7 +46,8 @@ void morale_update(region *r) { building *b = largestbuilding(r, cmp_taxes, false); if (b) { int bsize = buildingeffsize(b, false); - maxmorale = (int)(0.5 + b->type->taxes(b, bsize + 1) * MORALE_TAX_FACTOR); + assert(b->type->taxes>0); + maxmorale = (bsize + 1) * MORALE_TAX_FACTOR / b->type->taxes; } if (morale < maxmorale) { if (stability > MORALE_COOLDOWN && r->land->ownership->owner From 931e705b0586118991bbd237f6ab61d218a8f69a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Apr 2017 20:37:02 +0200 Subject: [PATCH 152/218] delete unused functions --- src/magic.c | 32 -------------------------------- src/magic.h | 4 ---- 2 files changed, 36 deletions(-) diff --git a/src/magic.c b/src/magic.c index de1336d66..005f0ff94 100644 --- a/src/magic.c +++ b/src/magic.c @@ -231,26 +231,6 @@ bool FactionSpells(void) return rule != 0; } -void read_spells(struct selist **slistp, magic_t mtype, - struct storage *store) -{ - for (;;) { - spell *sp; - char spname[64]; - - READ_TOK(store, spname, sizeof(spname)); - if (strcmp(spname, "end") == 0) - break; - sp = find_spell(spname); - if (!sp) { - log_error("read_spells: could not find spell '%s' in school '%s'\n", spname, magic_school[mtype]); - } - if (sp) { - add_spell(slistp, sp); - } - } -} - int get_spell_level_mage(const spell * sp, void * cbdata) { sc_mage *mage = (sc_mage *)cbdata; @@ -305,18 +285,6 @@ static int read_mage(attrib * a, void *owner, struct gamedata *data) return AT_READ_OK; } -void write_spells(struct selist *slist, struct storage *store) -{ - selist *ql; - int qi; - - for (ql = slist, qi = 0; ql; selist_advance(&ql, &qi, 1)) { - spell *sp = (spell *)selist_get(ql, qi); - WRITE_TOK(store, sp->sname); - } - WRITE_TOK(store, "end"); -} - static void write_mage(const attrib * a, const void *owner, struct storage *store) { diff --git a/src/magic.h b/src/magic.h index 37fe33eae..8bf209c95 100644 --- a/src/magic.h +++ b/src/magic.h @@ -349,10 +349,6 @@ extern "C" { struct order *ord, const struct spllprm *spobj); bool FactionSpells(void); - void write_spells(struct selist *slist, struct storage *store); - void read_spells(struct selist **slistp, magic_t mtype, - struct storage *store); - struct spellbook * get_spellbook(const char * name); void free_spellbooks(void); void free_spellbook(struct spellbook *sb); From 6f4a8b5df1f76495f527a30f5b311ef3e85af342 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Apr 2017 21:50:17 +0200 Subject: [PATCH 153/218] header cleanup --- src/magic.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/magic.h b/src/magic.h index 8bf209c95..d3e45089e 100644 --- a/src/magic.h +++ b/src/magic.h @@ -244,10 +244,6 @@ extern "C" { /* prft, ob der Spruch in der Spruchliste der Einheit steht. */ void pick_random_spells(struct faction *f, int level, struct spellbook * book, int num_spells); void show_new_spells(struct faction * f, int level, const struct spellbook *book); - void updatespelllist(struct unit *u); - /* fgt alle Zauber des Magiegebietes der Einheit, deren Stufe kleiner - * als das aktuelle Magietalent ist, in die Spruchliste der Einheit - * ein */ bool knowsspell(const struct region *r, const struct unit *u, const struct spell * sp); /* prft, ob die Einheit diesen Spruch gerade beherrscht, dh From e6f8c943faa2d91f01307f1e632a177ee53d54b1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 03:27:28 +0200 Subject: [PATCH 154/218] refactor the special fumble functions for spells. removed from struct spell. funpointers in structs are bad, mkay. --- src/kernel/jsonconf.c | 3 --- src/kernel/spell.c | 23 +++++++++++++++++++++++ src/kernel/spell.h | 4 +++- src/kernel/spell.test.c | 15 +++++++++++++++ src/kernel/xmlreader.c | 9 --------- src/magic.c | 6 ++++-- src/spells.c | 3 +-- 7 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 0f5642c42..b4ce122c5 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -597,9 +597,6 @@ static void json_spells(cJSON *json) { else if (strcmp(item->string, "cast") == 0) { sp->cast = (spell_f)get_function(item->valuestring); } - else if (strcmp(item->string, "fumble") == 0) { - sp->fumble = (fumble_f)get_function(item->valuestring); - } else if (strcmp(item->string, "syntax") == 0) { sp->syntax = strdup(item->valuestring); } diff --git a/src/kernel/spell.c b/src/kernel/spell.c index 212b0a7d2..900f98ff0 100644 --- a/src/kernel/spell.c +++ b/src/kernel/spell.c @@ -33,6 +33,28 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +static critbit_tree cb_fumbles; +void add_fumble(const char *sname, fumble_f fun) +{ + size_t len; + char data[64]; + + len = cb_new_kv(sname, strlen(sname), &fun, sizeof(fun), data); + assert(len <= sizeof(data)); + cb_insert(&cb_fumbles, data, len); +} + +fumble_f get_fumble(const char *sname) +{ + void * match; + fumble_f result = NULL; + + if (cb_find_prefix(&cb_fumbles, sname, strlen(sname) + 1, &match, 1, 0)) { + cb_get_kv(match, &result, sizeof(result)); + } + return result; +} + static critbit_tree cb_spells; selist * spells; @@ -49,6 +71,7 @@ static void free_spell_cb(void *cbdata) { } void free_spells(void) { + cb_clear(&cb_fumbles); cb_clear(&cb_spells); selist_foreach(spells, free_spell_cb); selist_free(spells); diff --git a/src/kernel/spell.h b/src/kernel/spell.h index e7592f082..ae5322c9a 100644 --- a/src/kernel/spell.h +++ b/src/kernel/spell.h @@ -42,7 +42,6 @@ extern "C" { int rank; /* Reihenfolge der Zauber */ struct spell_component *components; spell_f cast; - fumble_f fumble; } spell; typedef struct spellref { @@ -50,6 +49,9 @@ extern "C" { struct spell *sp; } spellref; + void add_fumble(const char *sname, fumble_f fun); + fumble_f get_fumble(const char *sname); + struct spellref *spellref_create(struct spell *sp, const char *name); void spellref_free(struct spellref *spref); struct spell *spellref_get(struct spellref *spref); diff --git a/src/kernel/spell.test.c b/src/kernel/spell.test.c index b500f94cc..739be35da 100644 --- a/src/kernel/spell.test.c +++ b/src/kernel/spell.test.c @@ -86,10 +86,25 @@ static void test_spellref(CuTest *tc) test_cleanup(); } +void my_fumble(const struct castorder *co) { + UNUSED_ARG(co); +} + +static void test_fumbles(CuTest *tc) +{ + test_setup(); + CuAssertTrue(tc, NULL==get_fumble("hodor")); + add_fumble("hodor", my_fumble); + CuAssertTrue(tc, my_fumble==get_fumble("hodor")); + test_cleanup(); + CuAssertTrue(tc, NULL==get_fumble("hodor")); +} + CuSuite *get_spell_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_spellref); + SUITE_ADD_TEST(suite, test_fumbles); SUITE_ADD_TEST(suite, test_create_a_spell); SUITE_ADD_TEST(suite, test_create_duplicate_spell); SUITE_ADD_TEST(suite, test_create_spell_with_id); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index e29f2811c..f9e62dc43 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1312,11 +1312,8 @@ static int parse_spellbooks(xmlDocPtr doc) static int parse_spells(xmlDocPtr doc) { pf_generic cast = 0; - pf_generic fumble = 0; xmlXPathContextPtr xpath = xmlXPathNewContext(doc); xmlXPathObjectPtr spells; - char zText[32]; - strcpy(zText, "fumble_"); /* reading eressea/spells/spell */ spells = xmlXPathEvalExpression(BAD_CAST "/eressea/spells/spell", xpath); @@ -1404,8 +1401,6 @@ static int parse_spells(xmlDocPtr doc) if (!cast) { log_error("no spell cast function registered for '%s'\n", sp->sname); } - strlcpy(zText + 7, sp->sname, sizeof(zText) - 7); - fumble = get_function(zText); } else { for (k = 0; k != result->nodesetval->nodeNr; ++k) { @@ -1422,9 +1417,6 @@ static int parse_spells(xmlDocPtr doc) log_error("unknown function name '%s' for spell '%s'\n", (const char *)propValue, sp->sname); } } - else if (fun && strcmp((const char *)propValue, "fumble") == 0) { - fumble = fun; - } else { log_error("unknown function type '%s' for spell '%s'\n", (const char *)propValue, sp->sname); } @@ -1432,7 +1424,6 @@ static int parse_spells(xmlDocPtr doc) } } sp->cast = (spell_f)cast; - sp->fumble = (fumble_f)fumble; xmlXPathFreeObject(result); /* reading eressea/spells/spell/resource */ diff --git a/src/magic.c b/src/magic.c index 005f0ff94..5a6672db5 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1370,14 +1370,16 @@ static void do_fumble(castorder * co) double effect; static const race *rc_toad; static int rc_cache; + fumble_f fun; ADDMSG(&u->faction->msgs, msg_message("patzer", "unit region spell", u, r, sp)); switch (rng_int() % 10) { case 0: /* wenn vorhanden spezieller Patzer, ansonsten nix */ - if (sp->fumble) { - sp->fumble(co); + fun = get_fumble(sp->sname); + if (fun) { + fun(co); } else { fumble_default(co); diff --git a/src/spells.c b/src/spells.c index 10815708d..8bf30de88 100644 --- a/src/spells.c +++ b/src/spells.c @@ -6622,8 +6622,7 @@ static void register_spelldata(void) register_function((pf_generic)data->cast, data->sname); } if (data->fumble) { - strlcpy(zText + 7, data->sname, sizeof(zText) - 7); - register_function((pf_generic)data->fumble, zText); + add_fumble(data->sname, data->fumble); } } } From e5f898ce87525be8dd09efa08ccfa5b75be88db0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 03:42:39 +0200 Subject: [PATCH 155/218] bugfix: portals crash buildingtype(). only type that has no construction. --- src/kernel/building.c | 2 +- src/kernel/building.test.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 2107551de..cdd33b022 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -190,7 +190,7 @@ const char *buildingtype(const building_type * btype, const building * b, int bs if (btype->name) { return btype->name(btype, b, bsize); } - if (btype->construction->extra.name) { + if (btype->construction && btype->construction->extra.name) { if (b) { assert(b->type == btype); bsize = adjust_size(b, bsize); diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index 2b546cd79..3d25cd9a1 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -558,9 +558,24 @@ static void test_largestbuilding(CuTest *tc) { test_cleanup(); } +static void test_buildingtype(CuTest *tc) { + building_type *btype; + test_setup(); + btype = test_create_buildingtype("hodor"); + CuAssertPtrNotNull(tc, btype->construction); + CuAssertStrEquals(tc, "hodor", buildingtype(btype, NULL, 1)); + btype->construction->extra.name = strdup("castle"); + CuAssertStrEquals(tc, "castle", buildingtype(btype, NULL, 1)); + btype = bt_get_or_create("portal"); + CuAssertPtrEquals(tc, NULL, btype->construction); + CuAssertStrEquals(tc, "portal", buildingtype(btype, NULL, 1)); + test_cleanup(); +} + CuSuite *get_building_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_buildingtype); SUITE_ADD_TEST(suite, test_largestbuilding); SUITE_ADD_TEST(suite, test_cmp_castle_size); SUITE_ADD_TEST(suite, test_cmp_taxes); From 1885831204624fe108c2a38de51183d8991ec179 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 03:48:50 +0200 Subject: [PATCH 156/218] remove handle_events for unused events. --- src/give.c | 2 -- src/monsters.c | 4 ---- 2 files changed, 6 deletions(-) diff --git a/src/give.c b/src/give.c index 1265ab169..060ecbbb9 100644 --- a/src/give.c +++ b/src/give.c @@ -244,7 +244,6 @@ struct order *ord) warden_add_give(src, dest, itype, delta); } #endif - handle_event(dest->attribs, "receive", src); } else { /* return horses to the region */ @@ -257,7 +256,6 @@ struct order *ord) give_money(src, itype, n); } } - handle_event(src->attribs, "give", dest); } add_give(src, dest, n, delta, item2resource(itype), ord, error); if (error) diff --git a/src/monsters.c b/src/monsters.c index 21a3583af..d60268858 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -799,10 +799,6 @@ void plan_monsters(faction * f) if (long_order == NULL) { /* Ab hier noch nicht generalisierte Spezialbehandlungen. */ - if (!u->orders) { - handle_event(u->attribs, "ai_move", u); - } - if (fval(rc, RCF_DRAGON)) { long_order = plan_dragon(u); } From 3052628251d47538650b48403b399a0930eb5dc4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 04:28:07 +0200 Subject: [PATCH 157/218] broaden the fumbe-lookup tests a bit, make sure prefixes don't match. --- src/kernel/spell.test.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/kernel/spell.test.c b/src/kernel/spell.test.c index 739be35da..7777024ef 100644 --- a/src/kernel/spell.test.c +++ b/src/kernel/spell.test.c @@ -86,18 +86,24 @@ static void test_spellref(CuTest *tc) test_cleanup(); } -void my_fumble(const struct castorder *co) { +void fumble_foo(const struct castorder *co) { + UNUSED_ARG(co); +} + +void fumble_bar(const struct castorder *co) { UNUSED_ARG(co); } static void test_fumbles(CuTest *tc) { test_setup(); - CuAssertTrue(tc, NULL==get_fumble("hodor")); - add_fumble("hodor", my_fumble); - CuAssertTrue(tc, my_fumble==get_fumble("hodor")); + CuAssertTrue(tc, NULL==get_fumble("foo")); + add_fumble("foone", fumble_foo); + add_fumble("foozle", fumble_bar); + CuAssertTrue(tc, fumble_foo==get_fumble("foone")); + CuAssertTrue(tc, fumble_bar==get_fumble("foozle")); + CuAssertTrue(tc, NULL==get_fumble("foo")); test_cleanup(); - CuAssertTrue(tc, NULL==get_fumble("hodor")); } CuSuite *get_spell_suite(void) From 294b7bf01e1bebbf6d55a454fc9f1f184ce8aca1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 10:00:29 +0200 Subject: [PATCH 158/218] route all casting through a single cast_spell function. --- src/battle.c | 24 +++++------------------- src/bind_unit.c | 13 ++++--------- src/kernel/jsonconf.c | 2 +- src/kernel/spell.h | 2 +- src/kernel/xmlreader.c | 2 +- src/magic.c | 12 +++++++++--- src/magic.h | 1 + src/magic.test.c | 2 +- 8 files changed, 23 insertions(+), 35 deletions(-) diff --git a/src/battle.c b/src/battle.c index fce3d3049..81f0b635d 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1749,15 +1749,9 @@ void do_combatmagic(battle * b, combatmagic_t was) fighter *fig = co->magician.fig; const spell *sp = co->sp; - level = co->level; - if (!sp->cast) { - log_error("spell '%s' has no function.\n", sp->sname); - } - else { - level = sp->cast(co); - if (level > 0) { - pay_spell(fig->unit, sp, level, 1); - } + level = cast_spell(co); + if (level > 0) { + pay_spell(fig->unit, sp, level, 1); } } } @@ -1771,7 +1765,7 @@ static int cast_combatspell(troop at, const spell * sp, int level, double force) castorder co; create_castorder_combat(&co, at.fighter, sp, level, force); - level = sp->cast(&co); + level = cast_spell(&co); free_castorder(&co); if (level > 0) { pay_spell(at.fighter->unit, sp, level, 1); @@ -1840,12 +1834,7 @@ static void do_combatspell(troop at) return; } - if (!sp->cast) { - log_error("spell '%s' has no function.\n", sp->sname); - } - else { - level = cast_combatspell(at, sp, level, power); - } + level = cast_combatspell(at, sp, level, power); } /* Sonderattacken: Monster patzern nicht und zahlen auch keine @@ -1860,9 +1849,6 @@ static void do_extra_spell(troop at, const att * a) if (!sp) { log_error("no such spell: '%s'", a->data.sp->name); } - else if (sp->cast == NULL) { - log_error("spell '%s' has no function.", sp->sname); - } else { assert(a->level > 0); cast_combatspell(at, sp, a->level, a->level); diff --git a/src/bind_unit.c b/src/bind_unit.c index b95f43d4a..34b647418 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -512,15 +512,10 @@ static void unit_castspell(unit * u, const char *name, int level) if (sp) { spellbook *book = unit_get_spellbook(u); if (spellbook_get(book, sp)) { - if (!sp->cast) { - log_error("spell '%s' has no function.\n", sp->sname); - } - else { - castorder co; - create_castorder(&co, u, 0, sp, u->region, level, (double)level, 0, 0, 0); - sp->cast(&co); - free_castorder(&co); - } + castorder co; + create_castorder(&co, u, 0, sp, u->region, level, (double)level, 0, 0, 0); + cast_spell(&co); + free_castorder(&co); } } } diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index b4ce122c5..6dd3909b5 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -595,7 +595,7 @@ static void json_spells(cJSON *json) { continue; } else if (strcmp(item->string, "cast") == 0) { - sp->cast = (spell_f)get_function(item->valuestring); + sp->cast_fun = (spell_f)get_function(item->valuestring); } else if (strcmp(item->string, "syntax") == 0) { sp->syntax = strdup(item->valuestring); diff --git a/src/kernel/spell.h b/src/kernel/spell.h index ae5322c9a..da077347a 100644 --- a/src/kernel/spell.h +++ b/src/kernel/spell.h @@ -41,7 +41,7 @@ extern "C" { int sptyp; int rank; /* Reihenfolge der Zauber */ struct spell_component *components; - spell_f cast; + spell_f cast_fun; } spell; typedef struct spellref { diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index f9e62dc43..60c80dade 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1423,7 +1423,7 @@ static int parse_spells(xmlDocPtr doc) xmlFree(propValue); } } - sp->cast = (spell_f)cast; + sp->cast_fun = (spell_f)cast; xmlXPathFreeObject(result); /* reading eressea/spells/spell/resource */ diff --git a/src/magic.c b/src/magic.c index 5a6672db5..602207c02 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1433,7 +1433,7 @@ static void do_fumble(castorder * co) case 5: case 6: /* Spruch gelingt, aber alle Magiepunkte weg */ - co->level = sp->cast(co); + co->level = cast_spell(co); set_spellpoints(u, 0); ADDMSG(&u->faction->msgs, msg_message("patzer4", "unit region spell", u, r, sp)); @@ -1444,7 +1444,7 @@ static void do_fumble(castorder * co) case 9: default: /* Spruch gelingt, alle nachfolgenden Sprüche werden 2^4 so teuer */ - co->level = sp->cast(co); + co->level = cast_spell(co); ADDMSG(&u->faction->msgs, msg_message("patzer5", "unit region spell", u, r, sp)); countspells(u, 3); @@ -2900,7 +2900,7 @@ void magic(void) fumbled = true; } else { - co->level = sp->cast(co); + co->level = cast_spell(co); if (co->level <= 0) { /* Kosten nur für real benötige Stufe berechnen */ continue; @@ -3003,6 +3003,12 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan return 0; } +int cast_spell(struct castorder *co) +{ + const spell *sp = co->sp; + return sp->cast_fun(co); +} + static critbit_tree cb_spellbooks; spellbook * get_spellbook(const char * name) diff --git a/src/magic.h b/src/magic.h index d3e45089e..6c905ea68 100644 --- a/src/magic.h +++ b/src/magic.h @@ -286,6 +286,7 @@ extern "C" { /* Hnge c-order co an die letze c-order von cll an */ void free_castorders(struct castorder *co); /* Speicher wieder freigeben */ + int cast_spell(struct castorder *co); /* Prfroutinen fr Zaubern */ int countspells(struct unit *u, int step); diff --git a/src/magic.test.c b/src/magic.test.c index a3a199e42..3f279315c 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -378,7 +378,7 @@ void test_multi_cast(CuTest *tc) { test_setup(); sp = create_spell("fireball", 0); - sp->cast = cast_fireball; + sp->cast_fun = cast_fireball; CuAssertPtrEquals(tc, sp, find_spell("fireball")); lang = test_create_locale(); From df96589ea6e024e01ec775ce2e2dadd2b927b765 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 17:25:24 +0200 Subject: [PATCH 159/218] add tests for earn_silver. this is an odd one, don't want to break it. --- scripts/tests/e2/spells.lua | 43 ++++++++++++++++++++++++++++++++++ scripts/tests/e3/spells.lua | 46 ++++++++++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index 107b20232..4a45d7bc2 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -26,3 +26,46 @@ function test_shapeshift() s = u2:show() assert_equal("1 Goblin", string.sub(s, string.find(s, "1 Goblin"))) end + +-- E3: earn 50 per level of spell +function test_earn_silber() + local r = region.create(0, 0, "plain") + local f = faction.create("human") + local u = unit.create(f, r) + + eressea.settings.set("rules.food.flags", "4") + eressea.settings.set("magic.fumble.enable", "0") + eressea.settings.set("rules.peasants.growth", "0") + eressea.settings.set("rules.economy.repopulate_maximum", "0") + + u.magic = "gwyrrd" + u.race = "elf" + u:set_skill("magic", 10) + u.aura = 100 + local err = u:add_spell("earn_silver#gwyrrd") + assert_equal(0, err) + + u:clear_orders() + u:add_order("ZAUBERE STUFE 1 Viehheilung") + r:set_resource("money", 350) + r:set_resource("peasant", 0) + process_orders() -- get 50 silver + assert_equal(50, u:get_item("money")) + assert_equal(300, r:get_resource("money")) + + u:clear_orders() -- get 100 silver + u:add_order("ZAUBERE STUFE 2 Viehheilung") + process_orders() + assert_equal(150, u:get_item("money")) + assert_equal(200, r:get_resource("money")) + + u:clear_orders() -- get 150 silver + u:add_order("ZAUBERE STUFE 3 Viehheilung") + process_orders() + assert_equal(300, u:get_item("money")) + assert_equal(50, r:get_resource("money")) + + process_orders() -- not enough + assert_equal(350, u:get_item("money")) + assert_equal(0, r:get_resource("money")) +end diff --git a/scripts/tests/e3/spells.lua b/scripts/tests/e3/spells.lua index df9408fbd..b7d89c3e0 100644 --- a/scripts/tests/e3/spells.lua +++ b/scripts/tests/e3/spells.lua @@ -29,9 +29,6 @@ function test_blessedharvest_lasts_n_turn() u:add_order("ZAUBERE STUFE 3 Regentanz") assert_equal(0, r:get_resource("money"), 0) - local m = 0 - local p = 100 - process_orders() assert_equal(200, r:get_resource("money")) u:clear_orders() @@ -64,3 +61,46 @@ function test_magic() -- there used to be a SEGFAULT when writing reports here: -- write_reports() end + +-- E3: earn 50 per every TWO levels of spell +function test_earn_silber() + local r = region.create(0, 0, "plain") + local f = faction.create("human") + local u = unit.create(f, r) + + eressea.settings.set("rules.food.flags", "4") + eressea.settings.set("magic.fumble.enable", "0") + eressea.settings.set("rules.peasants.growth", "0") + eressea.settings.set("rules.economy.repopulate_maximum", "0") + + u.magic = "gwyrrd" + u.race = "elf" + u:set_skill("magic", 10) + u.aura = 100 + local err = u:add_spell("earn_silver#gwyrrd") + assert_equal(0, err) + + u:clear_orders() + u:add_order("ZAUBERE STUFE 1 Viehheilung") + r:set_resource("money", 250) + r:set_resource("peasant", 0) + process_orders() -- get 50 silver + assert_equal(50, u:get_item("money")) + assert_equal(200, r:get_resource("money")) + + u:clear_orders() -- get 75 silver + u:add_order("ZAUBERE STUFE 2 Viehheilung") + process_orders() + assert_equal(125, u:get_item("money")) + assert_equal(125, r:get_resource("money")) + + u:clear_orders() -- get 100 silver + u:add_order("ZAUBERE STUFE 3 Viehheilung") + process_orders() + assert_equal(225, u:get_item("money")) + assert_equal(25, r:get_resource("money")) + + process_orders() -- not enough + assert_equal(250, u:get_item("money")) + assert_equal(0, r:get_resource("money")) +end From 6da21dbbe982958406dabbbfe3e0e4e4ea987316 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 17:42:16 +0200 Subject: [PATCH 160/218] Zaubertests in Ebenen sind unstabil. In E3 bekommen Elfen eien Bonus im Wald. --- scripts/tests/e2/spells.lua | 4 ++-- scripts/tests/e3/spells.lua | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index 4a45d7bc2..4b0892d9d 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -28,8 +28,8 @@ function test_shapeshift() end -- E3: earn 50 per level of spell -function test_earn_silber() - local r = region.create(0, 0, "plain") +function test_earn_silver() + local r = region.create(0, 0, "mountain") local f = faction.create("human") local u = unit.create(f, r) diff --git a/scripts/tests/e3/spells.lua b/scripts/tests/e3/spells.lua index b7d89c3e0..bea931c1c 100644 --- a/scripts/tests/e3/spells.lua +++ b/scripts/tests/e3/spells.lua @@ -63,8 +63,8 @@ function test_magic() end -- E3: earn 50 per every TWO levels of spell -function test_earn_silber() - local r = region.create(0, 0, "plain") +function test_earn_silver() + local r = region.create(0, 0, "mountain") local f = faction.create("human") local u = unit.create(f, r) From fb8f63e73ba2cf756237513b0b1fee5efb455977 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 17:48:08 +0200 Subject: [PATCH 161/218] also fix the test --- scripts/tests/e3/spells.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/tests/e3/spells.lua b/scripts/tests/e3/spells.lua index bea931c1c..ab8e4aca0 100644 --- a/scripts/tests/e3/spells.lua +++ b/scripts/tests/e3/spells.lua @@ -82,25 +82,25 @@ function test_earn_silver() u:clear_orders() u:add_order("ZAUBERE STUFE 1 Viehheilung") - r:set_resource("money", 250) + r:set_resource("money", 200) r:set_resource("peasant", 0) process_orders() -- get 50 silver assert_equal(50, u:get_item("money")) - assert_equal(200, r:get_resource("money")) + assert_equal(150, r:get_resource("money")) - u:clear_orders() -- get 75 silver + u:clear_orders() -- get 50 silver u:add_order("ZAUBERE STUFE 2 Viehheilung") process_orders() - assert_equal(125, u:get_item("money")) - assert_equal(125, r:get_resource("money")) + assert_equal(100, u:get_item("money")) + assert_equal(100, r:get_resource("money")) - u:clear_orders() -- get 100 silver + u:clear_orders() -- get 75 silver u:add_order("ZAUBERE STUFE 3 Viehheilung") process_orders() - assert_equal(225, u:get_item("money")) + assert_equal(175, u:get_item("money")) assert_equal(25, r:get_resource("money")) process_orders() -- not enough - assert_equal(250, u:get_item("money")) + assert_equal(200, u:get_item("money")) assert_equal(0, r:get_resource("money")) end From 74673f172f1c0bb71a9164773329c184b195ec0c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 21:38:30 +0200 Subject: [PATCH 162/218] test for raindance/harvest spells, both games --- scripts/tests/e2/spells.lua | 34 +++++++++++++++++++++++++++++++++- scripts/tests/e3/spells.lua | 7 ++----- src/kernel/building.c | 2 +- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index 4b0892d9d..dad951293 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -27,7 +27,39 @@ function test_shapeshift() assert_equal("1 Goblin", string.sub(s, string.find(s, "1 Goblin"))) end --- E3: earn 50 per level of spell +function test_raindance() + local r = region.create(0, 0, "plain") + local f = faction.create("halfling", "noreply@eressea.de", "de") + local u = unit.create(f, r) + local err = 0 + r:set_resource("peasant", 100) + r:set_resource("money", 0) + u.magic = "gwyrrd" + u.race = "dwarf" + u:set_skill("magic", 20) + u.aura = 200 + err = err + u:add_spell("raindance") + assert_equal(0, err) + + u:clear_orders() + u:add_order("ZAUBERE STUFE 1 Regentanz") + assert_equal(0, r:get_resource("money")) + + process_orders() + assert_equal(200, r:get_resource("money")) + assert_equal(0, u:get_item("money")) + + u:clear_orders() + u:add_order("ARBEITEN") + process_orders() + assert_equal(10, u:get_item("money")) -- only peasants benefit + assert_equal(400, r:get_resource("money")) + -- this is where the spell ends + process_orders() + process_orders() + assert_equal(600, r:get_resource("money")) +end + function test_earn_silver() local r = region.create(0, 0, "mountain") local f = faction.create("human") diff --git a/scripts/tests/e3/spells.lua b/scripts/tests/e3/spells.lua index ab8e4aca0..5cd8ef431 100644 --- a/scripts/tests/e3/spells.lua +++ b/scripts/tests/e3/spells.lua @@ -9,20 +9,17 @@ function setup() eressea.settings.set("rules.peasants.growth", "0") end -function test_blessedharvest_lasts_n_turn() +function test_raindance() local r = region.create(0, 0, "plain") local f = faction.create("halfling", "noreply@eressea.de", "de") local u = unit.create(f, r) - local err = 0 r:set_resource("peasant", 100) r:set_resource("money", 0) - u:add_item("money", 1000) u.magic = "gwyrrd" u.race = "dwarf" u:set_skill("magic", 20) u.aura = 200 - err = err + u:add_spell("raindance") - err = err + u:add_spell("blessedharvest") + local err = u:add_spell("raindance") assert_equal(0, err) u:clear_orders() diff --git a/src/kernel/building.c b/src/kernel/building.c index cdd33b022..9decc9039 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -704,7 +704,7 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn) else { wage = wagetable[esize][2]; } - if (rule_blessed_harvest() == HARVEST_WORK) { + if (r->attribs && rule_blessed_harvest() == HARVEST_WORK) { /* E1 rules */ wage += curse_geteffect(get_curse(r->attribs, ct_find("blessedharvest"))); } From edd3b36a9fd6785ddc3507bc14077c2f13a03172 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 18:18:47 +0200 Subject: [PATCH 163/218] add a callbacks module. make last-chance spell function in lua for spells with none. --- src/bindings.c | 14 ++++++++++++++ src/bindings.h | 1 + src/helpers.c | 14 -------------- src/helpers.h | 5 ++--- src/kernel/CMakeLists.txt | 2 ++ src/kernel/callbacks.c | 4 ++++ src/kernel/callbacks.h | 35 +++++++++++++++++++++++++++++++++++ src/magic.c | 6 +++++- 8 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 src/kernel/callbacks.c create mode 100644 src/kernel/callbacks.h diff --git a/src/bindings.c b/src/bindings.c index 1d6270b35..9ea548465 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -92,6 +92,20 @@ TOLUA_PKG(locale); TOLUA_PKG(log); TOLUA_PKG(game); +int tolua_toid(lua_State * L, int idx, int def) +{ + int no = 0; + int type = lua_type(L, idx); + if (type == LUA_TNUMBER) { + no = (int)tolua_tonumber(L, idx, def); + } + else { + const char *str = tolua_tostring(L, idx, NULL); + no = str ? atoi36(str) : def; + } + return no; +} + int log_lua_error(lua_State * L) { const char *error = lua_tostring(L, -1); diff --git a/src/bindings.h b/src/bindings.h index 354bb199a..2275236cb 100755 --- a/src/bindings.h +++ b/src/bindings.h @@ -18,6 +18,7 @@ extern "C" { struct _dictionary_; struct selist; + int tolua_toid(struct lua_State * L, int idx, int def); int tolua_sqlite_open(struct lua_State *L); int tolua_bindings_open(struct lua_State *L, const struct _dictionary_ *d); int tolua_itemlist_next(struct lua_State *L); diff --git a/src/helpers.c b/src/helpers.c index 59695e9b4..924082bcd 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -455,20 +455,6 @@ use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord) return result; } -int tolua_toid(lua_State * L, int idx, int def) -{ - int no = 0; - int type = lua_type(L, idx); - if (type == LUA_TNUMBER) { - no = (int)tolua_tonumber(L, idx, def); - } - else { - const char *str = tolua_tostring(L, idx, NULL); - no = str ? atoi36(str) : def; - } - return no; -} - void register_tolua_helpers(void) { at_register(&at_direction); diff --git a/src/helpers.h b/src/helpers.h index d77765187..5187f7bcf 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -14,9 +14,8 @@ without prior permission by the authors of Eressea. extern "C" { #endif - struct lua_State; - void register_tolua_helpers(void); - int tolua_toid(struct lua_State *L, int idx, int def); + struct lua_State; + void register_tolua_helpers(void); #ifdef __cplusplus } diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index b8423ae03..e572d0763 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -6,6 +6,7 @@ alliance.test.c ally.test.c build.test.c building.test.c +# callbacks.test.c command.test.c config.test.c # connection.test.c @@ -38,6 +39,7 @@ alliance.c ally.c build.c building.c +callbacks.c command.c config.c connection.c diff --git a/src/kernel/callbacks.c b/src/kernel/callbacks.c new file mode 100644 index 000000000..d8070bd04 --- /dev/null +++ b/src/kernel/callbacks.c @@ -0,0 +1,4 @@ +#include +#include "callbacks.h" + +struct callbacks callbacks; diff --git a/src/kernel/callbacks.h b/src/kernel/callbacks.h new file mode 100644 index 000000000..99db5e390 --- /dev/null +++ b/src/kernel/callbacks.h @@ -0,0 +1,35 @@ +/* +Copyright (c) 1998-2015, Enno Rehling +Katja Zedel + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +**/ + +#ifndef H_KRNL_CALLBACKS_H +#define H_KRNL_CALLBACKS_H + +#ifdef __cplusplus +extern "C" { +#endif + + struct castorder; + + extern struct callbacks { + int (*cast_spell)(struct castorder *co); + } callbacks; + +#ifdef __cplusplus +} +#endif +#endif /* H_KRNL_CALLBACKS_H */ diff --git a/src/magic.c b/src/magic.c index 602207c02..8db533923 100644 --- a/src/magic.c +++ b/src/magic.c @@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include #include #include @@ -3006,7 +3007,10 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan int cast_spell(struct castorder *co) { const spell *sp = co->sp; - return sp->cast_fun(co); + if (sp->cast_fun) { + return sp->cast_fun(co); + } + return callbacks.cast_spell(co); } static critbit_tree cb_spellbooks; From bd9968c2667f4a3f0bd209f00ee4bd1f74e8eb01 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 18:23:42 +0200 Subject: [PATCH 164/218] set the callback, remove lua_callspell from XML. WIP: some spells cannot find their lua callback. --- res/core/spells.xml | 20 -------------------- res/e3a/spells.xml | 25 ------------------------- res/eressea/spells.xml | 20 -------------------- src/helpers.c | 4 +++- 4 files changed, 3 insertions(+), 66 deletions(-) diff --git a/res/core/spells.xml b/res/core/spells.xml index cb7fcf911..59d06a522 100644 --- a/res/core/spells.xml +++ b/res/core/spells.xml @@ -10,14 +10,12 @@ - - @@ -25,12 +23,10 @@ - - @@ -38,19 +34,16 @@ - - - @@ -58,18 +51,15 @@ - - - @@ -77,12 +67,10 @@ - - @@ -90,25 +78,21 @@ - - - - @@ -116,7 +100,6 @@ - @@ -124,20 +107,17 @@ - - - diff --git a/res/e3a/spells.xml b/res/e3a/spells.xml index 74eb89146..89a977275 100644 --- a/res/e3a/spells.xml +++ b/res/e3a/spells.xml @@ -10,14 +10,12 @@ - - @@ -39,7 +37,6 @@ - @@ -106,7 +103,6 @@ - @@ -119,7 +115,6 @@ - @@ -189,7 +184,6 @@ - @@ -205,7 +199,6 @@ - @@ -269,7 +262,6 @@ - @@ -304,12 +296,10 @@ - - @@ -394,21 +384,18 @@ - - - @@ -416,7 +403,6 @@ - @@ -426,7 +412,6 @@ - @@ -435,7 +420,6 @@ - @@ -444,7 +428,6 @@ - @@ -454,7 +437,6 @@ - @@ -472,39 +454,33 @@ - - - - - - @@ -518,7 +494,6 @@ - diff --git a/res/eressea/spells.xml b/res/eressea/spells.xml index 1d762f4bd..6b2e43a15 100644 --- a/res/eressea/spells.xml +++ b/res/eressea/spells.xml @@ -10,14 +10,12 @@ - - @@ -494,12 +492,10 @@ - - @@ -507,7 +503,6 @@ - @@ -520,12 +515,10 @@ - - @@ -533,18 +526,15 @@ - - - @@ -558,12 +548,10 @@ - - @@ -583,25 +571,21 @@ - - - - @@ -609,7 +593,6 @@ - @@ -617,20 +600,17 @@ - - - diff --git a/src/helpers.c b/src/helpers.c index 924082bcd..429c5d190 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -24,6 +24,7 @@ without prior permission by the authors of Eressea. #include #include +#include #include #include #include @@ -460,7 +461,8 @@ void register_tolua_helpers(void) at_register(&at_direction); at_register(&at_building_action); - register_function((pf_generic)lua_callspell, TOLUA_CAST "lua_castspell"); + callbacks.cast_spell = lua_callspell; + register_function((pf_generic)lua_initfamiliar, TOLUA_CAST "lua_initfamiliar"); register_function((pf_generic)lua_getresource, From 724a41ac8537a3bfd78fc97cd8905f9a6129a8e7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 18:41:30 +0200 Subject: [PATCH 165/218] refactor: pass function name to callback, calculate it in call_spell instead. --- src/helpers.c | 13 +------------ src/kernel/callbacks.h | 2 +- src/kernel/xmlreader.c | 2 +- src/magic.c | 15 ++++++++++++++- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/helpers.c b/src/helpers.c index 429c5d190..4e020cefe 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -157,23 +157,12 @@ static void push_param(lua_State * L, char c, spllprm * param) } /** callback to use lua for spell functions */ -static int lua_callspell(castorder * co) +static int lua_callspell(castorder * co, const char *fname) { lua_State *L = (lua_State *)global.vm_state; - const char *fname = co->sp->sname; unit *caster = co_get_caster(co); region * r = co_get_region(co); int result = -1; - const char *hashpos = strchr(fname, '#'); - char fbuf[64]; - - if (hashpos != NULL) { - ptrdiff_t len = hashpos - fname; - assert(len < (ptrdiff_t) sizeof(fbuf)); - memcpy(fbuf, fname, len); - fbuf[len] = '\0'; - fname = fbuf; - } lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { diff --git a/src/kernel/callbacks.h b/src/kernel/callbacks.h index 99db5e390..71f3900c4 100644 --- a/src/kernel/callbacks.h +++ b/src/kernel/callbacks.h @@ -26,7 +26,7 @@ extern "C" { struct castorder; extern struct callbacks { - int (*cast_spell)(struct castorder *co); + int (*cast_spell)(struct castorder *co, const char *fname); } callbacks; #ifdef __cplusplus diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 60c80dade..c0595b4f5 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1399,7 +1399,7 @@ static int parse_spells(xmlDocPtr doc) if (result->nodesetval->nodeNr == 0) { cast = get_function(sp->sname); if (!cast) { - log_error("no spell cast function registered for '%s'\n", sp->sname); + log_info("no spell cast function registered for '%s'\n", sp->sname); } } else { diff --git a/src/magic.c b/src/magic.c index 8db533923..d7bc63ca2 100644 --- a/src/magic.c +++ b/src/magic.c @@ -3006,11 +3006,24 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan int cast_spell(struct castorder *co) { + const char *fname = co->sp->sname; + const char *hashpos = strchr(fname, '#'); + char fbuf[64]; + const spell *sp = co->sp; if (sp->cast_fun) { return sp->cast_fun(co); } - return callbacks.cast_spell(co); + + if (hashpos != NULL) { + ptrdiff_t len = hashpos - fname; + assert(len < (ptrdiff_t) sizeof(fbuf)); + memcpy(fbuf, fname, len); + fbuf[len] = '\0'; + fname = fbuf; + } + + return callbacks.cast_spell(co, fname); } static critbit_tree cb_spellbooks; From 976b23be724385db3deb7376961ae2ffb2499b1e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 20:54:53 +0200 Subject: [PATCH 166/218] refactor E3 to use the same raindance/harvest spells as E2. only indirect effects are different. --- res/e3a/spells.xml | 2 ++ scripts/eressea/e3/init.lua | 1 - scripts/eressea/e3/rules.lua | 35 ----------------------------------- scripts/tests/e3/spells.lua | 5 ++--- src/economy.c | 3 +-- src/spells.c | 5 +++-- 6 files changed, 8 insertions(+), 43 deletions(-) delete mode 100644 scripts/eressea/e3/rules.lua diff --git a/res/e3a/spells.xml b/res/e3a/spells.xml index 89a977275..80d9e6260 100644 --- a/res/e3a/spells.xml +++ b/res/e3a/spells.xml @@ -296,6 +296,7 @@ + @@ -494,6 +495,7 @@ + diff --git a/scripts/eressea/e3/init.lua b/scripts/eressea/e3/init.lua index e376eaadc..f7402268c 100644 --- a/scripts/eressea/e3/init.lua +++ b/scripts/eressea/e3/init.lua @@ -1,4 +1,3 @@ -require 'eressea.e3.rules' require 'eressea.spells' eressea.log.debug("rules for game E3") diff --git a/scripts/eressea/e3/rules.lua b/scripts/eressea/e3/rules.lua deleted file mode 100644 index e49e03438..000000000 --- a/scripts/eressea/e3/rules.lua +++ /dev/null @@ -1,35 +0,0 @@ --- the "raindance" spell -function raindance(r, mage, level, force) - if (create_curse(mage, r, "blessedharvest", force, 1+force*2, 100 * force)) then - -- slightly crooked way of reporting an action to everyone in the region - local msg = message.create("raindance_effect") - msg:set_unit("mage", mage) - if (msg:report_action(r, mage, 3)) then - local msg2 = message.create("raindance_effect") - msg2:set_unit("mage", nil) - msg2:report_action(r, mage, 4) - end - end - return level -end - --- the "blessed harvest" spell -function blessedharvest(r, mage, level, force) - if create_curse(mage, r, "blessedharvest", force, 1+force*2, 50 * force) then - -- slightly crooked way of reporting an action to everyone in the region - local msg = message.create("harvest_effect") - msg:set_unit("mage", mage) - if (msg:report_action(r, mage, 3)) then - local msg2 = message.create("harvest_effect") - msg2:set_unit("mage", nil) - msg2:report_action(r, mage, 4) - end - for idx, rn in ipairs(r.adj) do - -- nur landregionen haben moral>=0 - if r.morale>=0 then - create_curse(mage, r, "blessedharvest", force, force*2, 50 * force) - end - end - end - return level -end diff --git a/scripts/tests/e3/spells.lua b/scripts/tests/e3/spells.lua index 5cd8ef431..24f97c221 100644 --- a/scripts/tests/e3/spells.lua +++ b/scripts/tests/e3/spells.lua @@ -32,10 +32,9 @@ function test_raindance() u:add_order("ARBEITEN") process_orders() process_orders() + assert_equal(500, r:get_resource("money")) process_orders() - assert_equal(800, r:get_resource("money")) - process_orders() - assert_equal(900, r:get_resource("money")) + assert_equal(600, r:get_resource("money")) end function test_magic() diff --git a/src/economy.c b/src/economy.c index 1a4cc5b18..48653d0aa 100644 --- a/src/economy.c +++ b/src/economy.c @@ -2658,8 +2658,7 @@ expandwork(region * r, request * work_begin, request * work_end, int maxwork) const curse_type *blessedharvest_ct = ct_find("blessedharvest"); if (blessedharvest_ct) { int happy = - (int)curse_geteffect(get_curse(r->attribs, blessedharvest_ct)); - happy = MIN(happy, jobs); + (int)(jobs * curse_geteffect(get_curse(r->attribs, blessedharvest_ct))); earnings += happy; } } diff --git a/src/spells.c b/src/spells.c index 8bf30de88..5341a8e11 100644 --- a/src/spells.c +++ b/src/spells.c @@ -1104,8 +1104,9 @@ static int sp_blessedharvest(castorder * co) if (create_curse(mage, &r->attribs, ct_find("blessedharvest"), co->force, duration, 1.0, 0)) { - message *seen = msg_message("harvest_effect", "mage", mage); - message *unseen = msg_message("harvest_effect", "mage", NULL); + const char * effect = co->sp->sname[0]=='b' ? "harvest_effect" : "raindance_effect"; + message *seen = msg_message(effect, "mage", mage); + message *unseen = msg_message(effect, "mage", NULL); report_effect(r, mage, seen, unseen); msg_release(seen); msg_release(unseen); From 80d696d02ab8eec9557af571ca025e75ce114b02 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 22:15:18 +0200 Subject: [PATCH 167/218] remove the funcpointer from struct spell. --- res/e3a/strings.xml | 2 +- src/bindings.h | 2 +- src/helpers.c | 20 ++++++++----------- src/helpers.h | 1 + src/kernel/jsonconf.c | 3 --- src/kernel/spell.c | 32 ++++++++++++++++++++++++++---- src/kernel/spell.h | 4 +++- src/kernel/xmlreader.c | 45 +++--------------------------------------- src/magic.c | 13 +++++++----- src/magic.test.c | 2 +- src/spells.c | 17 ++++++++-------- 11 files changed, 63 insertions(+), 78 deletions(-) diff --git a/res/e3a/strings.xml b/res/e3a/strings.xml index 054cabfaa..eb9f48cf3 100644 --- a/res/e3a/strings.xml +++ b/res/e3a/strings.xml @@ -210,7 +210,7 @@ Dieser Zauber wird die gesamte Ausrüstung der Zieleinheit für einige Zeit vor den Blicken anderer verschleiern. Der Zauber schützt nicht vor Dieben und Spionen. This spell will hide the whole equipment of a target unit from the looks of others. It will not protect against thieves or spies. - + Durch dieses uralte Tanzritual ruft der Zauberkundige die Kräfte des Lebens und der Fruchtbarkeit an. Die darauf folgenden Regenfälle begünstigen das Wachstum und erhöhen die Ernteerträge einiger Bauern der Region bis der Regen wieder nachlässt. This ancient rite calls upon the forces of life and fertility. For the next few weeks, the peasants' harvest will be extraordinary good. diff --git a/src/bindings.h b/src/bindings.h index 2275236cb..5cb64a038 100755 --- a/src/bindings.h +++ b/src/bindings.h @@ -18,7 +18,7 @@ extern "C" { struct _dictionary_; struct selist; - int tolua_toid(struct lua_State * L, int idx, int def); + int tolua_toid(struct lua_State *L, int idx, int def); int tolua_sqlite_open(struct lua_State *L); int tolua_bindings_open(struct lua_State *L, const struct _dictionary_ *d); int tolua_itemlist_next(struct lua_State *L); diff --git a/src/helpers.c b/src/helpers.c index 4e020cefe..700850018 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -23,6 +23,7 @@ without prior permission by the authors of Eressea. #include #include +#include #include #include #include @@ -452,21 +453,16 @@ void register_tolua_helpers(void) callbacks.cast_spell = lua_callspell; - register_function((pf_generic)lua_initfamiliar, - TOLUA_CAST "lua_initfamiliar"); - register_function((pf_generic)lua_getresource, - TOLUA_CAST "lua_getresource"); - register_function((pf_generic)lua_changeresource, - TOLUA_CAST "lua_changeresource"); - register_function((pf_generic)lua_equipmentcallback, - TOLUA_CAST "lua_equip"); + register_function((pf_generic)lua_initfamiliar, "lua_initfamiliar"); + register_function((pf_generic)lua_getresource, "lua_getresource"); + register_function((pf_generic)lua_changeresource, "lua_changeresource"); + register_function((pf_generic)lua_equipmentcallback, "lua_equip"); - register_function((pf_generic)lua_wage, TOLUA_CAST "lua_wage"); - register_function((pf_generic)lua_maintenance, - TOLUA_CAST "lua_maintenance"); + register_function((pf_generic)lua_wage, "lua_wage"); + register_function((pf_generic)lua_maintenance, "lua_maintenance"); item_use_fun = use_item_lua; res_produce_fun = produce_resource_lua; res_limit_fun = limit_resource_lua; - register_item_give(lua_giveitem, TOLUA_CAST "lua_giveitem"); + register_item_give(lua_giveitem, "lua_giveitem"); } diff --git a/src/helpers.h b/src/helpers.h index 5187f7bcf..d0bbcc58b 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -15,6 +15,7 @@ extern "C" { #endif struct lua_State; + void register_tolua_helpers(void); #ifdef __cplusplus diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 6dd3909b5..32ab06e08 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -594,9 +594,6 @@ static void json_spells(cJSON *json) { if (strcmp(item->string, "index") == 0) { continue; } - else if (strcmp(item->string, "cast") == 0) { - sp->cast_fun = (spell_f)get_function(item->valuestring); - } else if (strcmp(item->string, "syntax") == 0) { sp->syntax = strdup(item->valuestring); } diff --git a/src/kernel/spell.c b/src/kernel/spell.c index 900f98ff0..393bbecb9 100644 --- a/src/kernel/spell.c +++ b/src/kernel/spell.c @@ -33,7 +33,30 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -static critbit_tree cb_fumbles; + +static critbit_tree cb_spell_fun; +void add_spellcast(const char *sname, spell_f fun) +{ + size_t len; + char data[64]; + + len = cb_new_kv(sname, strlen(sname), &fun, sizeof(fun), data); + assert(len <= sizeof(data)); + cb_insert(&cb_spell_fun, data, len); +} + +spell_f get_spellcast(const char *sname) +{ + void * match; + spell_f result = NULL; + + if (cb_find_prefix(&cb_spell_fun, sname, strlen(sname) + 1, &match, 1, 0)) { + cb_get_kv(match, &result, sizeof(result)); + } + return result; +} + +static critbit_tree cb_fumble_fun; void add_fumble(const char *sname, fumble_f fun) { size_t len; @@ -41,7 +64,7 @@ void add_fumble(const char *sname, fumble_f fun) len = cb_new_kv(sname, strlen(sname), &fun, sizeof(fun), data); assert(len <= sizeof(data)); - cb_insert(&cb_fumbles, data, len); + cb_insert(&cb_fumble_fun, data, len); } fumble_f get_fumble(const char *sname) @@ -49,7 +72,7 @@ fumble_f get_fumble(const char *sname) void * match; fumble_f result = NULL; - if (cb_find_prefix(&cb_fumbles, sname, strlen(sname) + 1, &match, 1, 0)) { + if (cb_find_prefix(&cb_fumble_fun, sname, strlen(sname) + 1, &match, 1, 0)) { cb_get_kv(match, &result, sizeof(result)); } return result; @@ -71,7 +94,8 @@ static void free_spell_cb(void *cbdata) { } void free_spells(void) { - cb_clear(&cb_fumbles); + cb_clear(&cb_fumble_fun); + cb_clear(&cb_spell_fun); cb_clear(&cb_spells); selist_foreach(spells, free_spell_cb); selist_free(spells); diff --git a/src/kernel/spell.h b/src/kernel/spell.h index da077347a..41feaa17d 100644 --- a/src/kernel/spell.h +++ b/src/kernel/spell.h @@ -41,7 +41,6 @@ extern "C" { int sptyp; int rank; /* Reihenfolge der Zauber */ struct spell_component *components; - spell_f cast_fun; } spell; typedef struct spellref { @@ -52,6 +51,9 @@ extern "C" { void add_fumble(const char *sname, fumble_f fun); fumble_f get_fumble(const char *sname); + void add_spellcast(const char *sname, spell_f fun); + spell_f get_spellcast(const char *sname); + struct spellref *spellref_create(struct spell *sp, const char *name); void spellref_free(struct spellref *spref); struct spell *spellref_get(struct spellref *spref); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index c0595b4f5..7367a2023 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -279,11 +279,8 @@ parse_function(xmlNodePtr node, pf_generic * funPtr, xmlChar ** namePtr) xmlChar *propValue = xmlGetProp(node, BAD_CAST "value"); assert(propValue != NULL); fun = get_function((const char *)propValue); - if (fun != NULL) { - xmlFree(propValue); - - propValue = xmlGetProp(node, BAD_CAST "name"); - } + xmlFree(propValue); + propValue = xmlGetProp(node, BAD_CAST "name"); *namePtr = propValue; *funPtr = fun; return 0; @@ -1311,7 +1308,6 @@ static int parse_spellbooks(xmlDocPtr doc) static int parse_spells(xmlDocPtr doc) { - pf_generic cast = 0; xmlXPathContextPtr xpath = xmlXPathNewContext(doc); xmlXPathObjectPtr spells; @@ -1388,44 +1384,9 @@ static int parse_spells(xmlDocPtr doc) sp->sptyp |= REGIONSPELL; k = xml_ivalue(node, "combat", 0); - if (k >= 0 && k <= 3) + if (k >= 0 && k <= 3) { sp->sptyp |= modes[k]; - - /* reading eressea/spells/spell/function */ - - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "function", xpath); - - if (result->nodesetval->nodeNr == 0) { - cast = get_function(sp->sname); - if (!cast) { - log_info("no spell cast function registered for '%s'\n", sp->sname); - } } - else { - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - pf_generic fun; - - parse_function(node, &fun, &propValue); - assert(propValue != NULL); - if (strcmp((const char *)propValue, "cast") == 0) { - if (fun) { - cast = fun; - } - else { - log_error("unknown function name '%s' for spell '%s'\n", (const char *)propValue, sp->sname); - } - } - else { - log_error("unknown function type '%s' for spell '%s'\n", (const char *)propValue, sp->sname); - } - xmlFree(propValue); - } - } - sp->cast_fun = (spell_f)cast; - xmlXPathFreeObject(result); - /* reading eressea/spells/spell/resource */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "resource", xpath); diff --git a/src/magic.c b/src/magic.c index d7bc63ca2..63c443296 100644 --- a/src/magic.c +++ b/src/magic.c @@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "skill.h" #include "study.h" +#include "helpers.h" #include "laws.h" #include @@ -3009,12 +3010,9 @@ int cast_spell(struct castorder *co) const char *fname = co->sp->sname; const char *hashpos = strchr(fname, '#'); char fbuf[64]; + spell_f fun; const spell *sp = co->sp; - if (sp->cast_fun) { - return sp->cast_fun(co); - } - if (hashpos != NULL) { ptrdiff_t len = hashpos - fname; assert(len < (ptrdiff_t) sizeof(fbuf)); @@ -3023,7 +3021,12 @@ int cast_spell(struct castorder *co) fname = fbuf; } - return callbacks.cast_spell(co, fname); + fun = get_spellcast(sp->sname); + if (!fun) { + log_warning("no spell function for %s, try callback", sp->sname); + return callbacks.cast_spell(co, fname); + } + return fun(co); } static critbit_tree cb_spellbooks; diff --git a/src/magic.test.c b/src/magic.test.c index 3f279315c..746905029 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -377,8 +377,8 @@ void test_multi_cast(CuTest *tc) { struct locale * lang; test_setup(); + add_spellcast("fireball", cast_fireball); sp = create_spell("fireball", 0); - sp->cast_fun = cast_fireball; CuAssertPtrEquals(tc, sp, find_spell("fireball")); lang = test_create_locale(); diff --git a/src/spells.c b/src/spells.c index 5341a8e11..468441cdd 100644 --- a/src/spells.c +++ b/src/spells.c @@ -6615,12 +6615,10 @@ static spelldata spell_functions[] = { static void register_spelldata(void) { int i; - char zText[32]; - strcpy(zText, "fumble_"); for (i = 0; spell_functions[i].sname; ++i) { spelldata *data = spell_functions + i; if (data->cast) { - register_function((pf_generic)data->cast, data->sname); + add_spellcast(data->sname, data->cast); } if (data->fumble) { add_fumble(data->sname, data->fumble); @@ -6733,11 +6731,14 @@ void register_spells(void) ct_register(&ct_firewall); ct_register(&ct_deathcloud); - register_function((pf_generic)sp_blessedharvest, "cast_blessedharvest"); - register_function((pf_generic)sp_summon_familiar, "cast_familiar"); - register_function((pf_generic)sp_babbler, "cast_babbler"); - register_function((pf_generic)sp_readmind, "cast_readmind"); - register_function((pf_generic)sp_kampfzauber, "combat_spell"); + add_spellcast("blabbermouth", sp_babbler); + add_spellcast("summon_familiar", sp_summon_familiar); + add_spellcast("meteor_rain", sp_kampfzauber); + add_spellcast("fireball", sp_kampfzauber); + add_spellcast("hail", sp_kampfzauber); + add_spellcast("readmind", sp_readmind); + add_spellcast("blessedharvest", sp_blessedharvest); + add_spellcast("raindance", sp_blessedharvest); register_spelldata(); From 51a991413fa31d56e97ef82091c9f6c1e85bf4e4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 22:46:35 +0200 Subject: [PATCH 168/218] use at_deprecate, as is intended. --- src/spells.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/spells.c b/src/spells.c index 468441cdd..332647fae 100644 --- a/src/spells.c +++ b/src/spells.c @@ -2931,10 +2931,6 @@ static int dc_read_compat(struct attrib *a, void *target, gamedata *data) } return AT_READ_FAIL; /* we don't care for the attribute. */ } - -attrib_type at_deathcloud_compat = { - "zauber_todeswolke", NULL, NULL, NULL, NULL, dc_read_compat -}; #endif /* ------------------------------------------------------------- */ @@ -6725,7 +6721,9 @@ void register_spells(void) { register_borders(); - at_register(&at_deathcloud_compat); +#ifdef COMPAT_DEATHCLOUD + at_deprecate("zauber_todeswolke", dc_read_compat); +#endif /* init_firewall(); */ ct_register(&ct_firewall); From 773e8c79d0facc308da398ae363af9a76e6b3c64 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 22:49:26 +0200 Subject: [PATCH 169/218] some code normalization. --- src/spells.c | 207 +++++++++++++++++++++++++-------------------------- src/spells.h | 1 + 2 files changed, 103 insertions(+), 105 deletions(-) diff --git a/src/spells.c b/src/spells.c index 332647fae..8f74eaf36 100644 --- a/src/spells.c +++ b/src/spells.c @@ -6448,6 +6448,99 @@ int sp_becomewyrm(castorder * co) return 0; } +/* ------------------------------------------------------------- */ +/* Name: Plappermaul +* Stufe: 4 +* Gebiet: Cerddor +* Kategorie: Einheit +* +* Wirkung: +* Einheit ausspionieren. Gibt auch Zauber und Kampfstatus aus. Wirkt +* gegen Magieresistenz. Ist diese zu hoch, so wird der Zauber entdeckt +* (Meldung) und der Zauberer erhaelt nur die Talente, nicht die Werte +* der Einheit und auch keine Zauber. +* +* Flag: +* (UNITSPELL | TESTCANSEE) +*/ +static int sp_babbler(castorder * co) +{ + unit *target; + region *r = co_get_region(co); + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + message *msg; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) + return 0; + + target = pa->param[0]->data.u; + + if (target->faction == mage->faction) { + /* Die Einheit ist eine der unsrigen */ + cmistake(mage, co->order, 45, MSG_MAGIC); + } + + /* Magieresistenz Unit */ + if (target_resists_magic(mage, target, TYP_UNIT, 0)) { + spy_message(5, mage, target); + msg = msg_message("babbler_resist", "unit mage", target, mage); + } + else { + spy_message(100, mage, target); + msg = msg_message("babbler_effect", "unit", target); + } + r_addmessage(r, target->faction, msg); + msg_release(msg); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Traumdeuten +* Stufe: 7 +* Kategorie: Einheit +* +* Wirkung: +* Wirkt gegen Magieresistenz. Spioniert die Einheit aus. Gibt alle +* Gegenstaende, Talente mit Stufe, Zauber und Kampfstatus an. +* +* Magieresistenz hier pruefen, wegen Fehlermeldung +* +* Flag: +* (UNITSPELL) +*/ +static int sp_readmind(castorder * co) +{ + unit *target; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) + return 0; + + target = pa->param[0]->data.u; + + if (target->faction == mage->faction) { + /* Die Einheit ist eine der unsrigen */ + cmistake(mage, co->order, 45, MSG_MAGIC); + } + + /* Magieresistenz Unit */ + if (target_resists_magic(mage, target, TYP_UNIT, 0)) { + cmistake(mage, co->order, 180, MSG_MAGIC); + /* "Fuehlt sich beobachtet" */ + ADDMSG(&target->faction->msgs, msg_message("stealdetect", "unit", target)); + return 0; + } + spy_message(2, mage, target); + + return cast_level; +} + typedef struct spelldata { const char *sname; spell_f cast; @@ -6567,7 +6660,7 @@ static spelldata spell_functions[] = { { "concealing_aura", sp_itemcloak, 0 }, { "tybiedfumbleshield", sp_fumbleshield, 0 }, #ifdef SHOWASTRAL_NOT_BORKED - { "show_astral", sp_showastral, 0}, + { "show_astral", sp_showastral, 0 }, #endif { "resist_magic", sp_resist_magic_bonus, 0 }, { "keeploot", sp_keeploot, 0 }, @@ -6605,6 +6698,14 @@ static spelldata spell_functions[] = { { "firestorm", sp_immolation, 0 }, { "coldfront", sp_immolation, 0 }, { "acidrain", sp_immolation, 0 }, + { "blabbermouth", sp_babbler, NULL }, + { "summon_familiar", sp_summon_familiar, NULL }, + { "meteor_rain", sp_kampfzauber, NULL }, + { "fireball", sp_kampfzauber, NULL }, + { "hail", sp_kampfzauber, NULL }, + { "readmind", sp_readmind, NULL }, + { "blessedharvest", sp_blessedharvest, NULL }, + { "raindance", sp_blessedharvest, NULL }, { 0, 0, 0 } }; @@ -6622,101 +6723,6 @@ static void register_spelldata(void) } } -/* ------------------------------------------------------------- */ -/* Name: Plappermaul -* Stufe: 4 -* Gebiet: Cerddor -* Kategorie: Einheit -* -* Wirkung: -* Einheit ausspionieren. Gibt auch Zauber und Kampfstatus aus. Wirkt -* gegen Magieresistenz. Ist diese zu hoch, so wird der Zauber entdeckt -* (Meldung) und der Zauberer erhaelt nur die Talente, nicht die Werte -* der Einheit und auch keine Zauber. -* -* Flag: -* (UNITSPELL | TESTCANSEE) -*/ -static int sp_babbler(castorder * co) -{ - unit *target; - region *r = co_get_region(co); - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - message *msg; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) - return 0; - - target = pa->param[0]->data.u; - - if (target->faction == mage->faction) { - /* Die Einheit ist eine der unsrigen */ - cmistake(mage, co->order, 45, MSG_MAGIC); - } - - /* Magieresistenz Unit */ - if (target_resists_magic(mage, target, TYP_UNIT, 0)) { - spy_message(5, mage, target); - msg = msg_message("babbler_resist", "unit mage", target, mage); - } - else { - spy_message(100, mage, target); - msg = msg_message("babbler_effect", "unit", target); - } - r_addmessage(r, target->faction, msg); - msg_release(msg); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Traumdeuten -* Stufe: 7 -* Kategorie: Einheit -* -* Wirkung: -* Wirkt gegen Magieresistenz. Spioniert die Einheit aus. Gibt alle -* Gegenstaende, Talente mit Stufe, Zauber und Kampfstatus an. -* -* Magieresistenz hier pruefen, wegen Fehlermeldung -* -* Flag: -* (UNITSPELL) -*/ -static int sp_readmind(castorder * co) -{ - unit *target; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) - return 0; - - target = pa->param[0]->data.u; - - if (target->faction == mage->faction) { - /* Die Einheit ist eine der unsrigen */ - cmistake(mage, co->order, 45, MSG_MAGIC); - } - - /* Magieresistenz Unit */ - if (target_resists_magic(mage, target, TYP_UNIT, 0)) { - cmistake(mage, co->order, 180, MSG_MAGIC); - /* "Fuehlt sich beobachtet" */ - ADDMSG(&target->faction->msgs, msg_message("stealdetect", "unit", target)); - return 0; - } - spy_message(2, mage, target); - - return cast_level; -} - -void register_magicresistance(void); - void register_spells(void) { register_borders(); @@ -6729,15 +6735,6 @@ void register_spells(void) ct_register(&ct_firewall); ct_register(&ct_deathcloud); - add_spellcast("blabbermouth", sp_babbler); - add_spellcast("summon_familiar", sp_summon_familiar); - add_spellcast("meteor_rain", sp_kampfzauber); - add_spellcast("fireball", sp_kampfzauber); - add_spellcast("hail", sp_kampfzauber); - add_spellcast("readmind", sp_readmind); - add_spellcast("blessedharvest", sp_blessedharvest); - add_spellcast("raindance", sp_blessedharvest); - register_spelldata(); register_unitcurse(); diff --git a/src/spells.h b/src/spells.h index 65270a164..275f41f7a 100644 --- a/src/spells.h +++ b/src/spells.h @@ -27,6 +27,7 @@ extern "C" { struct unit; struct message; + void register_magicresistance(void); void register_spells(void); void set_spelldata(struct spell *sp); From c281a1e5c9ac9f02524da9e18790c8a6233bf09d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 1 May 2017 13:26:17 +0200 Subject: [PATCH 170/218] compatibility code for old data that contains a caldera. --- src/helpers.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/helpers.c b/src/helpers.c index 700850018..8ba6f8942 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -18,6 +18,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include #include #include @@ -446,8 +447,23 @@ use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord) return result; } +/* compat code for old data files */ +static int caldera_read(trigger * t, struct gamedata *data) +{ + UNUSED_ARG(t); + read_building_reference(data); + return AT_READ_FAIL; +} + +struct trigger_type tt_caldera = { + "caldera", + NULL, NULL, NULL, NULL, + caldera_read +}; + void register_tolua_helpers(void) { + tt_register(&tt_caldera); at_register(&at_direction); at_register(&at_building_action); From 79de2ba2ed747fa7c051f26cd3fe2205624c7a91 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 1 May 2017 13:26:17 +0200 Subject: [PATCH 171/218] compatibility code for old data that contains a caldera. --- src/helpers.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/helpers.c b/src/helpers.c index 59695e9b4..e30daf278 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -18,6 +18,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include #include #include @@ -455,6 +456,21 @@ use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord) return result; } +/* compat code for old data files */ +static int caldera_read(trigger * t, struct gamedata *data) +{ + UNUSED_ARG(t); + read_building_reference(data); + return AT_READ_FAIL; +} + +struct trigger_type tt_caldera = { + "caldera", + NULL, NULL, NULL, NULL, + caldera_read +}; + + int tolua_toid(lua_State * L, int idx, int def) { int no = 0; @@ -471,6 +487,7 @@ int tolua_toid(lua_State * L, int idx, int def) void register_tolua_helpers(void) { + tt_register(&tt_caldera); at_register(&at_direction); at_register(&at_building_action); From 22c05963fddcf95fd47c0cbe7db9b4469770c516 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 1 May 2017 14:49:06 +0200 Subject: [PATCH 172/218] fix illusioncastle reporting. --- src/kernel/build.h | 8 +------- src/kernel/building.c | 1 - src/reports.c | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/kernel/build.h b/src/kernel/build.h index 323003efd..39916365a 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -60,13 +60,7 @@ extern "C" { } extra; struct construction *improvement; - /* next level, if upgradable. if more than one of these items - * can be built (weapons, armour) per turn, must not be NULL, - * but point to the same type again: - * const_sword.improvement = &const_sword - * last level of a building points to NULL, as do objects of - * an unlimited size. - */ + /* next level, if upgradable. */ } construction; void free_construction(struct construction *cons); diff --git a/src/kernel/building.c b/src/kernel/building.c index 9decc9039..bb97f57b8 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -192,7 +192,6 @@ const char *buildingtype(const building_type * btype, const building * b, int bs } if (btype->construction && btype->construction->extra.name) { if (b) { - assert(b->type == btype); bsize = adjust_size(b, bsize); } for (con = btype->construction; con; con = con->improvement) { diff --git a/src/reports.c b/src/reports.c index 353ed09fe..9af18c1d2 100644 --- a/src/reports.c +++ b/src/reports.c @@ -386,7 +386,7 @@ const char **illusion) if (illusion) { *illusion = NULL; - if (is_building_type(b->type, "illusioncastle")) { + if (b->attribs && is_building_type(b->type, "illusioncastle")) { const attrib *a = a_find(b->attribs, &at_icastle); if (a != NULL) { *illusion = buildingtype(icastle_type(a), b, b->size); From 3b11067825ec2003d28dab6a5333234088b10ebd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 1 May 2017 15:07:54 +0200 Subject: [PATCH 173/218] add a test for illusion buildings. --- src/magic.test.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/magic.test.c b/src/magic.test.c index 3f279315c..e2e695bbe 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -4,7 +4,7 @@ #include "teleport.h" #include "give.h" -#include +#include #include #include #include @@ -14,10 +14,12 @@ #include #include #include -#include + +#include #include #include +#include #include #include @@ -460,6 +462,27 @@ static void test_familiar_mage(CuTest *tc) { test_cleanup(); } +static void test_illusioncastle(CuTest *tc) +{ + building *b; + building_type *btype, *bt_icastle; + const attrib *a; + test_setup(); + btype = test_create_buildingtype("castle"); + bt_icastle = test_create_buildingtype("illusioncastle"); + b = test_create_building(test_create_region(0, 0, NULL), bt_icastle); + b->size = 1; + make_icastle(b, btype, 10); + a = a_find(b->attribs, &at_icastle); + CuAssertPtrNotNull(tc, a); + CuAssertPtrEquals(tc, btype, (void *)icastle_type(a)); + CuAssertPtrEquals(tc, bt_icastle, (void *)b->type); + CuAssertStrEquals(tc, "castle", buildingtype(btype, b, b->size)); + btype->construction->extra.name = strdup("site"); + CuAssertStrEquals(tc, "site", buildingtype(btype, b, b->size)); + test_cleanup(); +} + CuSuite *get_magic_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -477,6 +500,7 @@ CuSuite *get_magic_suite(void) SUITE_ADD_TEST(suite, test_hasspell); SUITE_ADD_TEST(suite, test_magic_resistance); SUITE_ADD_TEST(suite, test_max_spellpoints); + SUITE_ADD_TEST(suite, test_illusioncastle); DISABLE_TEST(suite, test_familiar_mage); return suite; } From 7b9305f005e606373d2ab6a536a00731f96704aa Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 1 May 2017 15:25:46 +0200 Subject: [PATCH 174/218] missing include --- src/magic.test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/magic.test.c b/src/magic.test.c index e2e695bbe..3e2073fc4 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -23,6 +23,7 @@ #include #include +#include void test_updatespells(CuTest * tc) { From fa7a3e246bdfc88a8a80a13af64a4406e7a15cd5 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 1 May 2017 17:04:28 +0200 Subject: [PATCH 175/218] eliminate spell->id. clean up some spell functions used by more than one spell. --- src/kernel/equipment.test.c | 2 +- src/kernel/jsonconf.c | 4 +- src/kernel/spell.c | 28 +----- src/kernel/spell.h | 4 +- src/kernel/spell.test.c | 31 +------ src/kernel/spellbook.test.c | 2 +- src/kernel/xmlreader.c | 4 +- src/magic.c | 21 ++--- src/magic.test.c | 20 ++--- src/spells.c | 56 +++++++++++- src/spells/combatspells.c | 174 ++++++------------------------------ src/spells/combatspells.h | 6 +- src/tests.c | 2 +- 13 files changed, 112 insertions(+), 242 deletions(-) diff --git a/src/kernel/equipment.test.c b/src/kernel/equipment.test.c index afd53849e..1e6bf1819 100644 --- a/src/kernel/equipment.test.c +++ b/src/kernel/equipment.test.c @@ -23,7 +23,7 @@ void test_equipment(CuTest * tc) enable_skill(SK_MAGIC, true); it_horses = test_create_itemtype("horse"); CuAssertPtrNotNull(tc, it_horses); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); CuAssertPtrNotNull(tc, sp); CuAssertPtrEquals(tc, 0, get_equipment("herpderp")); diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 6dd3909b5..9da82c88d 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -588,8 +588,8 @@ static void json_spells(cJSON *json) { for (child = json->child; child; child = child->next) { if (child->type == cJSON_Object) { spell *sp; - cJSON * item = cJSON_GetObjectItem(child, "index"); - sp = create_spell(child->string, item ? item->valueint : 0); + cJSON * item; + sp = create_spell(child->string); for (item = child->child; item; item = item->next) { if (strcmp(item->string, "index") == 0) { continue; diff --git a/src/kernel/spell.c b/src/kernel/spell.c index 900f98ff0..0db20fe48 100644 --- a/src/kernel/spell.c +++ b/src/kernel/spell.c @@ -85,7 +85,7 @@ void add_spell(struct selist **slistp, spell * sp) } } -spell * create_spell(const char * name, unsigned int id) +spell * create_spell(const char * name) { spell * sp; char buffer[64]; @@ -100,7 +100,6 @@ spell * create_spell(const char * name, unsigned int id) sp = (spell *)calloc(1, sizeof(spell)); len = cb_new_kv(name, len, &sp, sizeof(sp), buffer); if (cb_insert(&cb_spells, buffer, len) == CB_SUCCESS) { - sp->id = id ? id : hashstring(name); sp->sname = strdup(name); add_spell(&spells, sp); return sp; @@ -144,31 +143,6 @@ spell *find_spell(const char *name) return sp; } -spell *find_spellbyid(unsigned int id) -{ - selist *ql; - int qi; - - if (id == 0) - return NULL; - for (qi = 0, ql = spells; ql; selist_advance(&ql, &qi, 1)) { - spell *sp = (spell *)selist_get(ql, qi); - if (sp->id == id) { - return sp; - } - } - for (qi = 0, ql = spells; ql; selist_advance(&ql, &qi, 1)) { - spell *sp = (spell *)selist_get(ql, qi); - unsigned int hashid = hashstring(sp->sname); - if (hashid == id) { - return sp; - } - } - - log_warning("cannot find spell by id: %u\n", id); - return NULL; -} - struct spellref *spellref_create(spell *sp, const char *name) { spellref *spref = malloc(sizeof(spellref)); diff --git a/src/kernel/spell.h b/src/kernel/spell.h index da077347a..47d9644cf 100644 --- a/src/kernel/spell.h +++ b/src/kernel/spell.h @@ -34,7 +34,6 @@ extern "C" { typedef void(*fumble_f)(const struct castorder * co); typedef struct spell { - unsigned int id; char *sname; char *syntax; char *parameter; @@ -58,9 +57,8 @@ extern "C" { int sp_antimagiczone(struct castorder *co); - struct spell * create_spell(const char * name, unsigned int id); + struct spell * create_spell(const char * name); struct spell * find_spell(const char *name); - struct spell * find_spellbyid(unsigned int i); void add_spell(struct selist **slistp, spell * sp); void free_spells(void); diff --git a/src/kernel/spell.test.c b/src/kernel/spell.test.c index 7777024ef..e5a37fd65 100644 --- a/src/kernel/spell.test.c +++ b/src/kernel/spell.test.c @@ -19,7 +19,7 @@ static void test_create_a_spell(CuTest * tc) CuAssertPtrEquals(tc, 0, spells); CuAssertPtrEquals(tc, 0, find_spell("testspell")); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); CuAssertPtrEquals(tc, sp, find_spell("testspell")); CuAssertPtrNotNull(tc, spells); test_cleanup(); @@ -37,8 +37,8 @@ static void test_create_duplicate_spell(CuTest * tc) CuAssertPtrEquals(tc, 0, find_spell("testspell")); - sp = create_spell("testspell", 0); - CuAssertPtrEquals(tc, 0, create_spell("testspell", 0)); + sp = create_spell("testspell"); + CuAssertPtrEquals(tc, 0, create_spell("testspell")); CuAssertPtrNotNull(tc, sl); CuAssertStrEquals(tc, "create_spell: duplicate name '%s'", sl->s); CuAssertPtrEquals(tc, 0, sl->next); @@ -47,28 +47,6 @@ static void test_create_duplicate_spell(CuTest * tc) test_cleanup(); } -static void test_create_spell_with_id(CuTest * tc) -{ - spell *sp; - struct log_t *log; - strlist *sl = 0; - - test_setup(); - test_log_stderr(0); - log = test_log_start(LOG_CPERROR, &sl); - - CuAssertPtrEquals(tc, 0, find_spellbyid(42)); - sp = create_spell("testspell", 42); - CuAssertPtrEquals(tc, sp, find_spellbyid(42)); - CuAssertPtrEquals(tc, 0, create_spell("testspell", 47)); - CuAssertPtrEquals(tc, 0, find_spellbyid(47)); - CuAssertPtrNotNull(tc, sl); - CuAssertStrEquals(tc, "create_spell: duplicate name '%s'", sl->s); - CuAssertPtrEquals(tc, 0, sl->next); - test_log_stop(log, sl); - test_cleanup(); -} - static void test_spellref(CuTest *tc) { spellref *ref; @@ -79,7 +57,7 @@ static void test_spellref(CuTest *tc) CuAssertPtrEquals(tc, NULL, ref->sp); CuAssertStrEquals(tc, "hodor", ref->name); CuAssertPtrEquals(tc, NULL, spellref_get(ref)); - sp = create_spell("hodor", 0); + sp = create_spell("hodor"); CuAssertPtrNotNull(tc, sp); CuAssertPtrEquals(tc, sp, spellref_get(ref)); spellref_free(ref); @@ -113,6 +91,5 @@ CuSuite *get_spell_suite(void) SUITE_ADD_TEST(suite, test_fumbles); SUITE_ADD_TEST(suite, test_create_a_spell); SUITE_ADD_TEST(suite, test_create_duplicate_spell); - SUITE_ADD_TEST(suite, test_create_spell_with_id); return suite; } diff --git a/src/kernel/spellbook.test.c b/src/kernel/spellbook.test.c index 8b997557b..37f20cced 100644 --- a/src/kernel/spellbook.test.c +++ b/src/kernel/spellbook.test.c @@ -33,7 +33,7 @@ void test_named_spellbooks(CuTest * tc) CuAssertPtrNotNull(tc, sb); CuAssertStrEquals(tc, "spells", sb->name); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); spellbook_add(sb, sp, 1); CuAssertPtrNotNull(tc, sb->spells); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 60c80dade..418a1ba6e 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1328,14 +1328,12 @@ static int parse_spells(xmlDocPtr doc) int k; spell_component *component; spell *sp; - unsigned int index; static int modes[] = { 0, PRECOMBATSPELL, COMBATSPELL, POSTCOMBATSPELL }; /* spellname */ - index = xml_ivalue(node, "index", 0); propValue = xmlGetProp(node, BAD_CAST "name"); assert(propValue != NULL); - sp = create_spell((const char *)propValue, index); + sp = create_spell((const char *)propValue); xmlFree(propValue); if (!sp) { continue; diff --git a/src/magic.c b/src/magic.c index 602207c02..4e74d2cb4 100644 --- a/src/magic.c +++ b/src/magic.c @@ -339,23 +339,16 @@ sc_mage *get_mage(const unit * u) static int read_seenspell(attrib * a, void *owner, struct gamedata *data) { storage *store = data->store; - int i; spell *sp = 0; char token[32]; READ_TOK(store, token, sizeof(token)); - i = atoip(token); - if (i != 0) { - sp = find_spellbyid((unsigned int)i); + if (data->version < UNIQUE_SPELLS_VERSION) { + READ_INT(store, 0); /* ignore mtype */ } - else { - if (data->version < UNIQUE_SPELLS_VERSION) { - READ_INT(store, 0); /* ignore mtype */ - } - sp = find_spell(token); - if (!sp) { - log_warning("read_seenspell: could not find spell '%s'\n", token); - } + sp = find_spell(token); + if (!sp) { + log_warning("read_seenspell: could not find spell '%s'\n", token); } if (!sp) { return AT_READ_FAIL; @@ -898,9 +891,7 @@ void pay_spell(unit * u, const spell * sp, int cast_level, int range) bool knowsspell(const region * r, const unit * u, const spell * sp) { /* Ist überhaupt ein gültiger Spruch angegeben? */ - if (!sp || sp->id == 0) { - return false; - } + assert(sp); /* steht der Spruch in der Spruchliste? */ return u_hasspell(u, sp) != 0; } diff --git a/src/magic.test.c b/src/magic.test.c index e2e695bbe..89d24befc 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -34,7 +34,7 @@ void test_updatespells(CuTest * tc) test_create_race("human"); f = test_create_faction(0); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); CuAssertPtrNotNull(tc, sp); book = create_spellbook("spells"); @@ -67,7 +67,7 @@ void test_spellbooks(CuTest * tc) CuAssertStrEquals(tc, "herp", herp->name); CuAssertStrEquals(tc, "derp", derp->name); - sp = create_spell(sname, 0); + sp = create_spell(sname); spellbook_add(herp, sp, 1); CuAssertPtrNotNull(tc, sp); entry = spellbook_get(herp, sp); @@ -170,7 +170,7 @@ void test_getspell_unit(CuTest * tc) set_level(u, SK_MAGIC, 1); lang = test_create_locale(); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); @@ -199,7 +199,7 @@ void test_getspell_faction(CuTest * tc) set_level(u, SK_MAGIC, 1); lang = test_create_locale(); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); @@ -229,7 +229,7 @@ void test_getspell_school(CuTest * tc) set_level(u, SK_MAGIC, 1); lang = test_create_locale(); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); @@ -256,7 +256,7 @@ void test_set_pre_combatspell(CuTest * tc) u = test_create_unit(f, r); enable_skill(SK_MAGIC, true); set_level(u, SK_MAGIC, 1); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); sp->sptyp |= PRECOMBATSPELL; unit_add_spell(u, 0, sp, 1); @@ -288,7 +288,7 @@ void test_set_main_combatspell(CuTest * tc) u = test_create_unit(f, r); enable_skill(SK_MAGIC, true); set_level(u, SK_MAGIC, 1); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); sp->sptyp |= COMBATSPELL; unit_add_spell(u, 0, sp, 1); @@ -320,7 +320,7 @@ void test_set_post_combatspell(CuTest * tc) u = test_create_unit(f, r); enable_skill(SK_MAGIC, true); set_level(u, SK_MAGIC, 1); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); sp->sptyp |= POSTCOMBATSPELL; unit_add_spell(u, 0, sp, 1); @@ -350,7 +350,7 @@ void test_hasspell(CuTest * tc) f->magiegebiet = M_TYBIED; u = test_create_unit(f, r); enable_skill(SK_MAGIC, true); - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); sp->sptyp |= POSTCOMBATSPELL; unit_add_spell(u, 0, sp, 2); @@ -379,7 +379,7 @@ void test_multi_cast(CuTest *tc) { struct locale * lang; test_setup(); - sp = create_spell("fireball", 0); + sp = create_spell("fireball"); sp->cast_fun = cast_fireball; CuAssertPtrEquals(tc, sp, find_spell("fireball")); diff --git a/src/spells.c b/src/spells.c index 8bf30de88..142a96a7b 100644 --- a/src/spells.c +++ b/src/spells.c @@ -6444,6 +6444,54 @@ int sp_break_curse(castorder * co) return cast_level; } +static int sp_flee(castorder *co) { + if (co->force <= 0) { + return 0; + } + return flee_spell(co, 4); +} + +static int sp_song_of_fear(castorder *co) { + if (co->force <= 0) { + return 0; + } + return flee_spell(co, 3); +} + +static int sp_aura_of_fear(castorder *co) { + if (co->force <= 0) { + return 0; + } + return flee_spell(co, 5); +} + +static int sp_armor_shield(struct castorder * co) { + return armor_spell(co, 3, 20); +} + +static int sp_bark_skin(struct castorder * co) { + return armor_spell(co, 4, 1); +} + +static int sp_kampfzauber(castorder *co) { + const spell * sp = co->sp; + if (co->force <= 0) { + return 0; + } + else if (strcmp(sp->sname, "fireball") == 0) { + return damage_spell(co, 0, 0); + } + else if (strcmp(sp->sname, "hail") == 0) { + return damage_spell(co, 2, 4); + } + else if (strcmp(sp->sname, "meteor_rain") == 0) { + return damage_spell(co, 1, 1); + } + else { + return damage_spell(co, 10, 10); + } +} + /* ------------------------------------------------------------- */ int sp_becomewyrm(castorder * co) { @@ -6486,7 +6534,7 @@ static spelldata spell_functions[] = { { "holyground", sp_holyground, 0 }, { "summonent", sp_summonent, 0 }, { "blessstonecircle", sp_blessstonecircle, 0 }, - { "barkskin", sp_armorshield, 0 }, + { "barkskin", sp_bark_skin, 0 }, { "summonfireelemental", sp_drought, 0 }, { "maelstrom", sp_maelstrom, 0 }, { "magic_roots", sp_mallorn, 0 }, @@ -6539,7 +6587,7 @@ static spelldata spell_functions[] = { { "appeasement", sp_denyattack, 0 }, { "song_of_healing", sp_healing, 0 }, { "generous", sp_generous, 0 }, - { "song_of_fear", sp_flee, 0 }, + { "song_of_fear", sp_song_of_fear, 0 }, { "courting", sp_recruit, 0 }, { "song_of_confusion", sp_chaosrow, 0 }, { "heroic_song", sp_hero, 0 }, @@ -6591,7 +6639,7 @@ static spelldata spell_functions[] = { { "combat_speed", sp_speed, 0 }, { "view_reality", sp_viewreality, 0 }, { "double_time", sp_speed2, 0 }, - { "armor_shield", sp_armorshield, 0 }, + { "armor_shield", sp_armor_shield, 0 }, { "living_rock", sp_movecastle, 0 }, { "astral_disruption", sp_disruptastral, 0 }, { "sacrifice_strength", sp_permtransfer, 0 }, @@ -6603,7 +6651,7 @@ static spelldata spell_functions[] = { { "icy_dragonbreath", sp_dragonodem, 0 }, { "powerful_dragonbreath", sp_dragonodem, 0 }, { "drain_skills", sp_dragonodem, 0 }, - { "aura_of_fear", sp_flee, 0 }, + { "aura_of_fear", sp_aura_of_fear, 0 }, { "immolation", sp_immolation, 0 }, { "firestorm", sp_immolation, 0 }, { "coldfront", sp_immolation, 0 }, diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c index 8544a4a2d..08f38c8ea 100644 --- a/src/spells/combatspells.c +++ b/src/spells/combatspells.c @@ -47,31 +47,6 @@ #define EFFECT_HEALING_SPELL 5 -/* Some spells with a fixed, known ID (in XML). - * TODO: this method of identifying spells is error-prone, - * do not use it for new spells. */ -enum { - SPL_FIREBALL = 4, - SPL_HAGEL = 5, - SPL_CHAOSROW = 18, - SPL_FLEE = 20, - SPL_SONG_OF_FEAR = 21, - SPL_BERSERK = 22, - SPL_BLOODTHIRST = 23, - SPL_WINDSHIELD = 59, - SPL_HERO = 76, - SPL_METEORRAIN = 108, - SPL_REDUCESHIELD = 109, - SPL_ARMORSHIELD = 110, - SPL_DRAIG_FUMBLESHIELD = 143, - SPL_GWYRRD_FUMBLESHIELD = 144, - SPL_CERDDOR_FUMBLESHIELD = 145, - SPL_TYBIED_FUMBLESHIELD = 146, - SPL_SHADOWKNIGHTS = 147, - SPL_SHOCKWAVE = 163, - SPL_AURA_OF_FEAR = 175 -}; - /* ------------------------------------------------------------------ */ /* Kampfzauberfunktionen */ @@ -134,44 +109,23 @@ static double get_force(double power, int formel) } /* Generischer Kampfzauber */ -int sp_kampfzauber(struct castorder * co) +int damage_spell(struct castorder * co, int dmg, int strength) { fighter * fi = co->magician.fig; int level = co->level; - double power = co->force; const spell * sp = co->sp; + double power = co->force; battle *b = fi->side->battle; troop at, dt; message *m; /* Immer aus der ersten Reihe nehmen */ - int force, enemies; - int killed = 0; - const char *damage; + int enemies, killed = 0; + int force = lovar(get_force(power, strength)); + const char *damage = spell_damage(dmg); - if (power <= 0) - return 0; at.fighter = fi; at.index = 0; - switch (sp->id) { - /* lovar halbiert im Schnitt! */ - case SPL_FIREBALL: - damage = spell_damage(0); - force = lovar(get_force(power, 0)); - break; - case SPL_HAGEL: - damage = spell_damage(2); - force = lovar(get_force(power, 4)); - break; - case SPL_METEORRAIN: - damage = spell_damage(1); - force = lovar(get_force(power, 1)); - break; - default: - damage = spell_damage(10); - force = lovar(get_force(power, 10)); - } - enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE); if (enemies == 0) { message *m = @@ -257,13 +211,7 @@ int sp_stun(struct castorder * co) if (power <= 0) return 0; - switch (sp->id) { - case SPL_SHOCKWAVE: - force = lovar(get_force(power, 1)); - break; - default: - assert(0); - } + force = lovar(get_force(power, 1)); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); if (!enemies) { @@ -956,6 +904,7 @@ int sp_chaosrow(struct castorder * co) message *m; const char *mtype; int qi, k = 0; + bool chaosrow = strcmp(sp->sname, "chaosrow") == 0; if (!count_enemies(b, fi, FIGHT_ROW, NUMROWS, SELECT_ADVANCE | SELECT_FIND)) { m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); @@ -964,10 +913,7 @@ int sp_chaosrow(struct castorder * co) return 0; } - if (sp->id == SPL_CHAOSROW) - power *= 40; - else - power = get_force(power, 5); + power = chaosrow ? (power * 40) : get_force(power, 5); fgs = fighters(b, fi->side, FIGHT_ROW, NUMROWS, FS_ENEMY); scramble_fighters(fgs); @@ -1019,7 +965,7 @@ int sp_chaosrow(struct castorder * co) } selist_free(fgs); - if (sp->id == SPL_CHAOSROW) { + if (chaosrow) { mtype = (k > 0) ? "sp_chaosrow_effect_1" : "sp_chaosrow_effect_0"; } else { @@ -1034,33 +980,20 @@ int sp_chaosrow(struct castorder * co) /* Gesang der Furcht (Kampfzauber) */ /* Panik (Pr�kampfzauber) */ -int sp_flee(struct castorder * co) +int flee_spell(struct castorder * co, int strength) { fighter * fi = co->magician.fig; int level = co->level; - double power = co->force; const spell * sp = co->sp; battle *b = fi->side->battle; unit *mage = fi->unit; selist *fgs, *ql; - int force, n, qi; - int panik = 0; + int n, qi, panik = 0; message *msg; + double power = co->force; + int force; - switch (sp->id) { - case SPL_FLEE: - force = (int)get_force(power, 4); - break; - case SPL_SONG_OF_FEAR: - force = (int)get_force(power, 3); - break; - case SPL_AURA_OF_FEAR: - force = (int)get_force(power, 5); - break; - default: - force = (int)get_force(power, 10); - } - + force = (int)get_force(power, strength); if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE | SELECT_FIND)) { msg = msg_message("sp_flee_effect_0", "mage spell", mage, sp); message_all(b, msg); @@ -1116,16 +1049,8 @@ int sp_hero(struct castorder * co) int targets = 0; message *m; - switch (sp->id) { - case SPL_HERO: - df_bonus = (int)(power / 5); - force = MAX(1, lovar(get_force(power, 4))); - break; - - default: - df_bonus = 1; - force = MAX(1, (int)power); - } + df_bonus = (int)(power / 5); + force = MAX(1, lovar(get_force(power, 4))); allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE, ALLY_ANY); @@ -1170,19 +1095,9 @@ int sp_berserk(struct castorder * co) int targets = 0; message *m; - switch (sp->id) { - case SPL_BERSERK: - case SPL_BLOODTHIRST: - at_bonus = MAX(1, level / 3); - df_malus = 2; - force = (int)get_force(power, 2); - break; - - default: - at_bonus = 1; - df_malus = 0; - force = (int)power; - } + at_bonus = MAX(1, level / 3); + df_malus = 2; + force = (int)get_force(power, 2); allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE, ALLY_ANY); @@ -1327,16 +1242,9 @@ int sp_windshield(struct castorder * co) int enemies; message *m; - switch (sp->id) { - case SPL_WINDSHIELD: - force = (int)get_force(power, 4); - at_malus = level / 4; - break; + force = (int)get_force(power, 4); + at_malus = level / 4; - default: - force = (int)power; - at_malus = 2; - } enemies = count_enemies(b, fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE); if (!enemies) { m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); @@ -1429,7 +1337,7 @@ static void do_meffect(fighter * af, int typ, int effect, int duration) me->duration = duration; } -int sp_armorshield(struct castorder * co) +int armor_spell(struct castorder * co, int per_level, int time_multi) { fighter * fi = co->magician.fig; int level = co->level; @@ -1445,16 +1353,8 @@ int sp_armorshield(struct castorder * co) /* gibt R�stung +effect f�r duration Treffer */ - switch (sp->id) { - case SPL_ARMORSHIELD: - effect = level / 3; - duration = (int)(20 * power * power); - break; - - default: - effect = level / 4; - duration = (int)(power * power); - } + effect = level / per_level; + duration = (int)(time_multi * power * power); do_meffect(fi, SHIELD_ARMOR, effect, duration); return level; } @@ -1475,16 +1375,9 @@ int sp_reduceshield(struct castorder * co) /* jeder Schaden wird um effect% reduziert bis der Schild duration * Trefferpunkte aufgefangen hat */ - switch (sp->id) { - case SPL_REDUCESHIELD: - effect = 50; - duration = (int)(50 * power * power); - break; + effect = 50; + duration = (int)(50 * power * power); - default: - effect = level * 3; - duration = (int)get_force(power, 5); - } do_meffect(fi, SHIELD_REDUCE, effect, duration); return level; } @@ -1503,20 +1396,9 @@ int sp_fumbleshield(struct castorder * co) msg_release(m); /* der erste Zauber schl�gt mit 100% fehl */ + duration = 100; + effect = MAX(1, 25 - level); - switch (sp->id) { - case SPL_DRAIG_FUMBLESHIELD: - case SPL_GWYRRD_FUMBLESHIELD: - case SPL_CERDDOR_FUMBLESHIELD: - case SPL_TYBIED_FUMBLESHIELD: - duration = 100; - effect = MAX(1, 25 - level); - break; - - default: - duration = 100; - effect = 10; - } do_meffect(fi, SHIELD_BLOCK, effect, duration); return level; } diff --git a/src/spells/combatspells.h b/src/spells/combatspells.h index cf07c2a89..78da949e8 100644 --- a/src/spells/combatspells.h +++ b/src/spells/combatspells.h @@ -23,12 +23,10 @@ extern "C" { int sp_fumbleshield(struct castorder * co); int sp_shadowknights(struct castorder * co); int sp_combatrosthauch(struct castorder * co); - int sp_kampfzauber(struct castorder * co); int sp_healing(struct castorder * co); int sp_keeploot(struct castorder * co); int sp_reanimate(struct castorder * co); int sp_chaosrow(struct castorder * co); - int sp_flee(struct castorder * co); int sp_berserk(struct castorder * co); int sp_tiredsoldiers(struct castorder * co); int sp_reeling_arrows(struct castorder * co); @@ -51,6 +49,10 @@ extern "C" { int sp_undeadhero(struct castorder * co); int sp_immolation(struct castorder * co); + int flee_spell(struct castorder * co, int strength); + int damage_spell(struct castorder * co, int dmg, int strength); + int armor_spell(struct castorder * co, int per_level, int time_multi); + #ifdef __cplusplus } #endif diff --git a/src/tests.c b/src/tests.c index a9b4878b6..19deb91ea 100644 --- a/src/tests.c +++ b/src/tests.c @@ -356,7 +356,7 @@ void test_create_castorder(castorder *co, unit *u, int level, float force, int r spell * test_create_spell(void) { spell *sp; - sp = create_spell("testspell", 0); + sp = create_spell("testspell"); sp->components = (spell_component *)calloc(4, sizeof(spell_component)); assert_alloc(sp->components); From 8e9866f0ce4b0e6f7ee636a7901ffe9b8a9a0812 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 1 May 2017 19:09:00 +0200 Subject: [PATCH 176/218] additional tests for spells. also some support functionality for lua tests. --- scripts/tests/e2/init.lua | 1 + scripts/tests/e3/init.lua | 3 +- scripts/tests/spells.lua | 83 +++++++++++++++++++++++++++++++++++++++ src/bind_faction.c | 18 +++++++++ src/bind_unit.c | 8 ++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 scripts/tests/spells.lua diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index 46afc966a..4b4fe7dd4 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -20,3 +20,4 @@ require 'tests.magicbag' require 'tests.process' require 'tests.xmas' require 'tests.production' +require 'tests.spells' diff --git a/scripts/tests/e3/init.lua b/scripts/tests/e3/init.lua index 06e03d9b4..fc0586f89 100644 --- a/scripts/tests/e3/init.lua +++ b/scripts/tests/e3/init.lua @@ -5,11 +5,12 @@ require 'tests.e3.rules' require 'tests.e3.parser' require 'tests.e3.morale' require 'tests.e3.items' +require 'tests.e3.production' +require 'tests.spells' require 'tests.economy' require 'tests.orders' require 'tests.common' require 'tests.items' require 'tests.magicbag' require 'tests.process' -require 'tests.e3.production' require 'tests.production' diff --git a/scripts/tests/spells.lua b/scripts/tests/spells.lua new file mode 100644 index 000000000..e3c0a3021 --- /dev/null +++ b/scripts/tests/spells.lua @@ -0,0 +1,83 @@ +require 'lunit' +module("tests.spells", package.seeall, lunit.testcase) + +function setup() + eressea.free_game() + eressea.settings.set("nmr.removenewbie", "0") + eressea.settings.set("nmr.timeout", "0") + eressea.settings.set("NewbieImmunity", "0") + eressea.settings.set("rules.food.flags", "4") + eressea.settings.set("rules.encounters", "0") + eressea.settings.set("magic.regeneration.enable", "0") +end + +function test_create_bogus() + local r = region.create(0, 0, "plain") + local f = faction.create("human") + local u = unit.create(f, r, 1) + u.race = "elf" + u:set_skill("magic", 10) + u.magic = 'gwyrrd' + u:clear_orders() + u:add_order("ZAUBERE 'Erschaffe Katastrophe'") + process_orders() + assert_equal(f.messages[3], 'error173') -- HACKity HACK +end + +function test_create_roi() + local r = region.create(0, 0, "plain") + local f = faction.create("human") + local u = unit.create(f, r, 1) + u.race = "elf" + u:set_skill("magic", 10) + u.magic = 'gwyrrd' + u.aura = 100 + u:add_item("money", 3000) + u:add_spell("create_roi") + u:clear_orders() + u:add_order("ZAUBERE 'Erschaffe einen Ring der Unsichtbarkeit'") + local amax = u.aura_max + process_orders() + assert_equal(1, u:get_item("roi")) + assert_equal(50, u.aura) + assert_equal(amax - 1, u.aura_max) +end + +function test_create_aots() + local r = region.create(0, 0, "plain") + local f = faction.create("human") + local u = unit.create(f, r, 1) + u.race = "elf" + u:set_skill("magic", 10) + u.magic = 'gwyrrd' + u.aura = 100 + u:add_item("money", 3000) + u:add_spell("create_aots") + u:clear_orders() + u:add_order("ZAUBERE 'Erschaffe ein Amulett des wahren Sehens'") + local amax = u.aura_max + process_orders() + assert_equal(1, u:get_item("aots")) + assert_equal(50, u.aura) + assert_equal(amax - 1, u.aura_max) +end + +function test_create_dreameye() + local r = region.create(0, 0, "plain") + local f = faction.create("human") + local u = unit.create(f, r, 1) + u.race = "elf" + u:set_skill("magic", 10) + u.magic = 'gwyrrd' + u.aura = 100 + u:add_item("dragonhead", 1) + u:add_spell("create_dreameye") + u:clear_orders() + u:add_order("ZAUBERE 'Erschaffe ein Traumauge'") + local amax = u.aura_max + process_orders() + assert_equal(1, u:get_item("dreameye")) + assert_equal(100, u.aura) + assert_equal(amax - 5, u.aura_max) +end + diff --git a/src/bind_faction.c b/src/bind_faction.c index d16f15936..f9321f6b5 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -268,6 +268,23 @@ static int tolua_faction_setkey(lua_State * L) return 0; } +static int tolua_faction_get_messages(lua_State * L) +{ + faction *self = (faction *)tolua_tousertype(L, 1, 0); + int i = 1; + mlist *ml; + if (!self->msgs) { + return 0; + } + lua_newtable(L); + for (ml = self->msgs->begin; ml; ml = ml->next, ++i) { + lua_pushnumber(L, i); + lua_pushstring(L, ml->msg->type->name); + lua_rawset(L, -3); + } + return 1; +} + static int tolua_faction_count_msg_type(lua_State *L) { faction *self = (faction *)tolua_tousertype(L, 1, 0); const char *str = tolua_tostring(L, 2, 0); @@ -637,6 +654,7 @@ void tolua_faction_open(lua_State * L) /* tech debt hack, siehe https://paper.dropbox.com/doc/Weihnachten-2015-5tOx5r1xsgGDBpb0gILrv#:h=Probleme-mit-Tests-(Nachtrag-0 */ tolua_function(L, TOLUA_CAST "count_msg_type", tolua_faction_count_msg_type); + tolua_variable(L, TOLUA_CAST "messages", tolua_faction_get_messages, NULL); tolua_function(L, TOLUA_CAST "get_key", tolua_faction_getkey); tolua_function(L, TOLUA_CAST "set_key", tolua_faction_setkey); diff --git a/src/bind_unit.c b/src/bind_unit.c index 34b647418..1d6579b0e 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -193,6 +193,13 @@ static int tolua_unit_set_id(lua_State * L) return 0; } +static int tolua_unit_get_auramax(lua_State * L) +{ + unit *self = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, max_spellpoints(self->region, self)); + return 1; +} + static int tolua_unit_get_hpmax(lua_State * L) { unit *self = (unit *)tolua_tousertype(L, 1, 0); @@ -1033,6 +1040,7 @@ void tolua_unit_open(lua_State * L) tolua_variable(L, TOLUA_CAST "race", &tolua_unit_get_race, tolua_unit_set_race); tolua_variable(L, TOLUA_CAST "hp_max", &tolua_unit_get_hpmax, 0); + tolua_variable(L, TOLUA_CAST "aura_max", &tolua_unit_get_auramax, 0); tolua_function(L, TOLUA_CAST "show", &tolua_bufunit); } From 83d40962d205c34c5abc1d2e58363dac593608ed Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 2 May 2017 08:45:18 +0200 Subject: [PATCH 177/218] disable randomness that causes some tests to become intermittent. fix normalvariante and chance so they work better with constant rng always returning zero --- scripts/run-tests-e2.lua | 1 + scripts/run-tests-e3.lua | 1 + scripts/tests/common.lua | 3 +++ scripts/tests/production.lua | 1 + src/bindings.c | 7 +++++++ src/util/rand.c | 4 ++-- 6 files changed, 15 insertions(+), 2 deletions(-) diff --git a/scripts/run-tests-e2.lua b/scripts/run-tests-e2.lua index 4a2b3e59e..67a534ae6 100644 --- a/scripts/run-tests-e2.lua +++ b/scripts/run-tests-e2.lua @@ -17,6 +17,7 @@ require 'eressea.path' require 'tests.e2' require 'lunit' +rng_default(0) rules = require('eressea.' .. config.rules) result = lunit.main() return result.errors + result.failed diff --git a/scripts/run-tests-e3.lua b/scripts/run-tests-e3.lua index 47bcca60b..241b3e9fd 100644 --- a/scripts/run-tests-e3.lua +++ b/scripts/run-tests-e3.lua @@ -17,6 +17,7 @@ require 'eressea.xmlconf' require 'tests.e3' require 'lunit' +rng_default(0) eressea.settings.set("rules.alliances", "0") rules = require('eressea.' .. config.rules) result = lunit.main() diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 08a7ca94f..e612a17d7 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -218,6 +218,9 @@ function test_gmtool() local r1 = region.create(1, 0, "plain") local r2 = region.create(1, 1, "plain") local r3 = region.create(1, 2, "plain") + if not gmtool then + return + end gmtool.open() gmtool.select(r1, true) gmtool.select_at(0, 1, true) diff --git a/scripts/tests/production.lua b/scripts/tests/production.lua index b470a2652..8727762d1 100644 --- a/scripts/tests/production.lua +++ b/scripts/tests/production.lua @@ -6,6 +6,7 @@ function setup() eressea.game.reset() eressea.settings.set("rules.food.flags", "4") -- food is free eressea.settings.set("NewbieImmunity", "0") + eressea.settings.set("study.random_progress", "0") end local function create_faction(race) diff --git a/src/bindings.c b/src/bindings.c index 9ea548465..d78ed8537 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -990,6 +990,12 @@ static void parse_inifile(lua_State * L, const dictionary * d, const char *secti } } +static int lua_rng_default(lua_State *L) { + UNUSED_ARG(L); + random_source_inject_constant(0); + return 0; +} + void tolua_bind_open(lua_State * L); int tolua_bindings_open(lua_State * L, const dictionary *inifile) @@ -1060,6 +1066,7 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile) tolua_function(L, TOLUA_CAST "get_ship", tolua_get_ship); tolua_function(L, TOLUA_CAST "get_building", tolua_get_building); tolua_function(L, TOLUA_CAST "get_region", tolua_get_region); + tolua_function(L, TOLUA_CAST "rng_default", lua_rng_default); tolua_function(L, TOLUA_CAST "factions", tolua_get_factions); tolua_function(L, TOLUA_CAST "regions", tolua_get_regions); tolua_function(L, TOLUA_CAST "read_turn", tolua_read_turn); diff --git a/src/util/rand.c b/src/util/rand.c index f5c8a28bc..584e8541e 100644 --- a/src/util/rand.c +++ b/src/util/rand.c @@ -46,7 +46,7 @@ double normalvariate(double mu, double sigma) double z; for (;;) { double u1 = rng_double(); - double u2 = 1.0 - rng_double(); + double u2 = rng_double(); z = NV_MAGICCONST * (u1 - 0.5) / u2; if (z * z / 4.0 <= -log(u2)) { break; @@ -73,7 +73,7 @@ bool chance(double x) { if (x >= 1.0) return true; - return rng_double() < x; + return (1-rng_double()) < x; } typedef struct random_source { From 5778bc2c93344708f04d3cbbaea00a8c32dd52df Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 2 May 2017 09:59:04 +0200 Subject: [PATCH 178/218] no more than 4 critical hits --- src/battle.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle.c b/src/battle.c index 81f0b635d..19f30e59c 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1205,11 +1205,12 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) if (type != AT_COMBATSPELL && type != AT_SPELL) { if (rule_damage & DAMAGE_CRITICAL) { double kritchance = (sk * 3 - sd) / 200.0; + int maxk = 4; kritchance = MAX(kritchance, 0.005); kritchance = MIN(0.9, kritchance); - while (chance(kritchance)) { + while (maxk-- && chance(kritchance)) { da += dice_rand(damage); } } From cb0cd87f23581a881fcc36e74367d53da24457d1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 2 May 2017 15:10:43 +0200 Subject: [PATCH 179/218] fix callbacks linkage for clang/mac --- src/kernel/CMakeLists.txt | 2 +- src/kernel/callbacks.c | 3 ++- src/kernel/callbacks.h | 6 ++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index e572d0763..fe560af7a 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -17,7 +17,7 @@ group.test.c item.test.c messages.test.c order.test.c -# pathdinder.test.c +# pathfinder.test.c plane.test.c pool.test.c race.test.c diff --git a/src/kernel/callbacks.c b/src/kernel/callbacks.c index d8070bd04..c1d52352a 100644 --- a/src/kernel/callbacks.c +++ b/src/kernel/callbacks.c @@ -1,4 +1,5 @@ #include #include "callbacks.h" -struct callbacks callbacks; +struct callback_struct callbacks = { 0 }; + diff --git a/src/kernel/callbacks.h b/src/kernel/callbacks.h index 71f3900c4..f42d25d3f 100644 --- a/src/kernel/callbacks.h +++ b/src/kernel/callbacks.h @@ -25,11 +25,13 @@ extern "C" { struct castorder; - extern struct callbacks { + struct callback_struct { int (*cast_spell)(struct castorder *co, const char *fname); - } callbacks; + }; + extern struct callback_struct callbacks; #ifdef __cplusplus } #endif #endif /* H_KRNL_CALLBACKS_H */ + From 26795ae71782c2147804b14a4e89b2eeac7de83e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 3 May 2017 21:02:30 +0200 Subject: [PATCH 180/218] guassian distribution has no endless loops. --- src/platform.h | 1 + src/util/rand.c | 32 ++++++++++++++++++-------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/platform.h b/src/platform.h index 104ff28d7..fba2078bb 100644 --- a/src/platform.h +++ b/src/platform.h @@ -14,6 +14,7 @@ #define NO_STRDUP #define NO_MKDIR #define _CRT_SECURE_NO_WARNINGS +#define _USE_MATH_DEFINES #pragma warning(disable: 4710 4820) #pragma warning(disable: 4100) // unreferenced formal parameter #pragma warning(disable: 4456) // declaration hides previous diff --git a/src/util/rand.c b/src/util/rand.c index 584e8541e..a4ee7acb5 100644 --- a/src/util/rand.c +++ b/src/util/rand.c @@ -36,23 +36,27 @@ int lovar(double xpct_x2) return (rng_int() % n + rng_int() % n) / 1000; } -/* NormalRand aus python, random.py geklaut, dort ist Referenz auf -* den Algorithmus. mu = Mittelwert, sigma = Standardabweichung. -* http://de.wikipedia.org/wiki/Standardabweichung#Diskrete_Gleichverteilung.2C_W.C3.BCrfel -*/ +/* gaussian distribution + * taken from http://c-faq.com/lib/gaussian.html + */ + double normalvariate(double mu, double sigma) { - static const double NV_MAGICCONST = 1.7155277699214135; - double z; - for (;;) { - double u1 = rng_double(); - double u2 = rng_double(); - z = NV_MAGICCONST * (u1 - 0.5) / u2; - if (z * z / 4.0 <= -log(u2)) { - break; - } + static double U, V; + static int phase = 0; + double Z; + + if (phase == 0) { + U = (rng_int() + 1.) / (RNG_RAND_MAX + 2.); + V = rng_int() / (RNG_RAND_MAX + 1.); + Z = sqrt(-2 * log(U)) * sin(2 * M_PI * V); } - return mu + z * sigma; + else { + Z = sqrt(-2 * log(U)) * cos(2 * M_PI * V); + } + phase = 1 - phase; + + return mu + Z *sigma; } int ntimespprob(int n, double p, double mod) From ccf90413e663cbbce9cbe55ea34a877ec8d8dd06 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 4 May 2017 06:44:33 +0200 Subject: [PATCH 181/218] start cleaning up random bindings --- scripts/run-tests-e2.lua | 2 +- scripts/run-tests-e3.lua | 2 +- src/bindings.c | 12 +++++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/scripts/run-tests-e2.lua b/scripts/run-tests-e2.lua index 67a534ae6..27617592f 100644 --- a/scripts/run-tests-e2.lua +++ b/scripts/run-tests-e2.lua @@ -17,7 +17,7 @@ require 'eressea.path' require 'tests.e2' require 'lunit' -rng_default(0) +rng.inject(0) rules = require('eressea.' .. config.rules) result = lunit.main() return result.errors + result.failed diff --git a/scripts/run-tests-e3.lua b/scripts/run-tests-e3.lua index 241b3e9fd..0aefb5d3a 100644 --- a/scripts/run-tests-e3.lua +++ b/scripts/run-tests-e3.lua @@ -17,7 +17,7 @@ require 'eressea.xmlconf' require 'tests.e3' require 'lunit' -rng_default(0) +rng.inject(0) eressea.settings.set("rules.alliances", "0") rules = require('eressea.' .. config.rules) result = lunit.main() diff --git a/src/bindings.c b/src/bindings.c index d78ed8537..2ea6f1657 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -231,7 +231,7 @@ static int tolua_setkey(lua_State * L) return 0; } -static int tolua_rng_int(lua_State * L) +static int tolua_random(lua_State * L) { lua_pushinteger(L, rng_int()); return 1; @@ -1017,6 +1017,14 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile) tolua_module(L, NULL, 0); tolua_beginmodule(L, NULL); { + tolua_module(L, TOLUA_CAST "rng", 1); + tolua_beginmodule(L, TOLUA_CAST "rng"); + { + tolua_function(L, TOLUA_CAST "inject", lua_rng_default); + tolua_function(L, TOLUA_CAST "random", tolua_random); + } + tolua_endmodule(L); + tolua_function(L, TOLUA_CAST "rng_int", tolua_random); tolua_cclass(L, TOLUA_CAST "alliance", TOLUA_CAST "alliance", TOLUA_CAST "", NULL); tolua_beginmodule(L, TOLUA_CAST "alliance"); @@ -1066,7 +1074,6 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile) tolua_function(L, TOLUA_CAST "get_ship", tolua_get_ship); tolua_function(L, TOLUA_CAST "get_building", tolua_get_building); tolua_function(L, TOLUA_CAST "get_region", tolua_get_region); - tolua_function(L, TOLUA_CAST "rng_default", lua_rng_default); tolua_function(L, TOLUA_CAST "factions", tolua_get_factions); tolua_function(L, TOLUA_CAST "regions", tolua_get_regions); tolua_function(L, TOLUA_CAST "read_turn", tolua_read_turn); @@ -1107,7 +1114,6 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile) tolua_function(L, TOLUA_CAST "get_key", tolua_getkey); tolua_function(L, TOLUA_CAST "set_key", tolua_setkey); tolua_function(L, TOLUA_CAST "translate", &tolua_translate); - tolua_function(L, TOLUA_CAST "rng_int", tolua_rng_int); tolua_function(L, TOLUA_CAST "spells", tolua_get_spells); tolua_function(L, TOLUA_CAST "read_xml", tolua_read_xml); } tolua_endmodule(L); From 692c9a1dacda54f579dc981ba804a1e35d220c83 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 4 May 2017 08:14:19 +0200 Subject: [PATCH 182/218] M_PI is not defined in standard C, needs __USE_BSD --- src/platform.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform.h b/src/platform.h index fba2078bb..662d51e40 100644 --- a/src/platform.h +++ b/src/platform.h @@ -21,6 +21,7 @@ #pragma warning(disable: 4457) // declaration hides function parameter #pragma warning(disable: 4459) // declaration hides global #else /* assume gcc */ +#define __USE_BSD #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L # define va_copy(a,b) __va_copy(a,b) #endif From 7ad5c4b3f2b5feecb758097b4f4de3e14de6335a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 4 May 2017 08:22:20 +0200 Subject: [PATCH 183/218] define PI, because M_PI is not to be depended on --- src/platform.h | 1 - src/util/rand.c | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/platform.h b/src/platform.h index 662d51e40..fba2078bb 100644 --- a/src/platform.h +++ b/src/platform.h @@ -21,7 +21,6 @@ #pragma warning(disable: 4457) // declaration hides function parameter #pragma warning(disable: 4459) // declaration hides global #else /* assume gcc */ -#define __USE_BSD #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L # define va_copy(a,b) __va_copy(a,b) #endif diff --git a/src/util/rand.c b/src/util/rand.c index a4ee7acb5..bd8543b9e 100644 --- a/src/util/rand.c +++ b/src/util/rand.c @@ -28,6 +28,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#define PI_L 3.1415926535897932384626433832795L + int lovar(double xpct_x2) { int n = (int)(xpct_x2 * 500) + 1; @@ -49,10 +51,10 @@ double normalvariate(double mu, double sigma) if (phase == 0) { U = (rng_int() + 1.) / (RNG_RAND_MAX + 2.); V = rng_int() / (RNG_RAND_MAX + 1.); - Z = sqrt(-2 * log(U)) * sin(2 * M_PI * V); + Z = sqrt(-2 * log(U)) * sin(2 * PI_L * V); } else { - Z = sqrt(-2 * log(U)) * cos(2 * M_PI * V); + Z = sqrt(-2 * log(U)) * cos(2 * PI_L * V); } phase = 1 - phase; From db07cbed6b6ef1c926e276a961ff8e9264ba9281 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 6 May 2017 09:44:06 +0200 Subject: [PATCH 184/218] use correct type for PI (double). promote defines to platform-header. --- src/platform.h | 6 ++++++ src/util/rand.c | 6 ++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/platform.h b/src/platform.h index fba2078bb..97d254e2d 100644 --- a/src/platform.h +++ b/src/platform.h @@ -48,4 +48,10 @@ char * strdup(const char *s); int mkdir(const char *pathname, int mode); #endif +/* do not use M_PI, use one of these instead: */ +#define PI_F 3.1415926535897932384626433832795F +#define PI_D 3.1415926535897932384626433832795 +#define PI_L 3.1415926535897932384626433832795L + + #endif diff --git a/src/util/rand.c b/src/util/rand.c index bd8543b9e..441461068 100644 --- a/src/util/rand.c +++ b/src/util/rand.c @@ -28,8 +28,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#define PI_L 3.1415926535897932384626433832795L - int lovar(double xpct_x2) { int n = (int)(xpct_x2 * 500) + 1; @@ -51,10 +49,10 @@ double normalvariate(double mu, double sigma) if (phase == 0) { U = (rng_int() + 1.) / (RNG_RAND_MAX + 2.); V = rng_int() / (RNG_RAND_MAX + 1.); - Z = sqrt(-2 * log(U)) * sin(2 * PI_L * V); + Z = sqrt(-2 * log(U)) * sin(2 * PI_D * V); } else { - Z = sqrt(-2 * log(U)) * cos(2 * PI_L * V); + Z = sqrt(-2 * log(U)) * cos(2 * PI_D * V); } phase = 1 - phase; From 5dea221b8b70ba5c8644a1df03fb2a295128de05 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 6 May 2017 10:56:44 +0200 Subject: [PATCH 185/218] quick fix for intermittent spells --- scripts/tests/e2/init.lua | 2 +- scripts/tests/e2/spells.lua | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index 4b4fe7dd4..7fbc0eb95 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -1,3 +1,4 @@ +require 'tests.e2.spells' require 'tests.e2.buildings' require 'tests.e2.production' require 'tests.e2.adamantium' @@ -7,7 +8,6 @@ require 'tests.e2.e2features' require 'tests.e2.movement' require 'tests.e2.destroy' require 'tests.e2.guard' -require 'tests.e2.spells' require 'tests.e2.stealth' require 'tests.e2.items' require 'tests.items' diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index dad951293..fc1e3bc3b 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -8,6 +8,7 @@ function setup() eressea.settings.set("nmr.timeout", "0") eressea.settings.set("NewbieImmunity", "0") eressea.settings.set("rules.food.flags", "4") + eressea.settings.set("rules.peasants.growth.factor", "0") end function test_shapeshift() @@ -44,7 +45,7 @@ function test_raindance() u:clear_orders() u:add_order("ZAUBERE STUFE 1 Regentanz") assert_equal(0, r:get_resource("money")) - + process_orders() assert_equal(200, r:get_resource("money")) assert_equal(0, u:get_item("money")) From dd4bdca72bc4ab98806fa492525195f86c64bb31 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 6 May 2017 15:05:36 +0200 Subject: [PATCH 187/218] do not use the shiptypes list for searches, use a cbtrie. --- src/kernel/ship.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/kernel/ship.c b/src/kernel/ship.c index b9ac0b170..518c3ce0c 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -37,13 +37,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include -#include #include #include #include +#include +#include /* libc includes */ #include @@ -52,6 +54,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include selist *shiptypes = NULL; +static critbit_tree cb_shiptypes; static local_names *snames; @@ -89,16 +92,17 @@ const ship_type *findshiptype(const char *name, const struct locale *lang) static ship_type *st_find_i(const char *name) { - selist *ql; - int qi; + const char *match; + ship_type *st = NULL; - for (qi = 0, ql = shiptypes; ql; selist_advance(&ql, &qi, 1)) { - ship_type *stype = (ship_type *)selist_get(ql, qi); - if (strcmp(stype->_name, name) == 0) { - return stype; - } + match = cb_find_str(&cb_shiptypes, name); + if (match) { + cb_get_kv(match, &st, sizeof(st)); } - return NULL; + else { + log_warning("st_find: could not find ship '%s'\n", name); + } + return st; } const ship_type *st_find(const char *name) { @@ -108,10 +112,17 @@ const ship_type *st_find(const char *name) { ship_type *st_get_or_create(const char * name) { ship_type * st = st_find_i(name); if (!st) { + size_t len; + char data[64]; + st = (ship_type *)calloc(sizeof(ship_type), 1); st->_name = strdup(name); st->storm = 1.0; selist_push(&shiptypes, (void *)st); + + len = cb_new_kv(name, strlen(name), &st, sizeof(st), data); + assert(len <= sizeof(data)); + cb_insert(&cb_shiptypes, data, len); } return st; } @@ -250,6 +261,7 @@ static void free_shiptype(void *ptr) { } void free_shiptypes(void) { + cb_clear(&cb_shiptypes); selist_foreach(shiptypes, free_shiptype); selist_free(shiptypes); shiptypes = 0; From 6778cbe4836a25ac268b2fd38f42cba759279509 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 6 May 2017 15:25:13 +0200 Subject: [PATCH 188/218] assert that we do not add new ship types after the per-language lookup is initialized. --- src/kernel/ship.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 518c3ce0c..88c0f31e7 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -53,8 +53,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -selist *shiptypes = NULL; -static critbit_tree cb_shiptypes; +selist *shiptypes = NULL; /* do not use this list for searching*/ +static critbit_tree cb_shiptypes; /* use this trie instead */ static local_names *snames; @@ -63,9 +63,7 @@ const ship_type *findshiptype(const char *name, const struct locale *lang) local_names *sn = snames; variant var; - while (sn) { - if (sn->lang == lang) - break; + while (sn && sn->lang != lang) { sn = sn->next; } if (!sn) { @@ -111,6 +109,7 @@ const ship_type *st_find(const char *name) { ship_type *st_get_or_create(const char * name) { ship_type * st = st_find_i(name); + assert(!snames); if (!st) { size_t len; char data[64]; From 3eb89e93aecc903f1b4bfb2ae21b3d20945feafa Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 6 May 2017 15:33:35 +0200 Subject: [PATCH 189/218] use a cbtrie for shiptype-lookups instead of the selist. --- src/kernel/building.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index bb97f57b8..1053a7748 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -41,11 +41,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include #include #include #include +#include +#include /* libc includes */ #include @@ -62,21 +63,22 @@ typedef struct building_typelist { } building_typelist; selist *buildingtypes = NULL; +static critbit_tree cb_bldgtypes; /* Returns a building type for the (internal) name */ static building_type *bt_find_i(const char *name) { - selist *ql; - int qi; + const char *match; + building_type *btype = NULL; - assert(name); - - for (qi = 0, ql = buildingtypes; ql; selist_advance(&ql, &qi, 1)) { - building_type *btype = (building_type *)selist_get(ql, qi); - if (strcmp(btype->_name, name) == 0) - return btype; + match = cb_find_str(&cb_bldgtypes, name); + if (match) { + cb_get_kv(match, &btype, sizeof(btype)); } - return NULL; + else { + log_warning("st_find: could not find ship '%s'\n", name); + } + return btype; } const building_type *bt_find(const char *name) @@ -96,9 +98,15 @@ bool bt_changed(int *cache) return false; } -void bt_register(building_type * type) +void bt_register(building_type * btype) { - selist_push(&buildingtypes, (void *)type); + size_t len; + char data[64]; + + selist_push(&buildingtypes, (void *)btype); + len = cb_new_kv(btype->_name, strlen(btype->_name), &btype, sizeof(btype), data); + assert(len <= sizeof(data)); + cb_insert(&cb_bldgtypes, data, len); ++bt_changes; } @@ -111,6 +119,7 @@ static void free_buildingtype(void *ptr) { } void free_buildingtypes(void) { + cb_clear(&cb_bldgtypes); selist_foreach(buildingtypes, free_buildingtype); selist_free(buildingtypes); buildingtypes = 0; From b74d18b8c93d74659fc1662d2086d04300f1d565 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 6 May 2017 15:39:09 +0200 Subject: [PATCH 190/218] bt_register is non-standard API, hide it. factor out st_register for readability. --- src/kernel/building.c | 2 +- src/kernel/building.h | 1 - src/kernel/building.test.c | 9 ++++----- src/kernel/ship.c | 20 ++++++++++++-------- src/market.test.c | 4 +--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 1053a7748..948797b94 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -98,7 +98,7 @@ bool bt_changed(int *cache) return false; } -void bt_register(building_type * btype) +static void bt_register(building_type * btype) { size_t len; char data[64]; diff --git a/src/kernel/building.h b/src/kernel/building.h index edb46edfd..a2019e4a2 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -83,7 +83,6 @@ extern "C" { bool bt_changed(int *cache); const building_type *bt_find(const char *name); void free_buildingtypes(void); - void bt_register(struct building_type *type); int bt_effsize(const struct building_type *btype, const struct building *b, int bsize); diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index 3d25cd9a1..39b145d24 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -21,14 +21,13 @@ static void test_register_building(CuTest * tc) test_cleanup(); - btype = (building_type *)calloc(sizeof(building_type), 1); - btype->_name = strdup("herp"); CuAssertIntEquals(tc, true, bt_changed(&cache)); CuAssertIntEquals(tc, false, bt_changed(&cache)); - bt_register(btype); - CuAssertIntEquals(tc, true, bt_changed(&cache)); - CuAssertPtrNotNull(tc, bt_find("herp")); + btype = bt_get_or_create("herp"); + CuAssertIntEquals(tc, true, bt_changed(&cache)); + CuAssertPtrEquals(tc, btype, (void *)bt_find("herp")); + free_buildingtypes(); CuAssertIntEquals(tc, true, bt_changed(&cache)); test_cleanup(); diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 88c0f31e7..27db2e5c2 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -107,21 +107,25 @@ const ship_type *st_find(const char *name) { return st_find_i(name); } +static void st_register(ship_type *stype) { + size_t len; + char data[64]; + + selist_push(&shiptypes, (void *)stype); + + len = cb_new_kv(stype->_name, strlen(stype->_name), &stype, sizeof(stype), data); + assert(len <= sizeof(data)); + cb_insert(&cb_shiptypes, data, len); +} + ship_type *st_get_or_create(const char * name) { ship_type * st = st_find_i(name); assert(!snames); if (!st) { - size_t len; - char data[64]; - st = (ship_type *)calloc(sizeof(ship_type), 1); st->_name = strdup(name); st->storm = 1.0; - selist_push(&shiptypes, (void *)st); - - len = cb_new_kv(name, strlen(name), &st, sizeof(st), data); - assert(len <= sizeof(data)); - cb_insert(&cb_shiptypes, data, len); + st_register(st); } return st; } diff --git a/src/market.test.c b/src/market.test.c index a631dbcb7..2beeaea6b 100644 --- a/src/market.test.c +++ b/src/market.test.c @@ -43,9 +43,7 @@ static void test_market_curse(CuTest * tc) config_set("rules.region_owners", "1"); - btype = (building_type *)calloc(1, sizeof(building_type)); - btype->_name = strdup("market"); - bt_register(btype); + btype = bt_get_or_create("market"); terrain = get_terrain("plain"); From 898c12e99a89d06839e0e5a798776555b0d55561 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 6 May 2017 15:53:21 +0200 Subject: [PATCH 191/218] XML construction elements never have a building. required buildings are encoded by RMT_PROD_REQUIRE. improved error messaging. --- scripts/tests/production.lua | 2 +- src/economy.c | 24 ++++++++++-------------- src/economy.test.c | 2 +- src/kernel/build.c | 11 ----------- src/kernel/build.h | 10 ++-------- src/kernel/build.test.c | 24 ------------------------ src/kernel/building.c | 4 ++-- src/kernel/building.test.c | 2 +- src/kernel/ship.c | 3 ++- src/kernel/xmlreader.c | 11 ++--------- src/magic.test.c | 2 +- 11 files changed, 22 insertions(+), 73 deletions(-) diff --git a/scripts/tests/production.lua b/scripts/tests/production.lua index 8727762d1..c8a299676 100644 --- a/scripts/tests/production.lua +++ b/scripts/tests/production.lua @@ -27,7 +27,7 @@ function test_laen_needs_mine() turn_process() assert_equal(0, u:get_item('laen')) assert_equal(100, r:get_resource('laen')) - assert_equal(1, f:count_msg_type("error104")) -- requires building + assert_equal(1, f:count_msg_type("building_needed")) -- requires building u.building = building.create(u.region, "mine") u.building.working = true diff --git a/src/economy.c b/src/economy.c index 48653d0aa..5f62527ea 100644 --- a/src/economy.c +++ b/src/economy.c @@ -814,6 +814,7 @@ static struct message * get_modifiers(unit *u, skill_t sk, const resource_type * int skill = 0; int need_race = 0, need_bldg = 0; resource_mod *mod; + const struct building_type *btype_needed = NULL; if (btype && btype->modifiers) { for (mod = btype->modifiers; mod && mod->type != RMT_END; ++mod) { @@ -838,7 +839,9 @@ static struct message * get_modifiers(unit *u, skill_t sk, const resource_type * break; case RMT_PROD_REQUIRE: if (mod->race) need_race |= 1; - if (mod->btype) need_bldg |= 1; + if (mod->btype) { + need_bldg |= 1; + } break; default: /* is not a production modifier, ignore it */ @@ -848,14 +851,17 @@ static struct message * get_modifiers(unit *u, skill_t sk, const resource_type * } if (mod->type == RMT_PROD_REQUIRE) { if (mod->race) need_race |= 2; - if (mod->btype) need_bldg |= 2; + if (mod->btype) { + btype_needed = mod->btype; + need_bldg |= 2; + } } } if (need_race == 2) { return msg_error(u, u->thisorder, 117); } - if (need_bldg == 2) { - return msg_error(u, u->thisorder, 104); + if (btype_needed && need_bldg == 2) { + return msg_feedback(u, u->thisorder, "building_needed", "building", btype_needed->_name); } *skillp = skill; if (savep) *savep = frac_make(save_n, save_d); @@ -885,11 +891,6 @@ static void manufacture(unit * u, const item_type * itype, int want) ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "skill_needed", "skill", sk)); return; - case EBUILDINGREQ: - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "building_needed", "building", - itype->construction->extra.btype->_name)); - return; case ELOWSKILL: ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "manufacture_skills", @@ -1236,11 +1237,6 @@ static void create_potion(unit * u, const potion_type * ptype, int want) /* no skill, or not enough skill points to build */ cmistake(u, u->thisorder, 50, MSG_PRODUCE); break; - case EBUILDINGREQ: - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "building_needed", "building", - ptype->itype->construction->extra.btype->_name)); - break; case ECOMPLETE: assert(0); break; diff --git a/src/economy.test.c b/src/economy.test.c index 842db45f8..802610880 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -527,7 +527,7 @@ static void test_modify_production(CuTest *tc) { test_clear_messages(u->faction); make_item(u, itype, 10); CuAssertIntEquals(tc, 28, get_item(u, itype)); - CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error104")); + CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "building_needed")); rtype->modifiers[0].type = RMT_PROD_REQUIRE; rtype->modifiers[0].race = test_create_race("smurf"); diff --git a/src/kernel/build.c b/src/kernel/build.c index 36d72b109..57c172905 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -513,17 +513,6 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski return ENOMATERIALS; if (con->improvement == NULL && completed == con->maxsize) return ECOMPLETE; - if (con->type==CONS_ITEM && con->extra.btype) { - building *b; - if (!u->building || u->building->type != con->extra.btype) { - return EBUILDINGREQ; - } - b = inside_building(u); - if (!b || !building_is_active(b)) { - return EBUILDINGREQ; - } - } - if (con->skill != NOSKILL) { int effsk; int dm = get_effect(u, oldpotiontype[P_DOMORE]); diff --git a/src/kernel/build.h b/src/kernel/build.h index 39916365a..c201d900b 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -52,13 +52,8 @@ extern "C" { int reqsize; /* size of object using up 1 set of requirement. */ requirement *materials; /* material req'd to build one object */ - union { - /* CONS_BUILDING: */ - char * name; /* building level name */ - /* CONS_ITEM: */ - const struct building_type *btype; /* building required to build item */ - } extra; - + /* only used by CONS_BUILDING: */ + char * name; /* building level name */ struct construction *improvement; /* next level, if upgradable. */ } construction; @@ -89,7 +84,6 @@ extern "C" { #define ENEEDSKILL -2 #define ECOMPLETE -3 #define ENOMATERIALS -4 -#define EBUILDINGREQ -5 #ifdef __cplusplus } diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c index c3fa07e65..8cd408b09 100644 --- a/src/kernel/build.test.c +++ b/src/kernel/build.test.c @@ -71,29 +71,6 @@ static void test_build_requires_materials(CuTest *tc) { teardown_build(&bf); } -static void test_build_requires_building(CuTest *tc) { - build_fixture bf = { 0 }; - unit *u; - const struct resource_type *rtype; - building_type *btype; - - u = setup_build(&bf); - rtype = bf.cons.materials[0].rtype; - i_change(&u->items, rtype->itype, 1); - set_level(u, SK_ARMORER, 2); - bf.cons.type = CONS_ITEM; - bf.cons.extra.btype = btype = bt_get_or_create("hodor"); - btype->maxcapacity = 1; - btype->capacity = 1; - CuAssertIntEquals_Msg(tc, "must be inside a production building", EBUILDINGREQ, build(u, &bf.cons, 0, 1, 0)); - u->building = test_create_building(u->region, btype); - fset(u->building, BLD_MAINTAINED); - CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1, 0)); - btype->maxcapacity = 0; - CuAssertIntEquals_Msg(tc, "cannot build when production building capacity exceeded", EBUILDINGREQ, build(u, &bf.cons, 0, 1, 0)); - teardown_build(&bf); -} - static void test_build_failure_missing_skill(CuTest *tc) { build_fixture bf = { 0 }; unit *u; @@ -411,7 +388,6 @@ CuSuite *get_build_suite(void) SUITE_ADD_TEST(suite, test_build_failure_low_skill); SUITE_ADD_TEST(suite, test_build_failure_missing_skill); SUITE_ADD_TEST(suite, test_build_requires_materials); - SUITE_ADD_TEST(suite, test_build_requires_building); SUITE_ADD_TEST(suite, test_build_failure_completed); SUITE_ADD_TEST(suite, test_build_with_ring); SUITE_ADD_TEST(suite, test_build_with_potion); diff --git a/src/kernel/building.c b/src/kernel/building.c index 948797b94..31c4b3e27 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -199,14 +199,14 @@ const char *buildingtype(const building_type * btype, const building * b, int bs if (btype->name) { return btype->name(btype, b, bsize); } - if (btype->construction && btype->construction->extra.name) { + if (btype->construction && btype->construction->name) { if (b) { bsize = adjust_size(b, bsize); } for (con = btype->construction; con; con = con->improvement) { bsize -= con->maxsize; if (!con->improvement || bsize <0) { - return con->extra.name; + return con->name; } } } diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index 39b145d24..c1255373b 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -563,7 +563,7 @@ static void test_buildingtype(CuTest *tc) { btype = test_create_buildingtype("hodor"); CuAssertPtrNotNull(tc, btype->construction); CuAssertStrEquals(tc, "hodor", buildingtype(btype, NULL, 1)); - btype->construction->extra.name = strdup("castle"); + btype->construction->name = strdup("castle"); CuAssertStrEquals(tc, "castle", buildingtype(btype, NULL, 1)); btype = bt_get_or_create("portal"); CuAssertPtrEquals(tc, NULL, btype->construction); diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 27db2e5c2..3a7608789 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -248,8 +248,9 @@ void remove_ship(ship ** slist, ship * sh) void free_ship(ship * s) { - while (s->attribs) + while (s->attribs) { a_remove(&s->attribs, s->attribs); + } free(s->name); free(s->display); free(s); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 9f671d44c..080ff4207 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -247,17 +247,10 @@ construction ** consPtr, construct_t type) con->minskill = xml_ivalue(node, "minskill", -1); con->reqsize = xml_ivalue(node, "reqsize", 1); - if (type == CONS_ITEM) { - propValue = xmlGetProp(node, BAD_CAST "building"); - if (propValue != NULL) { - con->extra.btype = bt_get_or_create((const char *)propValue); - xmlFree(propValue); - } - } - else if (type == CONS_BUILDING) { + if (type == CONS_BUILDING) { propValue = xmlGetProp(node, BAD_CAST "name"); if (propValue != NULL) { - con->extra.name = strdup((const char *)propValue); + con->name = strdup((const char *)propValue); xmlFree(propValue); } } diff --git a/src/magic.test.c b/src/magic.test.c index 380001035..a1b55b45d 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -479,7 +479,7 @@ static void test_illusioncastle(CuTest *tc) CuAssertPtrEquals(tc, btype, (void *)icastle_type(a)); CuAssertPtrEquals(tc, bt_icastle, (void *)b->type); CuAssertStrEquals(tc, "castle", buildingtype(btype, b, b->size)); - btype->construction->extra.name = strdup("site"); + btype->construction->name = strdup("site"); CuAssertStrEquals(tc, "site", buildingtype(btype, b, b->size)); test_cleanup(); } From 9d5369ff1efc17a53f13c11dd95ac261f3df74c8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 6 May 2017 16:48:32 +0200 Subject: [PATCH 192/218] coverity: unintended integer division --- src/economy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/economy.c b/src/economy.c index 5f62527ea..0bc056b56 100644 --- a/src/economy.c +++ b/src/economy.c @@ -2944,8 +2944,8 @@ static void peasant_taxes(region * r) level = buildingeffsize(b, false); if (level > 0) { - double taxfactor = money * level / building_taxes(b); - double morale = money * region_get_morale(r) / MORALE_TAX_FACTOR; + double taxfactor = (double)money * level / building_taxes(b); + double morale = (double)money * region_get_morale(r) / MORALE_TAX_FACTOR; if (taxfactor > morale) { taxfactor = morale; } From 2e3f68ed879724e2ba980fd6d4cc9ec5fa222501 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 7 May 2017 13:26:54 +0200 Subject: [PATCH 193/218] add a config_set_int convenience function. --- src/kernel/config.c | 9 ++++++++- src/kernel/config.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/kernel/config.c b/src/kernel/config.c index 02ed9894d..1076e9432 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -782,11 +782,18 @@ void config_set_from(const dictionary *d, const char *valid_keys[]) } } -void config_set(const char *key, const char *value) { +void config_set(const char *key, const char *value) +{ ++config_cache_key; set_param(&configuration, key, value); } +void config_set_int(const char *key, int value) +{ + ++config_cache_key; + set_param(&configuration, key, itoa10(value)); +} + const char *config_get(const char *key) { return get_param(configuration, key); } diff --git a/src/kernel/config.h b/src/kernel/config.h index f80214fde..4cf0650ff 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -121,6 +121,7 @@ extern "C" { void free_params(struct param **pp); void config_set(const char *key, const char *value); + void config_set_int(const char *key, int value); void config_set_from(const struct _dictionary_ *d, const char *keys[]); const char *config_get(const char *key); int config_get_int(const char *key, int def); From 3e1462a1923316898efa304b4c5189eb2ba8bba8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 7 May 2017 13:35:59 +0200 Subject: [PATCH 194/218] add empty calendar unit test. --- src/CMakeLists.txt | 28 ++++++++++++++-------------- src/calendar.test.c | 25 +++++++++++++++++++++++++ src/test_eressea.c | 25 +++++++++++++------------ 3 files changed, 52 insertions(+), 26 deletions(-) create mode 100644 src/calendar.test.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ebe914dfe..c4c306118 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -197,42 +197,42 @@ target_link_libraries(convert ) set(TESTS_SRC - monsters.test.c - names.test.c - donations.test.c - wormhole.test.c - alchemy.test.c - guard.test.c test_eressea.c tests.c + alchemy.test.c battle.test.c - vortex.test.c - tests.test.c - volcano.test.c - reports.test.c + calendar.test.c creport.test.c - report.test.c - summary.test.c - travelthru.test.c direction.test.c + donations.test.c economy.test.c + give.test.c + guard.test.c json.test.c keyword.test.c - give.test.c laws.test.c lighthouse.test.c magic.test.c market.test.c monsters.test.c move.test.c + names.test.c piracy.test.c prefix.test.c renumber.test.c + reports.test.c + report.test.c + summary.test.c skill.test.c spells.test.c spy.test.c study.test.c + tests.test.c + travelthru.test.c upkeep.test.c + volcano.test.c + vortex.test.c + wormhole.test.c spells/flyingship.test.c spells/magicresistance.test.c triggers/shock.test.c diff --git a/src/calendar.test.c b/src/calendar.test.c new file mode 100644 index 000000000..e8df8cd58 --- /dev/null +++ b/src/calendar.test.c @@ -0,0 +1,25 @@ +#include + +#include "calendar.h" + +#include + +#include +#include "tests.h" + +static void test_calendar(CuTest * tc) +{ + gamedate gd; + + test_setup(); + get_gamedate(0, &gd); + CuAssertIntEquals(tc, 0, gd.month); + test_cleanup(); +} + +CuSuite *get_calendar_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_calendar); + return suite; +} diff --git a/src/test_eressea.c b/src/test_eressea.c index 1d991725f..5361ddf5e 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -116,35 +116,36 @@ int RunAllTests(int argc, char *argv[]) ADD_SUITE(ally); ADD_SUITE(messages); /* gamecode */ - ADD_SUITE(guard); - ADD_SUITE(report); - ADD_SUITE(creport); - ADD_SUITE(summary); - ADD_SUITE(names); ADD_SUITE(battle); - ADD_SUITE(volcano); + ADD_SUITE(calendar); + ADD_SUITE(creport); ADD_SUITE(donations); - ADD_SUITE(travelthru); ADD_SUITE(economy); ADD_SUITE(flyingship); ADD_SUITE(give); + ADD_SUITE(guard); + ADD_SUITE(key); ADD_SUITE(laws); ADD_SUITE(lighthouse); ADD_SUITE(market); ADD_SUITE(monsters); ADD_SUITE(move); + ADD_SUITE(names); + ADD_SUITE(otherfaction); ADD_SUITE(piracy); ADD_SUITE(prefix); ADD_SUITE(renumber); - ADD_SUITE(key); + ADD_SUITE(report); + ADD_SUITE(shock); + ADD_SUITE(spy); ADD_SUITE(stealth); - ADD_SUITE(otherfaction); + ADD_SUITE(study); + ADD_SUITE(summary); + ADD_SUITE(travelthru); ADD_SUITE(upkeep); + ADD_SUITE(volcano); ADD_SUITE(vortex); ADD_SUITE(wormhole); - ADD_SUITE(spy); - ADD_SUITE(study); - ADD_SUITE(shock); if (suites) { CuSuite *summary = CuSuiteNew(); From fa7e21b78382fe1fb783a00a12f1575e145e2f3b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 7 May 2017 13:40:43 +0200 Subject: [PATCH 195/218] very simple calendar test. --- src/calendar.test.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/calendar.test.c b/src/calendar.test.c index e8df8cd58..488db3bfe 100644 --- a/src/calendar.test.c +++ b/src/calendar.test.c @@ -7,19 +7,49 @@ #include #include "tests.h" +static void test_calendar_config(CuTest * tc) +{ + gamedate gd; + + test_setup(); + get_gamedate(0, &gd); + CuAssertIntEquals(tc, 0, first_turn()); + config_set_int("game.start", 42); + CuAssertIntEquals(tc, 42, first_turn()); + test_cleanup(); +} + static void test_calendar(CuTest * tc) { gamedate gd; test_setup(); get_gamedate(0, &gd); + CuAssertIntEquals(tc, 1, gd.year); + CuAssertIntEquals(tc, 0, gd.season); CuAssertIntEquals(tc, 0, gd.month); + CuAssertIntEquals(tc, 0, gd.week); + + get_gamedate(1, &gd); + CuAssertIntEquals(tc, 1, gd.year); + CuAssertIntEquals(tc, 0, gd.season); + CuAssertIntEquals(tc, 0, gd.month); + CuAssertIntEquals(tc, 1, gd.week); + + config_set_int("game.start", 42); + get_gamedate(42, &gd); + CuAssertIntEquals(tc, 1, gd.year); + CuAssertIntEquals(tc, 0, gd.season); + CuAssertIntEquals(tc, 0, gd.month); + CuAssertIntEquals(tc, 0, gd.week); + test_cleanup(); } CuSuite *get_calendar_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_calendar_config); SUITE_ADD_TEST(suite, test_calendar); return suite; } From 29061fa4baab2000402a9c13f9295822fd9eae15 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 7 May 2017 15:50:19 +0200 Subject: [PATCH 196/218] fleshing out the calendar tests --- src/calendar.c | 6 +++++- src/calendar.test.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/tests.c | 2 ++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/calendar.c b/src/calendar.c index d2a70c974..4c1534a27 100644 --- a/src/calendar.c +++ b/src/calendar.c @@ -6,7 +6,7 @@ #include int first_month = 0; -int weeks_per_month = 4; +int weeks_per_month = 3; int months_per_year = 12; char **seasonnames = NULL; char **weeknames = NULL; @@ -73,4 +73,8 @@ void calendar_cleanup(void) weeknames = 0; free(weeknames2); weeknames2 = 0; + + first_month = 0; + weeks_per_month = 3; + months_per_year = 12; } diff --git a/src/calendar.test.c b/src/calendar.test.c index 488db3bfe..e858747ec 100644 --- a/src/calendar.test.c +++ b/src/calendar.test.c @@ -36,6 +36,18 @@ static void test_calendar(CuTest * tc) CuAssertIntEquals(tc, 0, gd.month); CuAssertIntEquals(tc, 1, gd.week); + get_gamedate(weeks_per_month, &gd); + CuAssertIntEquals(tc, 1, gd.year); + CuAssertIntEquals(tc, 0, gd.season); + CuAssertIntEquals(tc, 1, gd.month); + CuAssertIntEquals(tc, 0, gd.week); + + get_gamedate(weeks_per_month*months_per_year, &gd); + CuAssertIntEquals(tc, 2, gd.year); + CuAssertIntEquals(tc, 0, gd.season); + CuAssertIntEquals(tc, 0, gd.month); + CuAssertIntEquals(tc, 0, gd.week); + config_set_int("game.start", 42); get_gamedate(42, &gd); CuAssertIntEquals(tc, 1, gd.year); @@ -43,6 +55,36 @@ static void test_calendar(CuTest * tc) CuAssertIntEquals(tc, 0, gd.month); CuAssertIntEquals(tc, 0, gd.week); + first_month = 2; + get_gamedate(42, &gd); + CuAssertIntEquals(tc, 1, gd.year); + CuAssertIntEquals(tc, 0, gd.season); + CuAssertIntEquals(tc, 2, gd.month); + CuAssertIntEquals(tc, 0, gd.week); + + test_cleanup(); +} + +static void test_calendar_season(CuTest * tc) +{ + gamedate gd; + + test_setup(); + month_season = calloc(months_per_year, sizeof(int)); + + get_gamedate(0, &gd); + CuAssertIntEquals(tc, 1, gd.year); + CuAssertIntEquals(tc, 0, gd.season); + CuAssertIntEquals(tc, 0, gd.month); + CuAssertIntEquals(tc, 0, gd.week); + + month_season[1] = 1; + get_gamedate(weeks_per_month + 1, &gd); + CuAssertIntEquals(tc, 1, gd.year); + CuAssertIntEquals(tc, 1, gd.season); + CuAssertIntEquals(tc, 1, gd.month); + CuAssertIntEquals(tc, 1, gd.week); + test_cleanup(); } @@ -51,5 +93,6 @@ CuSuite *get_calendar_suite(void) CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_calendar_config); SUITE_ADD_TEST(suite, test_calendar); + SUITE_ADD_TEST(suite, test_calendar_season); return suite; } diff --git a/src/tests.c b/src/tests.c index 19deb91ea..60447f5d8 100644 --- a/src/tests.c +++ b/src/tests.c @@ -3,6 +3,7 @@ #include "keyword.h" #include "prefix.h" #include "reports.h" +#include "calendar.h" #include #include @@ -206,6 +207,7 @@ static void test_reset(void) { free_resources(); free_config(); default_locale = 0; + calendar_cleanup(); close_orders(); free_locales(); free_spells(); From bf935f5bb7b44c87e17a58508cb7425f18c2e048 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 7 May 2017 16:11:45 +0200 Subject: [PATCH 197/218] gamedate: no negative turns allowed. feed the beast assert. --- src/bindings.c | 2 +- src/calendar.c | 3 +-- src/kernel/config.c | 2 +- src/laws.c | 1 + src/tests.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bindings.c b/src/bindings.c index 2ea6f1657..33d609ee0 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -921,7 +921,7 @@ static int init_data(const char *filename, const char *catalog) if (l) { return l; } - if (turn < 0) { + if (turn <= 0) { turn = first_turn(); } return 0; diff --git a/src/calendar.c b/src/calendar.c index 4c1534a27..1804ff497 100644 --- a/src/calendar.c +++ b/src/calendar.c @@ -27,8 +27,7 @@ const gamedate *get_gamedate(int turn, gamedate * gd) int t = turn - first_turn(); assert(gd); - if (t < 0) - t = turn; + assert(t >= 0); gd->week = t % weeks_per_month; /* 0 - weeks_per_month-1 */ gd->month = (t / weeks_per_month + first_month) % months_per_year; /* 0 - months_per_year-1 */ diff --git a/src/kernel/config.c b/src/kernel/config.c index 1076e9432..37765914b 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -96,7 +96,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. struct settings global; bool lomem = false; -int turn = -1; +int turn = 0; const char *parameters[MAXPARAMS] = { "LOCALE", diff --git a/src/laws.c b/src/laws.c index 3ab17f1ab..250738f76 100644 --- a/src/laws.c +++ b/src/laws.c @@ -4183,6 +4183,7 @@ static void reset_game(void) void turn_begin(void) { + assert(turn >= 0); ++turn; reset_game(); } diff --git a/src/tests.c b/src/tests.c index 60447f5d8..ec2ac2a2f 100644 --- a/src/tests.c +++ b/src/tests.c @@ -193,7 +193,7 @@ void test_log_stderr(int flags) { static void test_reset(void) { int i; - turn = 0; + turn = 1; default_locale = 0; if (errno) { From ad465f1028b7a53edf9f7d70a78e69614a05f892 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 7 May 2017 17:29:55 +0200 Subject: [PATCH 198/218] Ponnuki should not be aggressive. --- scripts/eressea/ponnuki.lua | 1 + src/monsters.c | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/eressea/ponnuki.lua b/scripts/eressea/ponnuki.lua index 29f882ab5..1a5d1959e 100644 --- a/scripts/eressea/ponnuki.lua +++ b/scripts/eressea/ponnuki.lua @@ -38,6 +38,7 @@ function ponnuki.init() u.name = "Ponnuki" u.info = "Go, Ponnuki, Go!" u.race_name = "Ritter von Go" + u.status = 5 -- FLIEHE print(u:show()) end else diff --git a/src/monsters.c b/src/monsters.c index d60268858..62c982532 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -748,10 +748,6 @@ void plan_monsters(faction * f) produceexp(u, SK_PERCEPTION, u->number); } - if (u->status > ST_BEHIND) { - setstatus(u, ST_FIGHT); - /* all monsters fight */ - } if (attacking && (!r->land || is_guard(u))) { monster_attacks(u, true, false); } From 7806f4991f2f151be0d123c9c9bdd78c5f787436 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 7 May 2017 17:46:51 +0200 Subject: [PATCH 199/218] store calendar configuration nin JSON, not XML. --- conf/calendar.json | 21 ++++++++++ conf/e2/config.json | 10 +++-- conf/e2/rules.xml | 1 - conf/e3/config.json | 2 + conf/e3/rules.xml | 2 - res/core/calendar.xml | 23 ----------- res/core/de/strings.xml | 12 ++++-- res/e3a/strings.xml | 8 +--- scripts/eressea/frost.lua | 4 +- scripts/eressea/xmasitems.lua | 4 +- scripts/tests/e2/e2features.lua | 4 +- scripts/tests/e3/rules.lua | 2 +- src/calendar.c | 52 +++++++++++------------ src/calendar.h | 13 +++--- src/kernel/jsonconf.c | 73 +++++++++++++++++++++++++++++++++ src/kernel/xmlreader.c | 5 ++- src/move.h | 1 + src/report.c | 8 ++-- src/summary.c | 11 +++-- 19 files changed, 163 insertions(+), 93 deletions(-) create mode 100644 conf/calendar.json delete mode 100644 res/core/calendar.xml diff --git a/conf/calendar.json b/conf/calendar.json new file mode 100644 index 000000000..8a134dc40 --- /dev/null +++ b/conf/calendar.json @@ -0,0 +1,21 @@ +{ + "calendar" : { + "months" : [ + { "storm" : 60, "season" : 2 }, + { "storm" : 10, "season" : 2 }, + + { "storm" : 60, "season" : 3 }, + { "storm" : 10, "season" : 3 }, + + { "storm" : 60, "season" : 0 }, + { "storm" : 80, "season" : 0 }, + + { "storm" : 50, "season" : 1 }, + { "storm" : 30, "season" : 1 }, + { "storm" : 60, "season" : 1 } + ], + "weeks" : [ + "firstweek", "secondweek", "thirdweek" + ] + } +} diff --git a/conf/e2/config.json b/conf/e2/config.json index 46ee01497..84265b78f 100644 --- a/conf/e2/config.json +++ b/conf/e2/config.json @@ -1,9 +1,10 @@ { - "include": [ - "keywords.json", - "prefixes.json", + "include": [ + "keywords.json", + "calendar.json", + "prefixes.json", "e2/terrains.json" - ], + ], "disabled": [ "jsreport" ], @@ -22,6 +23,7 @@ "hunger.long": true, "init_spells": 0, "game.era": 2, + "game.start": 184, "rules.reserve.twophase": true, "rules.give.max_men": -1, "rules.check_overload": false, diff --git a/conf/e2/rules.xml b/conf/e2/rules.xml index 8d0b01b27..c237773ab 100644 --- a/conf/e2/rules.xml +++ b/conf/e2/rules.xml @@ -16,7 +16,6 @@ - diff --git a/conf/e3/config.json b/conf/e3/config.json index beb45f35d..adbfa3526 100644 --- a/conf/e3/config.json +++ b/conf/e3/config.json @@ -1,6 +1,7 @@ { "include": [ "keywords.json", + "calendar.json", "prefixes.json", "e3/terrains.json" ], @@ -52,6 +53,7 @@ "study.expensivemigrants": true, "study.speedup": 2, "game.era": 3, + "game.start": 1, "rules.reserve.twophase": true, "rules.owners.force_leave": false, "rules.wage.function": 2, diff --git a/conf/e3/rules.xml b/conf/e3/rules.xml index d59787551..b86a397c8 100644 --- a/conf/e3/rules.xml +++ b/conf/e3/rules.xml @@ -21,8 +21,6 @@ - - diff --git a/res/core/calendar.xml b/res/core/calendar.xml deleted file mode 100644 index d96037698..000000000 --- a/res/core/calendar.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/core/de/strings.xml b/res/core/de/strings.xml index 349892e4e..c26bfe03b 100644 --- a/res/core/de/strings.xml +++ b/res/core/de/strings.xml @@ -6523,13 +6523,17 @@ Sonnenfeuer sunfire - + + neuer Zeitrechnung + of the new age + + des zweiten Zeitalters the second age - - neuer Zeitrechnung - of the new age + + des dritten Zeitalters + the third age diff --git a/res/e3a/strings.xml b/res/e3a/strings.xml index eb9f48cf3..e3c5b10ae 100644 --- a/res/e3a/strings.xml +++ b/res/e3a/strings.xml @@ -38,12 +38,6 @@ adamantium plates - - - des dritten Zeitalters - the third age - - Packeis fast ice @@ -87,6 +81,7 @@ repeating crossbows + Gerüst scaffolding @@ -103,6 +98,7 @@ Wache watch + Marktplatz marketplace diff --git a/scripts/eressea/frost.lua b/scripts/eressea/frost.lua index 2c2df4dae..beeef68f6 100644 --- a/scripts/eressea/frost.lua +++ b/scripts/eressea/frost.lua @@ -1,11 +1,11 @@ local function is_winter(turn) local season = get_season(turn) - return season == "calendar::winter" + return season == "winter" end local function is_spring(turn) local season = get_season(turn) - return season == "calendar::spring" + return season == "spring" end local function freeze(r, chance) diff --git a/scripts/eressea/xmasitems.lua b/scripts/eressea/xmasitems.lua index 27ea641ee..dffea2675 100644 --- a/scripts/eressea/xmasitems.lua +++ b/scripts/eressea/xmasitems.lua @@ -87,7 +87,7 @@ local self = {} function self.update() local turn = get_turn() local season = get_season(turn) - if season == "calendar::winter" then + if season == "winter" then eressea.log.debug("it is " .. season .. ", the christmas trees do their magic") local msg = message.create("xmastree_effect") for r in regions() do @@ -103,7 +103,7 @@ function self.update() end else local prevseason = get_season(turn-1) - if prevseason == "calendar::winter" then + if prevseason == "winter" then -- we celebrate knut and kick out the trees. for r in regions() do if r:get_key("xm06") then diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index eb118c931..6495bd5e6 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -11,8 +11,8 @@ function setup() end function test_calendar() - assert_equal(get_season(1011), "calendar::winter") - assert_equal(get_season(1012), "calendar::spring") + assert_equal("winter", get_season(1011)) + assert_equal("spring", get_season(1012)) end function test_herbalism() diff --git a/scripts/tests/e3/rules.lua b/scripts/tests/e3/rules.lua index 60adf77d1..7eb2f13a3 100644 --- a/scripts/tests/e3/rules.lua +++ b/scripts/tests/e3/rules.lua @@ -38,7 +38,7 @@ function teardown() end function test_calendar() - assert_equal(get_season(396), "calendar::winter") + assert_equal("winter", get_season(396)) end function disable_test_bug_1738_build_castle_e3() diff --git a/src/calendar.c b/src/calendar.c index 1804ff497..6fd717429 100644 --- a/src/calendar.c +++ b/src/calendar.c @@ -1,20 +1,35 @@ #include #include "calendar.h" +#include "move.h" /* storms */ + #include #include #include +#include int first_month = 0; int weeks_per_month = 3; int months_per_year = 12; -char **seasonnames = NULL; +const char *seasonnames[CALENDAR_SEASONS] = { "winter", "spring", "summer", "fall" }; char **weeknames = NULL; char **weeknames2 = NULL; -char **monthnames = NULL; int *month_season = NULL; -char *agename = NULL; -int seasons = 0; + +const char *calendar_month(int index) +{ + static char result[20]; + snprintf(result, sizeof(result), "month_%d", index + 1); + return result; +} + +const char *calendar_era(void) +{ + static char result[20]; + int era = config_get_int("game.era", 1); + snprintf(result, sizeof(result), "age_%d", era); + return result; +} int first_turn(void) { @@ -27,7 +42,7 @@ const gamedate *get_gamedate(int turn, gamedate * gd) int t = turn - first_turn(); assert(gd); - assert(t >= 0); + assert(t>=0); gd->week = t % weeks_per_month; /* 0 - weeks_per_month-1 */ gd->month = (t / weeks_per_month + first_month) % months_per_year; /* 0 - months_per_year-1 */ @@ -40,34 +55,17 @@ void calendar_cleanup(void) { int i; - free(agename); - - if (seasonnames) { - for (i = 0; i != seasons; ++i) { - free(seasonnames[i]); - } - free(seasonnames); - seasonnames = 0; - } - - if (monthnames) { - for (i = 0; i != months_per_year; ++i) { - free(monthnames[i]); - } - free(storms); - storms = 0; - free(month_season); - month_season = 0; - free(monthnames); - monthnames = 0; - } - for (i = 0; i != weeks_per_month; ++i) { if (weeknames) free(weeknames[i]); if (weeknames2) free(weeknames2[i]); } + + free(storms); + storms = 0; + free(month_season); + month_season = 0; free(weeknames); weeknames = 0; free(weeknames2); diff --git a/src/calendar.h b/src/calendar.h index d398cd77c..f8efa392c 100644 --- a/src/calendar.h +++ b/src/calendar.h @@ -11,17 +11,12 @@ extern "C" { SEASON_SUMMER, SEASON_AUTUMN }; - - extern char *agename; - extern int first_month; - - extern int seasons; - extern char **seasonnames; +#define CALENDAR_SEASONS 4 + extern const char *seasonnames[CALENDAR_SEASONS]; extern int months_per_year; - extern char **monthnames; extern int *month_season; - extern int *storms; /* in movement.c */ + extern int first_month; extern char **weeknames; extern char **weeknames2; @@ -36,6 +31,8 @@ extern "C" { const gamedate *get_gamedate(int turn, gamedate * gd); void calendar_cleanup(void); +const char *calendar_month(int index); +const char *calendar_era(void); int first_turn(void); #ifdef __cplusplus diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 9f96ea9d7..b7d79b64d 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -33,6 +33,8 @@ without prior permission by the authors of Eressea. /* game modules */ #include "prefix.h" +#include "move.h" +#include "calendar.h" /* util includes */ #include @@ -684,6 +686,74 @@ static void json_direction(cJSON *json, struct locale *lang) { } } +static void json_calendar(cJSON *json) { + cJSON *child; + if (json->type != cJSON_Object) { + log_error("calendar is not an object: %d", json->type); + return; + } + for (child = json->child; child; child = child->next) { + if (strcmp(child->string, "start") == 0) { + config_set_int("game.start", child->valueint); + } + else if (strcmp(child->string, "weeks") == 0) { + cJSON *entry; + int i; + if (child->type != cJSON_Array) { + log_error("calendar.weeks is not an array: %d", json->type); + return; + } + weeks_per_month = cJSON_GetArraySize(child); + free(weeknames); + weeknames = malloc(sizeof(char *) * weeks_per_month); + for (i = 0, entry = child->child; entry; entry = entry->next, ++i) { + if (entry->type == cJSON_String) { + weeknames[i] = strdup(entry->valuestring); + } + else { + log_error("calendar.weeks[%d] is not a string: %d", i, json->type); + free(weeknames); + weeknames = NULL; + return; + } + } + assert(i == weeks_per_month); + free(weeknames2); + weeknames2 = malloc(sizeof(char *) * weeks_per_month); + for (i = 0; i != weeks_per_month; ++i) { + weeknames2[i] = malloc(strlen(weeknames[i]) + 3); + sprintf(weeknames2[i], "%s_d", weeknames[i]); + } + } + else if (strcmp(child->string, "months") == 0) { + cJSON *jmonth; + int i; + if (child->type != cJSON_Array) { + log_error("calendar.seasons is not an array: %d", json->type); + return; + } + free(month_season); + month_season = NULL; + free(storms); + months_per_year = cJSON_GetArraySize(child); + storms = malloc(sizeof(int) * months_per_year); + month_season = malloc(sizeof(int) * months_per_year); + for (i = 0, jmonth = child->child; jmonth; jmonth = jmonth->next, ++i) { + if (jmonth->type == cJSON_Object) { + storms[i] = cJSON_GetObjectItem(jmonth, "storm")->valueint; + month_season[i] = cJSON_GetObjectItem(jmonth, "season")->valueint; + } + else { + log_error("calendar.months[%d] is not an object: %d", i, json->type); + free(storms); + storms = NULL; + return; + } + } + } + } +} + static void json_directions(cJSON *json) { cJSON *child; if (json->type != cJSON_Object) { @@ -890,6 +960,9 @@ void json_config(cJSON *json) { else if (strcmp(child->string, "strings") == 0) { json_strings(child); } + else if (strcmp(child->string, "calendar") == 0) { + json_calendar(child); + } else if (strcmp(child->string, "directions") == 0) { json_directions(child); } diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 080ff4207..7ba3ceb94 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -30,6 +30,7 @@ without prior permission by the authors of Eressea. #include "spellbook.h" #include "calendar.h" #include "prefix.h" +#include "move.h" #include "vortex.h" @@ -398,6 +399,7 @@ static int parse_buildings(xmlDocPtr doc) return 0; } +#if 0 static int parse_calendar(xmlDocPtr doc) { xmlXPathContextPtr xpath = xmlXPathNewContext(doc); @@ -523,7 +525,7 @@ static int parse_calendar(xmlDocPtr doc) return 0; } - +#endif static int parse_ships(xmlDocPtr doc) { xmlXPathContextPtr xpath = xmlXPathNewContext(doc); @@ -1869,7 +1871,6 @@ static int parse_strings(xmlDocPtr doc) void register_xmlreader(void) { xml_register_callback(parse_races); - xml_register_callback(parse_calendar); xml_register_callback(parse_resources); xml_register_callback(parse_buildings); /* requires resources */ diff --git a/src/move.h b/src/move.h index 4d0b4e9f2..d5b07fef9 100644 --- a/src/move.h +++ b/src/move.h @@ -34,6 +34,7 @@ extern "C" { struct order; extern struct attrib_type at_shiptrail; + extern int *storms; /* die Zahlen sind genau quivalent zu den race Flags */ #define MV_CANNOTMOVE (1<<5) diff --git a/src/report.c b/src/report.c index dbcf54ff1..188d8dfa9 100644 --- a/src/report.c +++ b/src/report.c @@ -123,13 +123,15 @@ static char *gamedate_season(const struct locale *lang) static char buf[256]; /* FIXME: static return value */ gamedate gd; + assert(weeknames); + get_gamedate(turn, &gd); sprintf(buf, (const char *)LOC(lang, "nr_calendar_season"), - LOC(lang, weeknames[gd.week]), - LOC(lang, monthnames[gd.month]), + LOC(lang, mkname("calendar", weeknames[gd.week])), + LOC(lang, mkname("calendar", calendar_month(gd.month))), gd.year, - agename ? LOC(lang, agename) : "", LOC(lang, seasonnames[gd.season])); + LOC(lang, mkname("calendar", calendar_era())), LOC(lang, mkname("calendar", seasonnames[gd.season]))); return buf; } diff --git a/src/summary.c b/src/summary.c index c18e54ee5..90cab98c0 100644 --- a/src/summary.c +++ b/src/summary.c @@ -151,13 +151,12 @@ static char *gamedate2(const struct locale *lang) if (weeknames2) { week = weeknames2[gd.week]; } - if (monthnames) { - month = monthnames[gd.month]; - } + month = calendar_month(gd.month); sprintf(buf, "in %s des Monats %s im Jahre %d %s.", - LOC(lang, week), - LOC(lang, month), - gd.year, agename ? LOC(lang, agename) : ""); + LOC(lang, mkname("calendar", week)), + LOC(lang, mkname("calendar", month)), + gd.year, + LOC(lang, mkname("calendar", calendar_era()))); return buf; } From 80ab32cf5128c0412b41d5744e495af4900f0b4d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 7 May 2017 17:48:59 +0200 Subject: [PATCH 200/218] remove calendar.xml from rules. --- conf/e2/rules.xml | 1 - conf/e3/rules.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/conf/e2/rules.xml b/conf/e2/rules.xml index c237773ab..7bde2205f 100644 --- a/conf/e2/rules.xml +++ b/conf/e2/rules.xml @@ -15,7 +15,6 @@ - diff --git a/conf/e3/rules.xml b/conf/e3/rules.xml index b86a397c8..7fbf7dc6e 100644 --- a/conf/e3/rules.xml +++ b/conf/e3/rules.xml @@ -10,7 +10,6 @@ - From 8765204e0060d6071690f567194fb7da83f0e4fd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 7 May 2017 18:10:18 +0200 Subject: [PATCH 201/218] add unit tests for calendar parsing. --- src/kernel/jsonconf.test.c | 64 +++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 456a27d22..2f54eeb8d 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -13,6 +13,8 @@ #include "order.h" #include "terrain.h" +#include "move.h" +#include "calendar.h" #include "prefix.h" #include "util/language.h" @@ -75,7 +77,7 @@ static void test_settings(CuTest * tc) "\"float\" : 1.5 }}"; cJSON *json = cJSON_Parse(data); - test_cleanup(); + test_setup(); config_set("game.id", "42"); /* should not be replaced */ config_set("game.name", "Eressea"); /* should not be replaced */ json_config(json); @@ -99,7 +101,7 @@ static void test_prefixes(CuTest * tc) "]}"; cJSON *json = cJSON_Parse(data); - test_cleanup(); + test_setup(); json_config(json); CuAssertPtrNotNull(tc, race_prefixes); CuAssertStrEquals(tc, "snow", race_prefixes[0]); @@ -119,7 +121,7 @@ static void test_disable(CuTest * tc) "]}"; cJSON *json = cJSON_Parse(data); - test_cleanup(); + test_setup(); CuAssertTrue(tc, skill_enabled(SK_ALCHEMY)); CuAssertTrue(tc, !keyword_disabled(K_BANNER)); CuAssertTrue(tc, !keyword_disabled(K_PAY)); @@ -135,6 +137,31 @@ static void test_disable(CuTest * tc) test_cleanup(); } +static void test_calendar(CuTest * tc) +{ + const char * data = "{\"calendar\": { " + "\"weeks\" : [ \"one\", \"two\", \"three\" ]," + "\"months\" : [" + "{ \"storm\" : 99, \"season\" : 1 }," + "{ \"storm\" : 22, \"season\" : 2 }" + "]" + "}}"; + cJSON *json = cJSON_Parse(data); + + test_setup(); + json_config(json); + CuAssertPtrNotNull(tc, storms); + CuAssertIntEquals(tc, 2, months_per_year); + CuAssertIntEquals(tc, 3, weeks_per_month); + CuAssertIntEquals(tc, 99, storms[0]); + CuAssertIntEquals(tc, 22, storms[1]); + CuAssertPtrNotNull(tc, month_season); + CuAssertIntEquals(tc, 1, month_season[0]); + CuAssertIntEquals(tc, 2, month_season[1]); + cJSON_Delete(json); + test_cleanup(); +} + static void test_races(CuTest * tc) { const char * data = "{\"races\": { \"orc\" : { " @@ -155,7 +182,7 @@ static void test_races(CuTest * tc) cJSON *json = cJSON_Parse(data); const struct race *rc; - test_cleanup(); + test_setup(); CuAssertPtrNotNull(tc, json); CuAssertPtrEquals(tc, 0, races); @@ -189,7 +216,7 @@ static void test_findrace(CuTest *tc) { const race *rc; CuAssertPtrNotNull(tc, json); - test_cleanup(); + test_setup(); lang = get_or_create_locale("de"); CuAssertPtrEquals(tc, 0, (void *)findrace("Zwerg", lang)); @@ -211,7 +238,7 @@ static void test_items(CuTest * tc) cJSON *json = cJSON_Parse(data); const item_type * itype; - test_cleanup(); + test_setup(); CuAssertPtrNotNull(tc, json); CuAssertPtrEquals(tc, 0, it_find("axe")); @@ -249,7 +276,7 @@ static void test_ships(CuTest * tc) const ship_type *st; const terrain_type *ter; - test_cleanup(); + test_setup(); CuAssertPtrNotNull(tc, json); CuAssertPtrEquals(tc, 0, shiptypes); @@ -286,7 +313,7 @@ static void test_castles(CuTest *tc) { cJSON *json = cJSON_Parse(data); const building_type *bt; - test_cleanup(); + test_setup(); CuAssertPtrNotNull(tc, json); CuAssertPtrEquals(tc, 0, buildingtypes); @@ -311,7 +338,7 @@ static void test_spells(CuTest * tc) cJSON *json = cJSON_Parse(data); const spell *sp; - test_cleanup(); + test_setup(); CuAssertPtrNotNull(tc, json); CuAssertPtrEquals(tc, 0, find_spell("fireball")); @@ -350,7 +377,7 @@ static void test_buildings(CuTest * tc) cJSON *json = cJSON_Parse(building_data); const building_type *bt; - test_cleanup(); + test_setup(); CuAssertPtrNotNull(tc, json); CuAssertPtrEquals(tc, 0, buildingtypes); @@ -400,7 +427,7 @@ static void test_buildings_default(CuTest * tc) const building_type *bt; building_type clone; - test_cleanup(); + test_setup(); bt = bt_get_or_create("house"); clone = *bt; @@ -425,7 +452,7 @@ static void test_ships_default(CuTest * tc) const ship_type *st; ship_type clone; - test_cleanup(); + test_setup(); st = st_get_or_create("hodor"); clone = *st; @@ -446,7 +473,7 @@ static void test_configs(CuTest * tc) FILE *F; cJSON *json = cJSON_Parse(data); - test_cleanup(); + test_setup(); F = fopen("test.json", "w"); fwrite(building_data, 1, strlen(building_data), F); @@ -475,7 +502,7 @@ static void test_terrains(CuTest * tc) cJSON *json = cJSON_Parse(data); - test_cleanup(); + test_setup(); CuAssertPtrNotNull(tc, json); CuAssertPtrEquals(tc, 0, (void *)get_terrain("plain")); @@ -511,7 +538,7 @@ static void test_directions(CuTest * tc) cJSON *json = cJSON_Parse(data); - test_cleanup(); + test_setup(); lang = get_or_create_locale("de"); CuAssertPtrNotNull(tc, json); CuAssertIntEquals(tc, NODIRECTION, get_direction("ost", lang)); @@ -533,7 +560,7 @@ static void test_skills(CuTest * tc) cJSON *json = cJSON_Parse(data); - test_cleanup(); + test_setup(); lang = get_or_create_locale("de"); CuAssertPtrNotNull(tc, json); CuAssertIntEquals(tc, NOSKILL, get_skill("potato", lang)); @@ -558,7 +585,7 @@ static void test_keywords(CuTest * tc) cJSON *json = cJSON_Parse(data); - test_cleanup(); + test_setup(); lang = get_or_create_locale("de"); CuAssertPtrNotNull(tc, json); CuAssertIntEquals(tc, NOKEYWORD, get_keyword("potato", lang)); @@ -583,7 +610,7 @@ static void test_strings(CuTest * tc) cJSON *json = cJSON_Parse(data); CuAssertPtrNotNull(tc, json); - test_cleanup(); + test_setup(); lang = get_or_create_locale("de"); CuAssertPtrNotNull(tc, lang); CuAssertPtrEquals(tc, NULL, (void *)LOC(lang, "move")); @@ -640,6 +667,7 @@ CuSuite *get_jsonconf_suite(void) SUITE_ADD_TEST(suite, test_prefixes); SUITE_ADD_TEST(suite, test_disable); SUITE_ADD_TEST(suite, test_infinitive_from_config); + SUITE_ADD_TEST(suite, test_calendar); return suite; } From 18defdd5a23f0621e6879f5c9870e8d6142bf557 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 7 May 2017 20:21:49 +0200 Subject: [PATCH 202/218] remove last pieces of calendar.xml --- conf/e2/config.xml | 24 ++++++++ src/kernel/xmlreader.c | 127 ----------------------------------------- 2 files changed, 24 insertions(+), 127 deletions(-) create mode 100644 conf/e2/config.xml diff --git a/conf/e2/config.xml b/conf/e2/config.xml new file mode 100644 index 000000000..0de6bff76 --- /dev/null +++ b/conf/e2/config.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 7ba3ceb94..f595ec7a4 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -399,133 +399,6 @@ static int parse_buildings(xmlDocPtr doc) return 0; } -#if 0 -static int parse_calendar(xmlDocPtr doc) -{ - xmlXPathContextPtr xpath = xmlXPathNewContext(doc); - xmlXPathObjectPtr xpathCalendars; - xmlNodeSetPtr nsetCalendars; - - xpathCalendars = xmlXPathEvalExpression(BAD_CAST "/eressea/calendar", xpath); - nsetCalendars = xpathCalendars->nodesetval; - if (nsetCalendars != NULL && nsetCalendars->nodeNr != 0) { - int c; - for (c = 0; c != nsetCalendars->nodeNr; ++c) { - xmlNodePtr calendar = nsetCalendars->nodeTab[c]; - xmlXPathObjectPtr xpathWeeks, xpathMonths, xpathSeasons; - xmlNodeSetPtr nsetWeeks, nsetMonths, nsetSeasons; - xmlChar *propValue = xmlGetProp(calendar, BAD_CAST "name"); - xmlChar *newyear = xmlGetProp(calendar, BAD_CAST "newyear"); - xmlChar *start; - - start = xmlGetProp(calendar, BAD_CAST "start"); - if (start && config_get("game.start") == NULL) { - config_set("game.start", (const char *)start); - xmlFree(start); - } - if (propValue) { - free(agename); - agename = strdup(mkname("calendar", (const char *)propValue)); - xmlFree(propValue); - } - - xpath->node = calendar; - xpathWeeks = xmlXPathEvalExpression(BAD_CAST "week", xpath); - nsetWeeks = xpathWeeks->nodesetval; - if (nsetWeeks != NULL && nsetWeeks->nodeNr) { - int i; - - weeks_per_month = nsetWeeks->nodeNr; - free(weeknames); - free(weeknames2); - weeknames = malloc(sizeof(char *) * weeks_per_month); - weeknames2 = malloc(sizeof(char *) * weeks_per_month); - for (i = 0; i != nsetWeeks->nodeNr; ++i) { - xmlNodePtr week = nsetWeeks->nodeTab[i]; - xmlChar *propValue = xmlGetProp(week, BAD_CAST "name"); - if (propValue) { - weeknames[i] = strdup(mkname("calendar", (const char *)propValue)); - weeknames2[i] = malloc(strlen(weeknames[i]) + 3); - sprintf(weeknames2[i], "%s_d", weeknames[i]); - xmlFree(propValue); - } - } - } - xmlXPathFreeObject(xpathWeeks); - - xpathSeasons = xmlXPathEvalExpression(BAD_CAST "season", xpath); - nsetSeasons = xpathSeasons->nodesetval; - if (nsetSeasons != NULL && nsetSeasons->nodeNr) { - int i; - - seasons = nsetSeasons->nodeNr; - assert(!seasonnames); - seasonnames = malloc(sizeof(char *) * seasons); - - for (i = 0; i != nsetSeasons->nodeNr; ++i) { - xmlNodePtr season = nsetSeasons->nodeTab[i]; - xmlChar *propValue = xmlGetProp(season, BAD_CAST "name"); - if (propValue) { - seasonnames[i] = - strdup(mkname("calendar", (const char *)propValue)); - xmlFree(propValue); - } - } - } - - xpathMonths = xmlXPathEvalExpression(BAD_CAST "season/month", xpath); - nsetMonths = xpathMonths->nodesetval; - if (nsetMonths != NULL && nsetMonths->nodeNr) { - int i; - - months_per_year = nsetMonths->nodeNr; - free(monthnames); - monthnames = malloc(sizeof(char *) * months_per_year); - free(month_season); - month_season = malloc(sizeof(int) * months_per_year); - free(storms); - storms = malloc(sizeof(int) * months_per_year); - - for (i = 0; i != nsetMonths->nodeNr; ++i) { - xmlNodePtr month = nsetMonths->nodeTab[i]; - xmlChar *propValue = xmlGetProp(month, BAD_CAST "name"); - - if (propValue) { - if (newyear - && strcmp((const char *)newyear, (const char *)propValue) == 0) { - first_month = i; - xmlFree(newyear); - newyear = NULL; - } - monthnames[i] = strdup(mkname("calendar", (const char *)propValue)); - xmlFree(propValue); - } - if (nsetSeasons) { - int j; - for (j = 0; j != seasons; ++j) { - xmlNodePtr season = month->parent; - if (season == nsetSeasons->nodeTab[j]) { - month_season[i] = j; - break; - } - } - assert(j != seasons); - } - storms[i] = xml_ivalue(nsetMonths->nodeTab[i], "storm", 0); - } - } - xmlXPathFreeObject(xpathMonths); - xmlXPathFreeObject(xpathSeasons); - xmlFree(newyear); - newyear = NULL; - } - } - xmlXPathFreeObject(xpathCalendars); - xmlXPathFreeContext(xpath); - - return 0; -} -#endif static int parse_ships(xmlDocPtr doc) { xmlXPathContextPtr xpath = xmlXPathNewContext(doc); From 4fdfbb44b59b10ca298ab3ad4976725f96599936 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 8 May 2017 08:15:18 +0200 Subject: [PATCH 203/218] this config.xml was added by accident. --- conf/e2/config.xml | 24 ------------------------ s/setup | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 conf/e2/config.xml diff --git a/conf/e2/config.xml b/conf/e2/config.xml deleted file mode 100644 index 0de6bff76..000000000 --- a/conf/e2/config.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/s/setup b/s/setup index e3e8e113d..adf4e0b85 100755 --- a/s/setup +++ b/s/setup @@ -56,7 +56,7 @@ done [ -z $INIFILE ] && INIFILE=$TOOLS/inifile [ -e $INIFILE ] || INIFILE=$TOOLS/iniparser/inifile -[ -e $SOURCE/conf/$rules/config.xml ] || abort "cannot find conf/$rules/config.xml" +[ -e $SOURCE/conf/$rules/config.json ] || abort "cannot find conf/$rules/config.json" cd $ERESSEA if [ -d $dir ] ; then From 53dc475d9d55d73526f23a78eb8390dfab46b1c9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 8 May 2017 22:41:00 +0200 Subject: [PATCH 204/218] remove unused callback functions. --- src/helpers.c | 165 -------------------------------------------------- 1 file changed, 165 deletions(-) diff --git a/src/helpers.c b/src/helpers.c index ab59ea60c..e4397bd46 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -211,43 +211,6 @@ static int lua_callspell(castorder * co, const char *fname) return result; } -/** callback to initialize a familiar from lua. */ -static int lua_initfamiliar(unit * u) -{ - lua_State *L = (lua_State *)global.vm_state; - char fname[64]; - int result = -1; - - strlcpy(fname, "initfamiliar_", sizeof(fname)); - strlcat(fname, u_race(u)->_name, sizeof(fname)); - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, u, TOLUA_CAST "unit"); - - if (lua_pcall(L, 1, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("familiar(%s) calling '%s': %s.\n", unitname(u), fname, error); - lua_pop(L, 1); - } - else { - result = (int)lua_tonumber(L, -1); - lua_pop(L, 1); - } - } - else { - log_warning("familiar(%s) calling '%s': not a function.\n", unitname(u), fname); - lua_pop(L, 1); - } - - create_mage(u, M_GRAY); - - strlcpy(fname, u_race(u)->_name, sizeof(fname)); - strlcat(fname, "_familiar", sizeof(fname)); - equip_unit(u, get_equipment(fname)); - return result; -} - static int lua_changeresource(unit * u, const struct resource_type *rtype, int delta) { @@ -281,127 +244,6 @@ lua_changeresource(unit * u, const struct resource_type *rtype, int delta) return result; } -static int lua_getresource(unit * u, const struct resource_type *rtype) -{ - lua_State *L = (lua_State *)global.vm_state; - int result = -1; - char fname[64]; - - strlcpy(fname, rtype->_name, sizeof(fname)); - strlcat(fname, "_getresource", sizeof(fname)); - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, u, TOLUA_CAST "unit"); - - if (lua_pcall(L, 1, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("get(%s) calling '%s': %s.\n", unitname(u), fname, error); - lua_pop(L, 1); - } - else { - result = (int)lua_tonumber(L, -1); - lua_pop(L, 1); - } - } - else { - log_error("get(%s) calling '%s': not a function.\n", unitname(u), fname); - lua_pop(L, 1); - } - - return result; -} - -static int -lua_wage(const region * r, const faction * f, const race * rc, int in_turn) -{ - lua_State *L = (lua_State *)global.vm_state; - const char *fname = "wage"; - int result = -1; - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, (void *)r, TOLUA_CAST "region"); - tolua_pushusertype(L, (void *)f, TOLUA_CAST "faction"); - tolua_pushstring(L, rc ? rc->_name : 0); - lua_pushinteger(L, in_turn); - - if (lua_pcall(L, 3, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("wage(%s) calling '%s': %s.\n", regionname(r, NULL), fname, error); - lua_pop(L, 1); - } - else { - result = (int)lua_tonumber(L, -1); - lua_pop(L, 1); - } - } - else { - log_error("wage(%s) calling '%s': not a function.\n", regionname(r, NULL), fname); - lua_pop(L, 1); - } - - return result; -} - -static int lua_maintenance(const unit * u) -{ - lua_State *L = (lua_State *)global.vm_state; - const char *fname = "maintenance"; - int result = -1; - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); - - if (lua_pcall(L, 1, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("maintenance(%s) calling '%s': %s.\n", unitname(u), fname, error); - lua_pop(L, 1); - } - else { - result = (int)lua_tonumber(L, -1); - lua_pop(L, 1); - } - } - else { - log_error("maintenance(%s) calling '%s': not a function.\n", unitname(u), fname); - lua_pop(L, 1); - } - - return result; -} - -static int lua_equipmentcallback(const struct equipment *eq, unit * u) -{ - lua_State *L = (lua_State *)global.vm_state; - char fname[64]; - int result = -1; - - strlcpy(fname, "equip_", sizeof(fname)); - strlcat(fname, eq->name, sizeof(fname)); - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); - - if (lua_pcall(L, 1, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("equip(%s) calling '%s': %s.\n", unitname(u), fname, error); - lua_pop(L, 1); - } - else { - result = (int)lua_tonumber(L, -1); - lua_pop(L, 1); - } - } - else { - log_error("equip(%s) calling '%s': not a function.\n", unitname(u), fname); - lua_pop(L, 1); - } - return result; -} - /** callback for an item-use function written in lua. */ static int use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord) @@ -447,7 +289,6 @@ use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord) return result; } - /* compat code for old data files */ static int caldera_read(trigger *t, struct gamedata *data) { @@ -470,13 +311,7 @@ void register_tolua_helpers(void) callbacks.cast_spell = lua_callspell; - register_function((pf_generic)lua_initfamiliar, "lua_initfamiliar"); - register_function((pf_generic)lua_getresource, "lua_getresource"); register_function((pf_generic)lua_changeresource, "lua_changeresource"); - register_function((pf_generic)lua_equipmentcallback, "lua_equip"); - - register_function((pf_generic)lua_wage, "lua_wage"); - register_function((pf_generic)lua_maintenance, "lua_maintenance"); item_use_fun = use_item_lua; res_produce_fun = produce_resource_lua; From d9fca4dcb3c3b03822e3059ff35d71446874742b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 8 May 2017 22:44:18 +0200 Subject: [PATCH 205/218] refactor stray fptr variable into callbacks module. --- src/helpers.c | 7 +++---- src/kernel/callbacks.h | 6 ++++++ src/kernel/resources.c | 2 -- src/kernel/resources.h | 2 -- src/laws.c | 3 ++- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/helpers.c b/src/helpers.c index e4397bd46..25079c549 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -310,11 +310,10 @@ void register_tolua_helpers(void) at_register(&at_building_action); callbacks.cast_spell = lua_callspell; - - register_function((pf_generic)lua_changeresource, "lua_changeresource"); - - item_use_fun = use_item_lua; + callbacks.use_item = use_item_lua; res_produce_fun = produce_resource_lua; res_limit_fun = limit_resource_lua; + + register_function((pf_generic)lua_changeresource, "lua_changeresource"); register_item_give(lua_giveitem, "lua_giveitem"); } diff --git a/src/kernel/callbacks.h b/src/kernel/callbacks.h index f42d25d3f..0aa71daca 100644 --- a/src/kernel/callbacks.h +++ b/src/kernel/callbacks.h @@ -24,9 +24,15 @@ extern "C" { #endif struct castorder; + struct order; + struct unit; + struct item_type; struct callback_struct { int (*cast_spell)(struct castorder *co, const char *fname); + int (*use_item)(struct unit *u, const struct item_type *itype, + int amount, struct order *ord); + }; extern struct callback_struct callbacks; diff --git a/src/kernel/resources.c b/src/kernel/resources.c index 8d6e1c2ac..fe18ae640 100644 --- a/src/kernel/resources.c +++ b/src/kernel/resources.c @@ -213,8 +213,6 @@ struct rawmaterial_type *rmt_create(struct resource_type *rtype) return rmtype; } -int(*item_use_fun)(struct unit *u, const struct item_type *itype, int amount, - struct order *ord); int(*res_limit_fun)(const struct region *, const struct resource_type *); void(*res_produce_fun)(struct region *, const struct resource_type *, int); diff --git a/src/kernel/resources.h b/src/kernel/resources.h index 1868dffc0..e7a232d27 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -73,8 +73,6 @@ extern "C" { extern int(*res_limit_fun)(const struct region *, const struct resource_type *); extern void(*res_produce_fun)(struct region *, const struct resource_type *, int); - extern int (*item_use_fun)(struct unit *, const struct item_type *, int amount, - struct order *ord); int limit_resource(const struct region *r, const struct resource_type *rtype); void produce_resource(struct region *r, const struct resource_type *rtype, int amount); diff --git a/src/laws.c b/src/laws.c index 250738f76..5bb87f4fb 100644 --- a/src/laws.c +++ b/src/laws.c @@ -45,6 +45,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* kernel includes */ #include #include +#include #include #include #include @@ -3218,7 +3219,7 @@ static int use_item(unit * u, const item_type * itype, int amount, struct order } if (itype->flags & ITF_CANUSE) { - int result = item_use_fun(u, itype, amount, ord); + int result = callbacks.use_item(u, itype, amount, ord); if (result > 0) { use_pooled(u, itype->rtype, GET_DEFAULT, result); } From 6b7dcadf84ccb1fc30ef1045f4387676527f47bb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 9 May 2017 08:18:20 +0200 Subject: [PATCH 206/218] refactor resource callbacks into callbacks module --- src/helpers.c | 4 ++-- src/kernel/callbacks.h | 5 ++++- src/kernel/resources.c | 14 ++++++-------- src/kernel/resources.h | 5 +++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/helpers.c b/src/helpers.c index 25079c549..7591dba9f 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -311,8 +311,8 @@ void register_tolua_helpers(void) callbacks.cast_spell = lua_callspell; callbacks.use_item = use_item_lua; - res_produce_fun = produce_resource_lua; - res_limit_fun = limit_resource_lua; + callbacks.produce_resource = produce_resource_lua; + callbacks.limit_resource = limit_resource_lua; register_function((pf_generic)lua_changeresource, "lua_changeresource"); register_item_give(lua_giveitem, "lua_giveitem"); diff --git a/src/kernel/callbacks.h b/src/kernel/callbacks.h index 0aa71daca..dcdf6ac90 100644 --- a/src/kernel/callbacks.h +++ b/src/kernel/callbacks.h @@ -26,13 +26,16 @@ extern "C" { struct castorder; struct order; struct unit; + struct region; struct item_type; + struct resource_type; struct callback_struct { int (*cast_spell)(struct castorder *co, const char *fname); int (*use_item)(struct unit *u, const struct item_type *itype, int amount, struct order *ord); - + void(*produce_resource)(struct region *, const struct resource_type *, int); + int(*limit_resource)(const struct region *, const struct resource_type *); }; extern struct callback_struct callbacks; diff --git a/src/kernel/resources.c b/src/kernel/resources.c index fe18ae640..842cb83ba 100644 --- a/src/kernel/resources.c +++ b/src/kernel/resources.c @@ -11,10 +11,11 @@ */ #include -#include #include "resources.h" /* kernel includes */ +#include +#include #include "build.h" #include "item.h" #include "region.h" @@ -213,14 +214,11 @@ struct rawmaterial_type *rmt_create(struct resource_type *rtype) return rmtype; } -int(*res_limit_fun)(const struct region *, const struct resource_type *); -void(*res_produce_fun)(struct region *, const struct resource_type *, int); - int limit_resource(const struct region *r, const resource_type *rtype) { assert(!rtype->raw); - if (res_limit_fun) { - return res_limit_fun(r, rtype); + if (callbacks.limit_resource) { + return callbacks.limit_resource(r, rtype); } return -1; } @@ -228,7 +226,7 @@ int limit_resource(const struct region *r, const resource_type *rtype) void produce_resource(struct region *r, const struct resource_type *rtype, int amount) { assert(!rtype->raw); - if (res_produce_fun) { - res_produce_fun(r, rtype, amount); + if (callbacks.produce_resource) { + callbacks.produce_resource(r, rtype, amount); } } diff --git a/src/kernel/resources.h b/src/kernel/resources.h index e7a232d27..2daa44dd8 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -15,8 +15,11 @@ extern "C" { #endif +#include + struct building_type; struct race; + struct region; enum { RM_USED = 1 << 0, /* resource has been used */ @@ -71,8 +74,6 @@ extern "C" { int base, int divisor, const struct resource_type *rtype); struct rawmaterial_type *rmt_create(struct resource_type *rtype); - extern int(*res_limit_fun)(const struct region *, const struct resource_type *); - extern void(*res_produce_fun)(struct region *, const struct resource_type *, int); int limit_resource(const struct region *r, const struct resource_type *rtype); void produce_resource(struct region *r, const struct resource_type *rtype, int amount); From c7f8b16c0790c8572100d374c2d193e7e74148b8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 9 May 2017 18:49:10 +0200 Subject: [PATCH 207/218] remove unused r->land->items list. --- src/creport.c | 3 --- src/kernel/item.c | 22 ++++++++++++---------- src/kernel/region.c | 9 +-------- src/kernel/region.h | 1 - src/kernel/save.c | 5 +++-- src/util/gamedata.h | 3 ++- 6 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/creport.c b/src/creport.c index 4dfacad2c..10dc4c323 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1416,9 +1416,6 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r) } } } - if (r->land) { - print_items(F, r->land->items, f->locale); - } cr_output_curses_compat(F, f, r, TYP_REGION); cr_borders(r, f, r->seen.mode, F); if (r->seen.mode == seen_unit && is_astral(r) diff --git a/src/kernel/item.c b/src/kernel/item.c index b83d0fac4..04274d633 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -911,25 +911,27 @@ void read_items(struct storage *store, item ** ilist) { for (;;) { char ibuf[32]; - const item_type *itype; int i; READ_STR(store, ibuf, sizeof(ibuf)); if (!strcmp("end", ibuf)) { break; } - itype = it_find(ibuf); READ_INT(store, &i); - if (i <= 0) { - log_error("data contains an entry with %d %s", i, ibuf); - } - else { - if (itype && itype->rtype) { - i_change(ilist, itype, i); + if (ilist) { + const item_type *itype; + itype = it_find(ibuf); + if (i <= 0) { + log_error("data contains an entry with %d %s", i, ibuf); } else { - log_error("data contains unknown item type %s.", ibuf); + if (itype && itype->rtype) { + i_change(ilist, itype, i); + } + else { + log_error("data contains unknown item type %s.", ibuf); + } + assert(itype && itype->rtype); } - assert(itype && itype->rtype); } } } diff --git a/src/kernel/region.c b/src/kernel/region.c index 492d6e438..5cb86ff47 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -1080,8 +1080,7 @@ void terraform_region(region * r, const terrain_type * terrain) if (!fval(terrain, LAND_REGION)) { region_setinfo(r, NULL); - if (r->land != NULL) { - i_freeall(&r->land->items); + if (r->land) { free_land(r->land); r->land = NULL; } @@ -1101,7 +1100,6 @@ void terraform_region(region * r, const terrain_type * terrain) for (d = 0; d != MAXDIRECTIONS; ++d) { rsetroad(r, d, 0); } - i_freeall(&r->land->items); } else { static struct surround { @@ -1176,11 +1174,6 @@ void terraform_region(region * r, const terrain_type * terrain) if (fval(terrain, LAND_REGION)) { const item_type *itype = NULL; - char equip_hash[64]; - - /* TODO: put the equipment in struct terrain, faster */ - sprintf(equip_hash, "terrain_%s", terrain->_name); - equip_items(&r->land->items, get_equipment(equip_hash)); if (r->terrain->herbs) { int len = 0; diff --git a/src/kernel/region.h b/src/kernel/region.h index 75c9a76db..e3204d129 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -105,7 +105,6 @@ extern "C" { int peasants; int newpeasants; int money; - struct item *items; /* items that can be claimed */ struct region_owner *ownership; } land_region; diff --git a/src/kernel/save.c b/src/kernel/save.c index cd944f345..39f2a129f 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1021,7 +1021,9 @@ static region *readregion(struct gamedata *data, int x, int y) if (!r->land->demands) { fix_demand(r); } - read_items(data->store, &r->land->items); + if (data->version < NOLANDITEM_VERSION) { + read_items(data->store, NULL); + } if (data->version >= REGIONOWNER_VERSION) { READ_INT(data->store, &n); region_set_morale(r, MAX(0, (short)n), -1); @@ -1095,7 +1097,6 @@ void writeregion(struct gamedata *data, const region * r) WRITE_INT(data->store, demand->value); } WRITE_TOK(data->store, "end"); - write_items(data->store, r->land->items); WRITE_SECTION(data->store); #if RELEASE_VERSION>=REGIONOWNER_VERSION WRITE_INT(data->store, region_get_morale(r)); diff --git a/src/util/gamedata.h b/src/util/gamedata.h index 75a750452..452a6e527 100644 --- a/src/util/gamedata.h +++ b/src/util/gamedata.h @@ -33,10 +33,11 @@ #define ATHASH_VERSION 353 /* attribute-type hash, not name */ #define NOWATCH_VERSION 354 /* plane->watchers is gone */ #define KEYVAL_VERSION 355 /* at_keys has values */ +#define NOLANDITEM_VERSION 356 /* land_region has no items */ /* unfinished: */ #define CRYPT_VERSION 400 /* passwords are encrypted */ -#define RELEASE_VERSION KEYVAL_VERSION /* current datafile */ +#define RELEASE_VERSION NOLANDITEM_VERSION /* current datafile */ #define MIN_VERSION INTPAK_VERSION /* minimal datafile we support */ #define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */ From 11d9afc62ed31cd225b7ddc78fb5019015eff9ec Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 12 May 2017 22:03:27 +0200 Subject: [PATCH 208/218] BUG 2322: Test and bugfix for castle names. --- scripts/tests/common.lua | 45 ++++++++++++++++++++++++++++++++++++++++ src/kernel/building.c | 3 --- src/kernel/building.h | 37 +++++++++++++++++---------------- 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index e612a17d7..936d2a79b 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1066,3 +1066,48 @@ function test_give_silver() assert_equal(21, r:get_resource("money")) assert_equal(10, u:get_item("money")) end + +function test_give_horses() + local r = region.create(0, 0, "plain") + local f = create_faction('human') + local u = unit.create(f, r, 1) + + r:set_resource("horse", 0) + u:add_item("horse", 21) + u:add_item("dolphin", 10) + u:add_order("GIB 0 7 PFERD") + u:add_order("GIB 0 5 DELPHIN") + process_orders() + assert_equal(7, r:get_resource("horse")) + assert_equal(5, u:get_item("dolphin")) + assert_equal(14, u:get_item("horse")) +end + +function test_give_silver() + local r = region.create(0, 0, "plain") + local f = create_faction('human') + local u = unit.create(f, r, 1) + + r:set_resource("peasant", 0) + r:set_resource("money", 11) + u:clear_orders() + u:add_item("money", 20) + u:add_order("GIB 0 10 SILBER") + process_orders() + assert_equal(21, r:get_resource("money")) + assert_equal(10, u:get_item("money")) +end + +function test_build_castle() + local r = region.create(0, 0, "plain") + local f = create_faction('human') + local u = unit.create(f, r, 1) + + u:add_item('stone', 1) + u:set_skill('building', 1) + u:add_order("MACHE BURG") + process_orders() + assert_not_nil(u.building) + assert_equal(1, u.building.size) + assert_equal(u.building.name, "Burg") +end diff --git a/src/kernel/building.c b/src/kernel/building.c index 31c4b3e27..431d44e9e 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -362,9 +362,6 @@ building *new_building(const struct building_type * btype, region * r, *bptr = b; update_lighthouse(b); - if (b->type->name) { - bname = LOC(lang, buildingtype(btype, b, 0)); - } if (!bname) { bname = LOC(lang, btype->_name); } diff --git a/src/kernel/building.h b/src/kernel/building.h index a2019e4a2..476424a92 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -76,6 +76,7 @@ extern "C" { extern struct selist *buildingtypes; extern struct attrib_type at_building_action; + extern struct attrib_type at_building_generic_type; int cmp_castle_size(const struct building *b, const struct building *a); int building_protection(const struct building_type *btype, int stage); @@ -114,13 +115,13 @@ extern "C" { int flags; } building; - extern struct attrib_type at_building_generic_type; - extern const char *buildingtype(const building_type * btype, + + const char *buildingtype(const building_type * btype, const struct building *b, int bsize); - extern const char *write_buildingname(const building * b, char *ibuf, + const char *write_buildingname(const building * b, char *ibuf, size_t size); - extern int buildingcapacity(const struct building *b); - extern struct building *new_building(const struct building_type *typ, + int buildingcapacity(const struct building *b); + struct building *new_building(const struct building_type *typ, struct region *r, const struct locale *lang); int build_building(struct unit *u, const struct building_type *typ, int id, int size, struct order *ord); @@ -145,9 +146,9 @@ extern "C" { void bunhash(struct building *b); int buildingcapacity(const struct building *b); - extern void remove_building(struct building **blist, struct building *b); - extern void free_building(struct building *b); - extern void free_buildings(void); + void remove_building(struct building **blist, struct building *b); + void free_building(struct building *b); + void free_buildings(void); const struct building_type *findbuildingtype(const char *name, const struct locale *lang); @@ -155,16 +156,16 @@ extern "C" { #include "build.h" #define NOBUILDING NULL - extern int resolve_building(variant data, void *address); - extern void write_building_reference(const struct building *b, + int resolve_building(variant data, void *address); + void write_building_reference(const struct building *b, struct storage *store); - extern variant read_building_reference(struct gamedata *data); + variant read_building_reference(struct gamedata *data); - extern struct building *findbuilding(int n); + struct building *findbuilding(int n); - extern struct unit *building_owner(const struct building *b); - extern void building_set_owner(struct unit * u); - extern void building_update_owner(struct building * bld); + struct unit *building_owner(const struct building *b); + void building_set_owner(struct unit * u); + void building_update_owner(struct building * bld); bool buildingtype_exists(const struct region *r, const struct building_type *bt, bool working); @@ -172,10 +173,10 @@ extern "C" { bool is_building_type(const struct building_type *btype, const char *name); struct building *active_building(const struct unit *u, const struct building_type *btype); - extern const char *buildingname(const struct building *b); + const char *buildingname(const struct building *b); - extern const char *building_getname(const struct building *b); - extern void building_setname(struct building *self, const char *name); + const char *building_getname(const struct building *b); + void building_setname(struct building *self, const char *name); struct region *building_getregion(const struct building *b); void building_setregion(struct building *bld, struct region *r); From 1bc23beccc8d018e1bd5b2fecb06932e71c2b768 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 12 May 2017 22:12:22 +0200 Subject: [PATCH 209/218] remove btypr->name funcptr and btype->attribs. why weren't these already gone? --- src/kernel/building.c | 3 --- src/kernel/building.h | 4 ---- src/kernel/building.test.c | 3 +-- src/kernel/jsonconf.c | 5 ----- src/kernel/xmlreader.c | 9 +-------- src/spells.c | 7 +------ 6 files changed, 3 insertions(+), 28 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 431d44e9e..92a4fd6f1 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -196,9 +196,6 @@ const char *buildingtype(const building_type * btype, const building * b, int bs } } } - if (btype->name) { - return btype->name(btype, b, bsize); - } if (btype->construction && btype->construction->name) { if (b) { bsize = adjust_size(b, bsize); diff --git a/src/kernel/building.h b/src/kernel/building.h index 476424a92..04ad08262 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -68,10 +68,6 @@ extern "C" { struct maintenance *maintenance; /* array of requirements */ struct construction *construction; /* construction of 1 building-level */ struct resource_mod *modifiers; /* modify production skills */ - - const char *(*name) (const struct building_type *, - const struct building * b, int size); - struct attrib *attribs; } building_type; extern struct selist *buildingtypes; diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index c1255373b..588ec2937 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -294,9 +294,8 @@ static void test_btype_defaults(CuTest *tc) { CuAssertStrEquals(tc, "hodor", btype->_name); CuAssertPtrEquals(tc, 0, btype->maintenance); CuAssertPtrEquals(tc, 0, btype->construction); - CuAssertTrue(tc, !btype->name); - CuAssertTrue(tc, !btype->taxes); CuAssertDblEquals(tc, 1.0, btype->auraregen, 0.0); + CuAssertIntEquals(tc, 0, btype->taxes); CuAssertIntEquals(tc, -1, btype->maxsize); CuAssertIntEquals(tc, 1, btype->capacity); CuAssertIntEquals(tc, -1, btype->maxcapacity); diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index b7d79b64d..609e73aac 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -339,11 +339,6 @@ static void json_building(cJSON *json, building_type *bt) { } break; case cJSON_String: - if (strcmp(child->string, "name") == 0) { - bt->name = (const char *(*)(const struct building_type *, - const struct building *, int))get_function(child->valuestring); - break; - } log_error("building %s contains unknown attribute %s", json->string, child->string); break; default: diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index f595ec7a4..9953f7335 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -356,14 +356,7 @@ static int parse_buildings(xmlDocPtr doc) continue; } assert(propValue != NULL); - if (strcmp((const char *)propValue, "name") == 0) { - btype->name = - (const char *(*)(const struct building_type *, - const struct building *, int))fun; - } - else { - log_error("unknown function type '%s' for building %s\n", (const char *)propValue, btype->_name); - } + log_error("unknown function type '%s' for building %s\n", (const char *)propValue, btype->_name); xmlFree(propValue); } xmlXPathFreeObject(result); diff --git a/src/spells.c b/src/spells.c index c515c0144..b1e5c0591 100644 --- a/src/spells.c +++ b/src/spells.c @@ -4534,12 +4534,7 @@ int sp_icastle(castorder * co) b->size = ((rng_int() % (int)(power)) + 1) * 5; } - if (type->name == NULL) { - bname = LOC(mage->faction->locale, type->_name); - } - else { - bname = LOC(mage->faction->locale, buildingtype(type, b, 0)); - } + bname = LOC(mage->faction->locale, buildingtype(type, b, 0)); building_setname(b, bname); /* TODO: Auf timeout und action_destroy umstellen */ From 7b0ec466fa7c6967858d729523698d0fb3ea06d4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 21 May 2017 13:09:54 +0200 Subject: [PATCH 210/218] only enable certain pragmas for MSVC 2015 and later --- src/platform.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform.h b/src/platform.h index 97d254e2d..9e2ecfadb 100644 --- a/src/platform.h +++ b/src/platform.h @@ -15,11 +15,13 @@ #define NO_MKDIR #define _CRT_SECURE_NO_WARNINGS #define _USE_MATH_DEFINES +#if _MSC_VER >= 1900 #pragma warning(disable: 4710 4820) #pragma warning(disable: 4100) // unreferenced formal parameter #pragma warning(disable: 4456) // declaration hides previous #pragma warning(disable: 4457) // declaration hides function parameter #pragma warning(disable: 4459) // declaration hides global +#endif #else /* assume gcc */ #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L # define va_copy(a,b) __va_copy(a,b) From efb0501b203418e929a98b875e8cbf244c68b97c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 12 Jul 2016 17:19:47 +0200 Subject: [PATCH 211/218] additional testing --- src/laws.test.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/laws.test.c b/src/laws.test.c index 36aafb4cb..34590be67 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1369,12 +1369,13 @@ static void test_show_elf(CuTest *tc) { unit *u; struct locale *loc; message * msg; + const struct item_type *itype; test_setup(); mt_register(mt_new_va("msg_event", "string:string", 0)); rc = test_create_race("elf"); - test_create_itemtype("elvenhorse"); + itype = test_create_itemtype("elvenhorse"); loc = test_create_locale(); locale_setstring(loc, "elvenhorse", "Elfenpferd"); @@ -1389,12 +1390,22 @@ static void test_show_elf(CuTest *tc) { u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); u->faction->locale = loc; ord = create_order(K_RESHOW, loc, "Elf"); + reshow_cmd(u, ord); CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "error36") == NULL); msg = test_find_messagetype(u->faction->msgs, "msg_event"); CuAssertPtrNotNull(tc, msg); CuAssertTrue(tc, memcmp("Elf:", msg->parameters[0].v, 4) == 0); test_clear_messages(u->faction); + + i_change(&u->items, itype, 1); + reshow_cmd(u, ord); + CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "error36") == NULL); + msg = test_find_messagetype(u->faction->msgs, "msg_event"); + CuAssertPtrNotNull(tc, msg); + CuAssertTrue(tc, memcmp("Elf:", msg->parameters[0].v, 4) == 0); + test_clear_messages(u->faction); + free_order(ord); test_cleanup(); } From bc0726da18df30c9ef1772435d1c38bf1406f7b2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 21 May 2017 14:52:46 +0200 Subject: [PATCH 212/218] remove duplicate test --- src/laws.test.c | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/src/laws.test.c b/src/laws.test.c index 66f6088ae..7e5df0b56 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1363,53 +1363,6 @@ static void test_show_without_item(CuTest *tc) test_cleanup(); } -static void test_show_elf(CuTest *tc) { - order *ord; - race * rc; - unit *u; - struct locale *loc; - message * msg; - const struct item_type *itype; - - test_setup(); - - mt_register(mt_new_va("msg_event", "string:string", 0)); - rc = test_create_race("elf"); - itype = test_create_itemtype("elvenhorse"); - - loc = test_create_locale(); - locale_setstring(loc, "elvenhorse", "Elfenpferd"); - locale_setstring(loc, "elvenhorse_p", "Elfenpferde"); - locale_setstring(loc, "race::elf_p", "Elfen"); - locale_setstring(loc, "race::elf", "Elf"); - init_locale(loc); - - CuAssertPtrNotNull(tc, finditemtype("elf", loc)); - CuAssertPtrNotNull(tc, findrace("elf", loc)); - - u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); - u->faction->locale = loc; - ord = create_order(K_RESHOW, loc, "Elf"); - - reshow_cmd(u, ord); - CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "error36") == NULL); - msg = test_find_messagetype(u->faction->msgs, "msg_event"); - CuAssertPtrNotNull(tc, msg); - CuAssertTrue(tc, memcmp("Elf:", msg->parameters[0].v, 4) == 0); - test_clear_messages(u->faction); - - i_change(&u->items, itype, 1); - reshow_cmd(u, ord); - CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "error36") == NULL); - msg = test_find_messagetype(u->faction->msgs, "msg_event"); - CuAssertPtrNotNull(tc, msg); - CuAssertTrue(tc, memcmp("Elf:", msg->parameters[0].v, 4) == 0); - test_clear_messages(u->faction); - - free_order(ord); - test_cleanup(); -} - static void test_show_race(CuTest *tc) { order *ord; race * rc; @@ -1664,7 +1617,6 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_name_building); SUITE_ADD_TEST(suite, test_name_ship); SUITE_ADD_TEST(suite, test_show_without_item); - SUITE_ADD_TEST(suite, test_show_elf); SUITE_ADD_TEST(suite, test_show_race); SUITE_ADD_TEST(suite, test_show_both); SUITE_ADD_TEST(suite, test_immigration); From 37aded9b1d1ace41db45d87e71d679b0bba9d3af Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 21 May 2017 16:12:13 +0200 Subject: [PATCH 213/218] remove unused function --- src/laws.test.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/laws.test.c b/src/laws.test.c index 7e5df0b56..4d6adbfe9 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1446,10 +1446,6 @@ static void test_show_both(CuTest *tc) { test_cleanup(); } -static int low_wage(const region * r, const faction * f, const race * rc, int in_turn) { - return 1; -} - static void test_immigration(CuTest * tc) { region *r; From a3f655f3226a0799a2cb311c6d8d6bc32763240c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 22 May 2017 21:35:25 +0200 Subject: [PATCH 214/218] fix bogus warnings --- src/kernel/building.c | 9 +++++---- src/kernel/ship.c | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 92a4fd6f1..bcc914cca 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -75,15 +75,16 @@ static building_type *bt_find_i(const char *name) if (match) { cb_get_kv(match, &btype, sizeof(btype)); } - else { - log_warning("st_find: could not find ship '%s'\n", name); - } return btype; } const building_type *bt_find(const char *name) { - return bt_find_i(name); + building_type *btype = bt_find_i(name); + if (!btype) { + log_warning("bt_find: could not find building '%s'\n", name); + } + return btype; } static int bt_changes = 1; diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 3a7608789..220c16619 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -97,14 +97,15 @@ static ship_type *st_find_i(const char *name) if (match) { cb_get_kv(match, &st, sizeof(st)); } - else { - log_warning("st_find: could not find ship '%s'\n", name); - } return st; } const ship_type *st_find(const char *name) { - return st_find_i(name); + ship_type *st = st_find_i(name); + if (!st) { + log_warning("st_find: could not find ship '%s'\n", name); + } + return st; } static void st_register(ship_type *stype) { From 8e15487a1eeae5f4b3706d8a40ffdcf2fc59f15e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 May 2017 06:27:25 +0200 Subject: [PATCH 215/218] BUG 2328: wrong calendar seasons. --- conf/calendar.json | 7 ++++--- scripts/tests/e2/e2features.lua | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/conf/calendar.json b/conf/calendar.json index 8a134dc40..43b01351a 100644 --- a/conf/calendar.json +++ b/conf/calendar.json @@ -2,17 +2,18 @@ "calendar" : { "months" : [ { "storm" : 60, "season" : 2 }, - { "storm" : 10, "season" : 2 }, - { "storm" : 60, "season" : 3 }, { "storm" : 10, "season" : 3 }, + { "storm" : 60, "season" : 3 }, + { "storm" : 10, "season" : 0 }, { "storm" : 60, "season" : 0 }, { "storm" : 80, "season" : 0 }, { "storm" : 50, "season" : 1 }, { "storm" : 30, "season" : 1 }, - { "storm" : 60, "season" : 1 } + + { "storm" : 60, "season" : 2 } ], "weeks" : [ "firstweek", "secondweek", "thirdweek" diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index 6495bd5e6..1a4047d63 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -404,3 +404,7 @@ function test_demonstealth() desc = u:show() assert_equal(nil, string.find(desc, "Drache")) end + +function test_calendar_season_2328() + assert_equal("fall", get_season(1026)) +end From a3ebddeae41b4faf88a44aba14e1ada9b75c693d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 May 2017 13:52:55 +0200 Subject: [PATCH 216/218] update cron to check environment for switches use server/bin instead of ~/bin --- etc/report-mail.de.txt | 10 ++++++++++ etc/report-mail.en.txt | 6 ++++++ etc/report-mail.txt | 14 ++++++++++++++ process/cron/crontab | 17 ----------------- process/cron/orders.cron | 4 ++++ process/cron/preview.cron | 4 +++- process/cron/run-eressea.cron | 20 ++++++++++++++++++-- process/orders.cron | 16 ---------------- process/run-turn | 3 +++ process/run-turn.sh | 22 ---------------------- 10 files changed, 58 insertions(+), 58 deletions(-) create mode 100644 etc/report-mail.de.txt create mode 100644 etc/report-mail.en.txt create mode 100644 etc/report-mail.txt delete mode 100644 process/cron/crontab delete mode 100755 process/orders.cron delete mode 100755 process/run-turn.sh diff --git a/etc/report-mail.de.txt b/etc/report-mail.de.txt new file mode 100644 index 000000000..e40d86b53 --- /dev/null +++ b/etc/report-mail.de.txt @@ -0,0 +1,10 @@ +Freust Du Dich, dass es diese Woche wieder einen Eressea-Report gibt? +Möchtest Du dazu beitragen, dass das auch nächste Woche wieder passiert? +Eressea ist ein freiwilliges gratis-Angebot, und die Spielleitung bezahlt +seit Jahren die Entwicklung und das Hosting aus eigener Tasche. Wenn Dir +das etwas wert ist, kannst Du das auf +https://flattr.com/thing/681354/Eressea zum Ausdruck bringen. + +Diese Mail enthält ein Attachment mit Deinem Eressea-Report in +komprimierter Form. Um ihn zu entpacken benötigst Du ein Programm, +das ZIP-Archive öffnen kann, wie z.B. 7-Zip (http://www.7-zip.org/) diff --git a/etc/report-mail.en.txt b/etc/report-mail.en.txt new file mode 100644 index 000000000..58a8e0c19 --- /dev/null +++ b/etc/report-mail.en.txt @@ -0,0 +1,6 @@ +If you feel that getting a report every weekend is worth something to you, +why not flattr Eressea at https://flattr.com/thing/681354/Eressea ? + +This email contains an Attachment with your Eressea report in compressed +form. To open the attachment, you will need a program that can extract +ZIP files, e.g. 7-Zip (http://www.7-zip.org/). diff --git a/etc/report-mail.txt b/etc/report-mail.txt new file mode 100644 index 000000000..4101243e7 --- /dev/null +++ b/etc/report-mail.txt @@ -0,0 +1,14 @@ +Freust Du Dich, dass es diese Woche wieder einen Eressea-Report gibt? +Möchtest Du dazu beitragen, dass das auch nächste Woche wieder passiert? +Eressea ist ein freiwilliges gratis-Angebot, und die Spielleitung bezahlt +seit Jahren die Entwicklung und das Hosting aus eigener Tasche. Wenn Dir +das etwas wert ist, kannst Du das auf +https://flattr.com/thing/681354/Eressea zum Ausdruck bringen. + +Diese Mail enthält ein Attachment mit Deinem Eressea-Report in +komprimierter Form. Um ihn zu entpacken benötigst Du ein Programm, +das ZIP-Archive öffnen kann, wie z.B. 7-Zip (http://www.7-zip.org/) + +This email contains an attachment with your Eressea report in compressed +form. To open the attachment, you will need a program that can extract +ZIP files, e.g. 7-Zip (http://www.7-zip.org/). diff --git a/process/cron/crontab b/process/cron/crontab deleted file mode 100644 index 9d7e155cb..000000000 --- a/process/cron/crontab +++ /dev/null @@ -1,17 +0,0 @@ -# Crontab for Eressea on gruenbaer.kn-bremen.de - -PATH=/home/eressea/bin:/opt/bin:/usr/local/bin:/usr/bin:/bin -ERESSEA=/home/eressea/eressea -ENABLED=yes -PREVIEW=yes -CONFIRM=yes - -# m h dom mon dow command -00 00 * * * $HOME/bin/fetchmail.cron -00 22 * * * $HOME/bin/backup-db.sh - -15 21 * * Sat [ "$ENABLED" = "yes" ] && $ERESSEA/server/bin/run-eressea.cron 3 -25 21 * * Sat [ "$ENABLED" = "yes" ] && $ERESSEA/server/bin/run-eressea.cron 4 -35 21 * * Sat [ "$ENABLED" = "yes" ] && $ERESSEA/server/bin/run-eressea.cron 2 -30 07 * * Sun [ "$PREVIEW" = "yes" ] && $ERESSEA/server/bin/preview.cron -*/5 * * * * [ "$CONFIRM" = "yes" ] && $ERESSEA/server/bin/orders.cron 2 3 4 diff --git a/process/cron/orders.cron b/process/cron/orders.cron index be573fe86..114a870a5 100755 --- a/process/cron/orders.cron +++ b/process/cron/orders.cron @@ -5,6 +5,10 @@ # this here script to make a non-blocking syntax check and reject or # accept the order file. +if [ "yes" != "$CONFIRM" ] ; then + exit +fi + for GAME in $* do if [ "$GAME" == "eressea" ]; then GAME=2 ; fi diff --git a/process/cron/preview.cron b/process/cron/preview.cron index 985ddf40b..71ebd0571 100755 --- a/process/cron/preview.cron +++ b/process/cron/preview.cron @@ -1,6 +1,8 @@ #!/bin/bash -[ -z ${ERESSEA} ] && ERESSEA=~/eressea +[ "$PREVIEW" != "yes" ] && exit +[ -z ${ERESSEA} ] && ERESSEA=$HOME/eressea + branch="develop" if [ -e ${ERESSEA}/build/.preview ]; then branch=`cat ${ERESSEA}/build/.preview` diff --git a/process/cron/run-eressea.cron b/process/cron/run-eressea.cron index 8b506a633..4ea38184c 100755 --- a/process/cron/run-eressea.cron +++ b/process/cron/run-eressea.cron @@ -1,7 +1,11 @@ #!/bin/bash GAME=$1 -BIN=$HOME/bin -export ERESSEA=$HOME/eressea + +[ "$ENABLED" != "yes" ] && exit +[ -z ${ERESSEA} ] && ERESSEA=$HOME/eressea + +export ERESSEA +BIN=$ERESSEA/server/bin TURN=$(cat $ERESSEA/game-$GAME/turn) if [ ! -e $ERESSEA/game-$GAME/data/$TURN.dat ]; then echo "data file $TURN is missing, cannot run turn for game $GAME" @@ -14,6 +18,18 @@ fi mkdir $REPORTS cd $ERESSEA/game-$GAME + +# wait for the queue lock to go away +maxt=5 +to=5 +while [ -e orders.queue.lock ] ; do + echo "waiting for orders to finish processing." + sleep $to + let to=$to+$to + let mast=$maxt-1 + [ $maxt -lt 0 ] && break +done + if [ -d test ]; then touch test/execute.lock fi diff --git a/process/orders.cron b/process/orders.cron deleted file mode 100755 index be573fe86..000000000 --- a/process/orders.cron +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -## this script processes incoming order files. -# files are delivered into an incoming queue by procmail, then cron runs -# this here script to make a non-blocking syntax check and reject or -# accept the order file. - -for GAME in $* -do - if [ "$GAME" == "eressea" ]; then GAME=2 ; fi - if [ "$GAME" == "e3a" ]; then GAME=3 ; fi - if [ -e $HOME/eressea/game-$GAME/orders.queue ] - then - $HOME/bin/orders-process $GAME - fi -done diff --git a/process/run-turn b/process/run-turn index 0c5ee8fd2..c0d0d6a40 100755 --- a/process/run-turn +++ b/process/run-turn @@ -1,3 +1,5 @@ +#!/bin/sh + GAME=$1 TURN=$2 @@ -12,3 +14,4 @@ echo "running turn $TURN, game $GAME" $ERESSEA/server/bin/eressea -v3 -t $TURN run-turn.lua mkdir -p log ln -f eressea.log log/eressea.log.$TURN + diff --git a/process/run-turn.sh b/process/run-turn.sh deleted file mode 100755 index 9cc4e4ffd..000000000 --- a/process/run-turn.sh +++ /dev/null @@ -1,22 +0,0 @@ -GAME=$1 -TURN=$2 - -if [ ! -d $ERESSEA/game-$GAME ] ; then - echo "No such game: $GAME" - exit 1 -fi - -cd $ERESSEA/game-$GAME -if [ -z $TURN ]; then - TURN=$(cat turn) -fi - -echo "running turn $TURN, game $GAME" -if [ -d orders.dir.$TURN ]; then - echo "orders.dir.$TURN already exists" -else - mv orders.dir orders.dir.$TURN - mkdir -p orders.dir -fi -ls -1rt orders.dir.$TURN/turn-* | xargs cat > orders.$TURN -$ERESSEA/bin/eressea -t $TURN run-turn.lua From 9e213d3bcd1c4b66b4aa2444166e223795a7168d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 May 2017 19:05:46 +0200 Subject: [PATCH 217/218] minor optimization and using fraction code --- s/install | 5 ----- src/magic.c | 2 +- src/reports.c | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/s/install b/s/install index 962961063..27cf185af 100755 --- a/s/install +++ b/s/install @@ -16,8 +16,3 @@ BIN_DIR="Debug" cd $ROOT/$BIN_DIR make install - -# install crontab, but only on the eressea server: -# in fact, never do this, because it overwrites hand-edits -#WHOAMI=`whoami`@`hostname` -#[ "eressea@gruenbaer" = "$WHOAMI" ] && crontab $ROOT/process/cron/crontab diff --git a/src/magic.c b/src/magic.c index a20fbc477..81a797e1c 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1107,7 +1107,7 @@ variant magic_resistance(unit * target) const plane *pl = rplane(target->region); if (rc == get_race(RC_HIRNTOETER) && !pl) { - prob.sa[1] *= 2; + prob = frac_mul(prob, frac_make(1, 2)); } assert(target->number > 0); /* Magier haben einen Resistenzbonus vom Magietalent * 5% */ diff --git a/src/reports.c b/src/reports.c index 9af18c1d2..ba0302c6c 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1221,7 +1221,7 @@ static void add_seen_nb(faction *f, region *r, seen_mode mode) { for (d = 0; d != MAXDIRECTIONS; ++d) { region *rn = next[d]; if (rn && rn->seen.modeseen.mode = seen_neighbour; if (first->index>rn->index) first = rn; if (last->indexindex) last = rn; } From b2665097469fcc4519f3e1b734070ccbf85d2e12 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 27 May 2017 20:07:36 +0200 Subject: [PATCH 218/218] Einheitenlimit anheben (3000 und 500) --- conf/e2/config.json | 2 +- conf/e3/config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/e2/config.json b/conf/e2/config.json index 84265b78f..fb231e2eb 100644 --- a/conf/e2/config.json +++ b/conf/e2/config.json @@ -27,7 +27,7 @@ "rules.reserve.twophase": true, "rules.give.max_men": -1, "rules.check_overload": false, - "rules.limit.faction": 2500, + "rules.limit.faction": 3000, "rules.maxskills.magic": 5, "rules.guard.base_stop_prob": 0.30, "rules.guard.skill_stop_prob": 0.05, diff --git a/conf/e3/config.json b/conf/e3/config.json index adbfa3526..bfd1bd0fc 100644 --- a/conf/e3/config.json +++ b/conf/e3/config.json @@ -88,7 +88,7 @@ "rules.economy.herbrot": 0, "rules.region_owner_pay_building": "market harbour lighthouse", "rules.dwarf_castles": true, - "rules.limit.faction": 250, + "rules.limit.faction": 500, "rules.grow.formula": 1, "rules.tactics.formula": 1, "rules.help.mask": "fight guard money give",