From 0738090f281811d72d4a55aafebeae34545b0274 Mon Sep 17 00:00:00 2001 From: Enno Rehling <enno.rehling@gmail.com> Date: Sun, 26 Feb 2017 13:19:47 +0100 Subject: [PATCH 01/42] 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 <kernel/faction.h> #include <kernel/spell.h> #include <kernel/race.h> +#include <kernel/resources.h> #include <kernel/unit.h> #include <kernel/building.h> #include <kernel/item.h> @@ -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 <enno.rehling@gmail.com> Date: Sun, 26 Feb 2017 13:47:22 +0100 Subject: [PATCH 02/42] 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 @@ <construction skill="training" minskill="1"/> <function name="give" value="givehorses"/> </item> - <resourcelimit> - <function name="produce" value="lua_produceresource"/> - <function name="limit" value="lua_limitresource"/> - </resourcelimit> </resource> 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 @@ <?xml version="1.0"?> -<resource name="log"> +<resource name="log" limited="yes"> <item weight="500" score="10"> <construction skill="forestry" minskill="1"/> </item> <resourcelimit> <modifier building="sawmill" type="skill" value="1"/> <modifier building="sawmill" type="material" value="0.5"/> - <function name="produce" value="lua_produceresource"/> - <function name="limit" value="lua_limitresource"/> </resourcelimit> </resource> 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 @@ <?xml version="1.0"?> -<resource name="mallorn"> +<resource name="mallorn" limited="yes"> <item weight="500" score="30"> <construction skill="forestry" minskill="2"/> </item> <resourcelimit> <modifier building="sawmill" type="skill" value="1"/> <modifier building="sawmill" type="material" value="0.5"/> - <function name="produce" value="lua_produceresource"/> - <function name="limit" value="lua_limitresource"/> </resourcelimit> </resource> 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 @@ <item weight="10" score="100"> <construction skill="herbalism" minskill="4"/> </item> - <resourcelimit> - <function name="produce" value="lua_produceresource"/> - <function name="limit" value="lua_limitresource"/> - </resourcelimit> </resource> 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 @@ <item weight="10" score="50"> <construction skill="herbalism" minskill="3"/> </item> - <resourcelimit> - <function name="produce" value="lua_produceresource"/> - <function name="limit" value="lua_limitresource"/> - </resourcelimit> </resource> 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 <enno.rehling@gmail.com> Date: Sun, 26 Feb 2017 13:55:19 +0100 Subject: [PATCH 03/42] 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 <enno.rehling@gmail.com> Date: Sun, 26 Feb 2017 14:00:20 +0100 Subject: [PATCH 04/42] remove pointless <resourcelimit/> 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 @@ <item weight="200" score="200"> <construction skill="mining" minskill="8"/> </item> - <resourcelimit> - <modifier type="require" building="mine"/> - </resourcelimit> + <modifier type="require" building="mine"/> </resource> <resource name="adamantiumaxe"> 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 @@ <?xml version="1.0"?> <resource name="iron" limited="yes" material="yes"> - <item weight="500" score="10"> - <construction skill="mining" minskill="1"/> - </item> - <resourcelimit> + <item weight="500" score="10"> + <construction skill="mining" minskill="1"/> + </item> <modifier building="mine" type="skill" value="1"/> <modifier building="mine" type="material" value="0.5"/> <modifier race="dwarf" type="material" value="0.60"/> - </resourcelimit> </resource> 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 @@ <?xml version="1.0"?> <resource name="laen" limited="yes" material="yes"> - <item weight="200" score="100"> - <construction skill="mining" minskill="7"/> - </item> - <resourcelimit> + <item weight="200" score="100"> + <construction skill="mining" minskill="7"/> + </item> <modifier type="require" building="mine"/> - </resourcelimit> </resource> 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 @@ <?xml version="1.0"?> <resource name="log" limited="yes"> - <item weight="500" score="10"> - <construction skill="forestry" minskill="1"/> - </item> - <resourcelimit> + <item weight="500" score="10"> + <construction skill="forestry" minskill="1"/> + </item> <modifier building="sawmill" type="skill" value="1"/> <modifier building="sawmill" type="material" value="0.5"/> - </resourcelimit> </resource> 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 @@ <?xml version="1.0"?> <resource name="mallorn" limited="yes"> - <item weight="500" score="30"> - <construction skill="forestry" minskill="2"/> - </item> - <resourcelimit> + <item weight="500" score="30"> + <construction skill="forestry" minskill="2"/> + </item> <modifier building="sawmill" type="skill" value="1"/> <modifier building="sawmill" type="material" value="0.5"/> - </resourcelimit> </resource> 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 @@ <?xml version="1.0"?> <resource name="stone" limited="yes" material="yes"> - <item weight="6000" score="10" big="yes"> - <construction skill="quarrying" minskill="1"/> - </item> - <resourcelimit> + <item weight="6000" score="10" big="yes"> + <construction skill="quarrying" minskill="1"/> + </item> <modifier building="quarry" type="skill" value="1"/> <modifier building="quarry" type="material" value="0.5"/> <modifier race="troll" type="material" value="0.75"/> - </resourcelimit> </resource> 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 @@ <?xml version="1.0"?> <resource name="iron" limited="yes" material="yes"> - <item weight="500" score="10"> - <construction skill="mining" minskill="1"/> - </item> - <resourcelimit> + <item weight="500" score="10"> + <construction skill="mining" minskill="1"/> + </item> <modifier building="mine" type="skill" value="1"/> <modifier building="mine" type="material" value="0.5"/> - </resourcelimit> </resource> 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 @@ <?xml version="1.0"?> <resource name="stone" limited="yes" material="yes"> - <item weight="6000" score="10" big="yes"> - <construction skill="quarrying" minskill="1"/> - </item> - <resourcelimit> + <item weight="6000" score="10" big="yes"> + <construction skill="quarrying" minskill="1"/> + </item> <modifier building="quarry" type="skill" value="1"/> <modifier building="quarry" type="material" value="0.5"/> - </resourcelimit> </resource> 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 <enno.rehling@gmail.com> Date: Sun, 26 Feb 2017 15:03:47 +0100 Subject: [PATCH 05/42] 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 <enno.rehling@gmail.com> Date: Sun, 26 Feb 2017 15:30:58 +0100 Subject: [PATCH 06/42] 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 <platform.h> + +#include <kernel/race.h> +#include <kernel/rules.h> +#include <kernel/xmlreader.h> + +#include <races/races.h> + +#include <util/xml.h> + +#include <storage.h> + +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 <platform.h> +#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 <enno.rehling@gmail.com> Date: Sun, 26 Feb 2017 15:33:32 +0100 Subject: [PATCH 07/42] 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 <platform.h> + +#ifdef USE_LIBXML2 +#include <kernel/xmlreader.h> +#include <util/xml.h> +#endif #include <kernel/race.h> #include <kernel/rules.h> -#include <kernel/xmlreader.h> - #include <races/races.h> -#include <util/xml.h> - #include <storage.h> +#include <string.h> + +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 <enno.rehling@gmail.com> Date: Sun, 26 Feb 2017 15:52:58 +0100 Subject: [PATCH 08/42] 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 <enno.rehling@gmail.com> Date: Sun, 26 Feb 2017 18:17:58 +0100 Subject: [PATCH 09/42] 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 <enno@eressea.de> Date: Sun, 26 Feb 2017 19:54:58 +0100 Subject: [PATCH 10/42] 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 @@ <resource name="p7" appearance="vial"> <item weight="0" score="90"> - <function name="useonother" value="usefoolpotion"/> + <function name="use" value="usefoolpotion"/> <potion level="3"/> <construction skill="alchemy" minskill="6"> <requirement type="h2"/> 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 8b69b6d003358e88b278f717bfb2e22d91355b0b Mon Sep 17 00:00:00 2001 From: Enno Rehling <enno@eressea.de> Date: Mon, 27 Feb 2017 04:00:45 +0100 Subject: [PATCH 11/42] 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 <enno@eressea.de> Date: Mon, 27 Feb 2017 04:22:28 +0100 Subject: [PATCH 12/42] 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 @@ </resource> <resource name="xmastree"> - <item weight="0"> - <function name="use" value="lua_useitem"/> - </item> + <item weight="0" use="yes" /> </resource> </resources> 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 @@ </resource> <resource name="snowman"> - <item notlost="yes" weight="1"> - <function name="use" value="lua_useitem"/> - </item> + <item notlost="yes" weight="1" use="yes" /> </resource> <resource name="snowglobe"> - <item notlost="yes" weight="1"> - <function name="use" value="lua_useitem"/> - </item> + <item notlost="yes" weight="1" use="yes" /> </resource> <resource name="ring_of_levitation" appearance="ring"> - <item notlost="yes" weight="0" cursed="true"> - <function name="use" value="lua_useitem"/> - </item> + <item notlost="yes" weight="0" cursed="true" use="yes" /> </resource> <resource name="birthdaycake"> @@ -44,23 +38,17 @@ <!-- ambassador rewards --> <resource name="seashell"> - <item cursed="true" weight="0"> - <function name="use" value="lua_useitem"/> - </item> + <item cursed="true" weight="0" use="yes" /> </resource> <!-- xmas 2005 --> <resource name="stardust" appearance="vial"> - <item weight="0"> - <function name="use" value="lua_useitem"/> - </item> + <item weight="0" use="yes" /> </resource> <!-- xmas 2006 --> <resource name="xmastree"> - <item weight="0"> - <function name="use" value="lua_useitem"/> - </item> + <item weight="0" use="yes" /> </resource> <!-- museum items --> 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 <enno@eressea.de> Date: Mon, 27 Feb 2017 09:48:24 +0100 Subject: [PATCH 13/42] 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 <platform.h> #include "helpers.h" #include "vortex.h" +#include "alchemy.h" #include <util/attrib.h> #include <util/base36.h> @@ -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 <enno@eressea.de> Date: Mon, 27 Feb 2017 11:39:55 +0100 Subject: [PATCH 14/42] 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 @@ <!-- potions --> <resource name="p0" appearance="vial"> - <item weight="0" score="30"> - <function name="use" value="usepotion"/> + <item weight="0" score="30" use="yes"> <potion level="1"/> <construction skill="alchemy" minskill="2"> <requirement type="h4"/> @@ -15,8 +14,7 @@ </resource> <resource name="goliathwater" appearance="vial"> - <item weight="0" score="30"> - <function name="use" value="usepotion"/> + <item weight="0" score="30" use="yes"> <potion level="1"/> <construction skill="alchemy" minskill="2"> <requirement type="h6"/> @@ -26,8 +24,7 @@ </resource> <resource name="truthpotion" appearance="vial"> - <item weight="0" score="30"> - <function name="use" value="usepotion"/> + <item weight="0" score="30" use="yes"> <potion level="1"/> <construction skill="alchemy" minskill="2"> <requirement type="h0"/> @@ -37,8 +34,7 @@ </resource> <resource name="p2" appearance="vial"> - <item weight="0" score="30"> - <function name="use" value="usepotion"/> + <item weight="0" score="30" use="yes"> <potion level="1"/> <construction skill="alchemy" minskill="2"> <requirement type="h5"/> @@ -48,8 +44,7 @@ </resource> <resource name="p3" appearance="vial"> - <item weight="0" score="60"> - <function name="use" value="usepotion"/> + <item weight="0" score="60" use="yes"> <potion level="2"/> <construction skill="alchemy" minskill="4"> <requirement type="h14"/> @@ -61,8 +56,7 @@ <resource name="ointment" appearance="vial"> <!-- Wundsalbe --> - <item weight="0" score="60"> - <function name="use" value="usehealingpotion"/> + <item weight="0" score="60" use="yes"> <potion level="2"/> <construction skill="alchemy" minskill="4"> <requirement type="h19"/> @@ -74,8 +68,7 @@ <resource name="peasantblood" appearance="vial"> <!-- Bauernblut --> - <item weight="0" score="60"> - <function name="use" value="usebloodpotion"/> + <item weight="0" score="60" use="yes"> <potion level="2"/> <construction skill="alchemy" minskill="4"> <requirement type="h17"/> @@ -87,8 +80,7 @@ </resource> <resource name="p6" appearance="vial"> - <item weight="0" score="90"> - <function name="use" value="usepotion"/> + <item weight="0" score="90" use="yes"> <potion level="3"/> <construction skill="alchemy" minskill="6"> <requirement type="h9"/> @@ -100,8 +92,7 @@ </resource> <resource name="p7" appearance="vial"> - <item weight="0" score="90"> - <function name="use" value="usefoolpotion"/> + <item weight="0" score="90" use="yes"> <potion level="3"/> <construction skill="alchemy" minskill="6"> <requirement type="h2"/> @@ -113,8 +104,7 @@ </resource> <resource name="nestwarmth" appearance="vial"> - <item weight="0" score="90"> - <function name="use" value="usewarmthpotion"/> + <item weight="0" score="90" use="yes"> <potion level="3"/> <construction skill="alchemy" minskill="6"> <requirement type="h18"/> @@ -126,8 +116,7 @@ </resource> <resource name="p9" appearance="vial"> - <item weight="0" score="90"> - <function name="use" value="usepotion"/> + <item weight="0" score="90" use="yes"> <potion level="3"/> <construction skill="alchemy" minskill="6"> <requirement type="h4"/> @@ -139,8 +128,7 @@ </resource> <resource name="p10" appearance="vial"> - <item weight="0" score="90"> - <function name="use" value="usepotion"/> + <item weight="0" score="90" use="yes"> <potion level="3"/> <construction skill="alchemy" minskill="6"> <requirement type="h19"/> @@ -152,8 +140,7 @@ </resource> <resource name="p11" appearance="vial"> - <item weight="0" score="120"> - <function name="use" value="usepotion"/> + <item weight="0" score="120" use="yes"> <potion level="4"/> <construction skill="alchemy" minskill="8"> <requirement type="h14"/> @@ -166,8 +153,7 @@ </resource> <resource name="p13" appearance="vial"> - <item weight="0" score="120"> - <function name="use" value="usepotion"/> + <item weight="0" score="120" use="yes"> <potion level="4"/> <construction skill="alchemy" minskill="8"> <requirement type="h5"/> @@ -181,8 +167,7 @@ </resource> <resource name="p14" appearance="vial"> - <item weight="0" score="120"> - <function name="use" value="usepotion"/> + <item weight="0" score="120" use="yes"> <potion level="4"/> <construction skill="alchemy" minskill="8"> <requirement type="h6"/> 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 @@ <resource name="ointment" appearance="vial"> <!-- Wundsalbe --> - <item weight="0" score="60"> - <function name="use" value="usehealingpotion"/> + <item weight="0" score="60" use="yes"> <potion level="2"/> </item> </resource> <resource name="p13" appearance="vial"> <!-- Elixier der Macht --> - <item weight="0" score="120"> - <function name="use" value="usepotion"/> + <item weight="0" score="120" use="yes"> <potion level="4"/> </item> </resource> <resource name="p3" appearance="vial"> <!-- Schaffenstrunk --> - <item weight="0" score="60"> - <function name="use" value="usepotion"/> + <item weight="0" score="60" use ="yes"> <potion level="2"/> </item> </resource> <resource name="p14" appearance="vial"> <!-- Heiltrank --> - <item weight="0" score="120"> - <function name="use" value="usepotion"/> + <item weight="0" score="120" use="yes"> <potion level="4"/> </item> </resource> <resource name="p0" appearance="vial"> <!-- Siebenmeilentee --> - <item weight="0" score="30"> - <function name="use" value="usepotion"/> + <item weight="0" score="30" use="yes"> <potion level="1"/> </item> </resource> <resource name="p2" appearance="vial"> <!-- Wasser des Lebens --> - <item weight="0" score="30"> - <function name="use" value="usepotion_delayed"/> + <item weight="0" score="30" use="yes"> <potion level="1"/> </item> </resource> <resource name="peasantblood" appearance="vial"> <!-- Bauernblut --> - <item weight="0" score="60"> - <function name="use" value="usebloodpotion"/> + <item weight="0" score="60" use="yes"> <potion level="2"/> </item> </resource> <resource name="p9" appearance="vial"> <!-- Pferdeglück --> - <item weight="0" score="90"> - <function name="use" value="usepotion"/> + <item weight="0" score="90" use="yes"> <potion level="3"/> </item> </resource> 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 <enno@eressea.de> Date: Mon, 27 Feb 2017 14:01:41 +0100 Subject: [PATCH 15/42] 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 @@ </resource> <resource name="aoc" appearance="amulet"> - <item weight="100"> - <function name="use" value="use_birthdayamulet"/> - </item> + <item weight="100" use="yes" /> </resource> <resource name="dreameye"> 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 <kernel/ship.h> #include <kernel/plane.h> #include <kernel/terrain.h> +#include <kernel/messages.h> #include <modules/autoseed.h> #include <attributes/key.h> #include <attributes/racename.h> @@ -46,6 +47,23 @@ without prior permission by the authors of Eressea. #include <string.h> #include <stdlib.h> +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 <enno@eressea.de> Date: Mon, 27 Feb 2017 14:10:12 +0100 Subject: [PATCH 16/42] 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 <platform.h> #include "items.h" +#include "alchemy.h" #include "study.h" #include "economy.h" #include "move.h" @@ -14,6 +15,7 @@ #include <kernel/order.h> #include <kernel/plane.h> #include <kernel/pool.h> +#include <kernel/race.h> #include <kernel/region.h> #include <kernel/ship.h> #include <kernel/spell.h> @@ -21,9 +23,15 @@ #include <items/demonseye.h> +/* triggers includes */ +#include <triggers/changerace.h> +#include <triggers/timeout.h> + #include <util/attrib.h> +#include <util/event.h> #include <util/parser.h> #include <util/rand.h> +#include <util/rng.h> #include <assert.h> #include <limits.h> @@ -125,15 +133,15 @@ struct order *ord) UNUSED_ARG(ord); assert(sp); - /* Reduziert die St�rke jedes Spruchs um effect */ + /* Reduziert die St�rke jedes Spruchs um effect */ effect = 5; - /* H�lt Spr�che 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 aufl�sen */ + /* Regionszauber aufl�sen */ while (*ap && force > 0) { curse *c; attrib *a = *ap; @@ -145,7 +153,7 @@ struct order *ord) } c = (curse *)a->data.v; - /* Immunit�t pr�fen */ + /* 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 <triggers/changerace.h> -#include <triggers/timeout.h> - /* util includes */ #include <util/attrib.h> #include <util/base36.h> -#include <critbit.h> -#include <util/event.h> #include <util/functions.h> #include <util/goodies.h> #include <util/log.h> #include <util/language.h> #include <util/message.h> -#include <util/umlaut.h> #include <util/rng.h> +#include <util/umlaut.h> +#include <critbit.h> #include <storage.h> /* 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 <attributes/fleechance.h> 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 <enno@eressea.de> Date: Mon, 27 Feb 2017 14:17:38 +0100 Subject: [PATCH 17/42] 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 <enno@eressea.de> Date: Mon, 27 Feb 2017 14:19:25 +0100 Subject: [PATCH 18/42] 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 <enno@eressea.de> Date: Mon, 27 Feb 2017 15:14:52 +0100 Subject: [PATCH 19/42] 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 @@ <!-- items --> <resource name="antimagic" appearance="amulet"> - <item weight="0" score="2000"> - <function name="use" value="use_antimagiccrystal"/> - </item> + <item weight="0" score="2000" use="yes" /> </resource> <resource name="catapultammo"> 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 <util/attrib.h> #include <util/event.h> +#include <util/log.h> #include <util/parser.h> #include <util/rand.h> #include <util/rng.h> @@ -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 <enno.rehling@gmail.com> Date: Mon, 27 Feb 2017 18:21:41 +0100 Subject: [PATCH 20/42] =?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 @@ </resource> <!-- XE items --> + <resource name="studypotion" appearance="vial"> + <!-- gives user one free learning attempt --> + <item weight="0" use="yes" /> + </resource> + <resource name="skillpotion" appearance="vial"> <!-- gives user one free learning attempt --> <item weight="0"> 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 @@ <item notlost="yes" cursed="true" weight="0"/> </resource> - <resource name="ao_daemon"> - <!-- summons igjarjuk --> - <item weight="0" score="6000" notlost="true" cursed="true"> - <function name="use" value="useigjarjuk"/> - <function name="give" value="giveigjarjuk"/> - </item> - </resource> - - <resource name="griphonwing"> - <!-- this lets you leave the arena --> - <item weight="0" score="6000" notlost="true" cursed="true"> - <function name="use" value="leave_arena"/> - <function name="give" value="giveigjarjuk"/> - </item> - </resource> - <resource name="eyeofdragon"> <!-- the arena gate, for one-time entry --> - <item weight="0" score="0"> - <function name="use" value="enter_arena"/> - </item> + <item weight="0" score="0"/> </resource> <resource name="jadee_ring" appearance="ring"> 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 @@ <text locale="de">Eine Geburtstagstorte mit 10 Kerzen. Herzlichen Glückwunsch, Eressea!</text> <text locale="en">A birthday cake with 10 candles. Happy Birthday, Eressea!</text> </string> - <string name="griphonwing"> - <text locale="de">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.</text> - </string> - <string name="ao_daemon"> - <text locale="de">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...</text> - </string> <string name="cookie"> <text locale="de">Kleines trockenes Dauergebäck, m od. s; - u. -es, - u. -e</text> </string> @@ -374,29 +362,6 @@ </string> <!-- art rewards end --> - <!-- igjarjuk queste begin --> - <string name="ao_daemon"> - <text locale="de">Auge des Dämon</text> - <text locale="en">eye of the demon</text> - <text locale="fr">oeil du démon</text> - </string> - <string name="ao_daemon_p"> - <text locale="de">Augen des Dämon</text> - <text locale="en">eyes of the demon</text> - <text locale="fr">oeil du démon</text> - </string> - <string name="griphonwing"> - <text locale="de">Schwinge des Greifen</text> - <text locale="en">wing of the gryphon</text> - <text locale="fr">aile du griffon</text> - </string> - <string name="griphonwing_p"> - <text locale="de">Schwingen des Greifen</text> - <text locale="en">wings of the gryphon</text> - <text locale="fr">ailes du griffon</text> - </string> - <!-- igjarjuk queste end --> - <string name="rm_adamantium"> <text locale="de">Adamantium</text> <text locale="en">adamantium</text> 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 <modules/museum.h> #endif -#if ARENA_MODULE -#include <modules/arena.h> -#endif #include <triggers/triggers.h> #include <util/language.h> #include <util/functions.h> @@ -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 <modules/museum.h> #endif -#if ARENA_MODULE -#include <modules/arena.h> -#endif #include <modules/autoseed.h> #include <kernel/building.h> 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 <enno@eressea.de> -Katja Zedel <katze@felidae.kn-bremen.de -Christian Schlittchen <corwin@amber.kn-bremen.de> - -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 <platform.h> -#include <kernel/config.h> - -#if ARENA_MODULE -#include "arena.h" - -/* modules include */ -#include "score.h" - -/* items include */ -#include <items/demonseye.h> - -/* kernel includes */ -#include <kernel/building.h> -#include <kernel/faction.h> -#include <kernel/item.h> -#include <kernel/messages.h> -#include <kernel/order.h> -#include <kernel/plane.h> -#include <kernel/pool.h> -#include <kernel/race.h> -#include <kernel/region.h> -#include <kernel/terrain.h> -#include <kernel/terrainid.h> -#include <kernel/unit.h> - -#include <move.h> - -/* util include */ -#include <util/attrib.h> -#include <util/base36.h> -#include <util/event.h> -#include <util/gamedata.h> -#include <util/functions.h> -#include <util/strings.h> -#include <util/lists.h> -#include <util/log.h> -#include <util/resolve.h> -#include <util/rng.h> - -#include <storage.h> - -/* libc include */ -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -/* 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 <enno@eressea.de> -Katja Zedel <katze@felidae.kn-bremen.de -Christian Schlittchen <corwin@amber.kn-bremen.de> - -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 <enno.rehling@gmail.com> Date: Mon, 27 Feb 2017 18:50:48 +0100 Subject: [PATCH 21/42] 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 @@ <item weight="0" score="6000"/> </resource> - <resource name="aoc" appearance="amulet"> - <item weight="100" use="yes" /> - </resource> - <resource name="dreameye"> - <item weight="100"> - <function name="use" value="use_tacticcrystal"/> - </item> + <item weight="100" use="yes" /> </resource> <resource name="pegasus"> @@ -105,16 +99,12 @@ <resource name="skillpotion" appearance="vial"> <!-- gives user one free learning attempt --> - <item weight="0"> - <function name="use" value="use_skillpotion"/> - </item> + <item weight="0" use="yes" /> </resource> <resource name="manacrystal" appearance="amulet"> <!-- gives user free aura --> - <item weight="0"> - <function name="use" value="use_manacrystal"/> - </item> + <item weight="0" use="yes" /> </resource> <!-- xmas items --> 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 @@ <string name="aots_p"> <text locale="de">Amulette des wahren Sehens</text> </string> - <string name="aoc"> - <text locale="de">Katzenamulett</text> - </string> - <string name="aoc_p"> - <text locale="de">Katzenamulette</text> - </string> <string name="roi"> <text locale="de">Ring der Unsichtbarkeit</text> </string> 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 @@ <string name="ao_chastity_p"> <text locale="en">amulets of chastity</text> </string> - <string name="aoc"> - <text locale="en">amulet of the kitten</text> - </string> - <string name="aoc_p"> - <text locale="en">amulets of the kitten</text> - </string> <string name="aod"> <text locale="en">amulet of darkness</text> </string> 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 @@ <string name="ao_chastity_p"> <text locale="fr">amulettes de chasteté</text> </string> - <string name="aoc"> - <text locale="fr">amulette du chaton</text> - </string> - <string name="aoc_p"> - <text locale="fr">amulettes du chaton</text> - </string> <string name="aod"> <text locale="fr">amulette de ténčbres</text> </string> 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 @@ <item notlost="yes" cursed="true" weight="0"/> </resource> + <resource name="aoc" appearance="amulet"> + <item weight="100" use="yes" /> + </resource> + <resource name="eyeofdragon"> <!-- the arena gate, for one-time entry --> <item weight="0" score="0"/> 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 @@ <text locale="de">Adamantiumrüstungen</text> <text locale="en">adamantium plates</text> </string> - + <string name="aoc"> + <text locale="de">Katzenamulett</text> + <text locale="en">amulet of the kitten</text> + <text locale="fr">amulette du chaton</text> + </string> + <string name="aoc_p"> + <text locale="en">amulets of the kitten</text> + <text locale="de">Katzenamulette</text> + <text locale="fr">amulettes du chaton</text> + </string> </strings> 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 <kernel/spell.h> #include <kernel/unit.h> -#include <items/demonseye.h> - /* triggers includes */ #include <triggers/changerace.h> #include <triggers/timeout.h> @@ -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 <enno@eressea.de> -Katja Zedel <katze@felidae.kn-bremen.de -Christian Schlittchen <corwin@amber.kn-bremen.de> - -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 <platform.h> -#include "demonseye.h" - -/* kernel includes */ -#include <kernel/faction.h> -#include <kernel/item.h> -#include <kernel/messages.h> -#include <kernel/plane.h> -#include <kernel/region.h> -#include <kernel/unit.h> - -/* util includes */ -#include <util/functions.h> - -/* libc includes */ -#include <assert.h> - -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 <enno@eressea.de> -Katja Zedel <katze@felidae.kn-bremen.de -Christian Schlittchen <corwin@amber.kn-bremen.de> - -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 <kernel/command.h> /* misc includes */ -#include <items/demonseye.h> #include <attributes/key.h> #include <triggers/gate.h> From 9d09574d5e10c8ec30e6ae8c564030e872ba0e20 Mon Sep 17 00:00:00 2001 From: Enno Rehling <enno.rehling@gmail.com> Date: Mon, 27 Feb 2017 19:35:14 +0100 Subject: [PATCH 22/42] 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 @@ <!-- xmas items --> <resource name="mistletoe"> <!-- Sets the chance of escape in a fight to 100 percent --> - <item notlost="yes" weight="0"> - <function name="use" value="usemistletoe"/> - </item> + <item notlost="yes" weight="0" use="yes" /> </resource> <resource name="speedsail"> - <item weight="0"> - <function name="use" value="use_speedsail"/> - </item> + <item weight="0" use="yes" /> </resource> <!-- items --> <resource name="antimagic" appearance="amulet"> - <item weight="0" score="2000" use="yes" /> + <item weight="0" score="2000" use="yes" /> </resource> <resource name="catapultammo"> 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 @@ <resource name="aurapotion50"> <function name="change" value="changeitem"/> - <item weight="0"> - <function name="use" value="use_aurapotion50"/> - </item> + <item weight="0" use="yes" /> </resource> <resource name="bagpipeoffear"> <function name="change" value="changeitem"/> - <item weight="0"> - <function name="use" value="use_bagpipeoffear"/> - </item> + <item weight="0" use="yes"/> </resource> </resources> 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 <kernel/building.h> #include <kernel/config.h> +#include <kernel/curse.h> #include <kernel/faction.h> #include <kernel/group.h> #include <kernel/item.h> @@ -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 <kernel/spell.h> #include <kernel/unit.h> +#include <attributes/fleechance.h> + /* triggers includes */ #include <triggers/changerace.h> #include <triggers/timeout.h> @@ -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 <attributes/fleechance.h> -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 <enno.rehling@gmail.com> Date: Mon, 27 Feb 2017 20:16:50 +0100 Subject: [PATCH 23/42] 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 <storage.h> + 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 <kernel/config.h> +#include <kernel/curse.h> #include <kernel/region.h> #include <kernel/resources.h> #include <kernel/unit.h> @@ -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 <kernel/curse.h> #include <kernel/region.h> #include <kernel/unit.h> #include <kernel/ship.h> #include <kernel/build.h> +#include <util/attrib.h> #include <util/language.h> #include <util/log.h> @@ -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 <enno.rehling@gmail.com> Date: Mon, 27 Feb 2017 20:26:48 +0100 Subject: [PATCH 24/42] 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 <enno.rehling@gmail.com> Date: Mon, 27 Feb 2017 20:41:05 +0100 Subject: [PATCH 25/42] 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 @@ <!-- museum items --> <resource name="questkey1" appearance="key"> <!-- Key for an old quest. placeholder item --> - <item notlost="yes" weight="0" > - <function name="use" value="use_museumkey"/> - </item> + <item notlost="yes" weight="0" use="yes" /> </resource> <resource name="questkey2" appearance="key"> <!-- Key for an old quest. placeholder item --> - <item notlost="yes" weight="0" > - <function name="use" value="use_museumkey"/> - </item> + <item notlost="yes" weight="0" use="yes" /> </resource> <resource name="museumexitticket"> <!-- you get your stuff back when leaving the museum --> - <item notlost="yes" weight="0"> - <function name="use" value="use_museumexitticket"/> - </item> + <item notlost="yes" weight="0" use="yes" /> </resource> <resource name="museumticket"> <!-- you get your stuff back when leaving the museum --> - <item weight="0"> - <function name="use" value="use_museumticket"/> - </item> + <item weight="0" use="yes" /> </resource> <!-- gimmicks, etc. --> 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 <enno.rehling@gmail.com> Date: Mon, 27 Feb 2017 21:00:15 +0100 Subject: [PATCH 26/42] 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 <enno.rehling@gmail.com> Date: Tue, 28 Feb 2017 03:48:41 +0100 Subject: [PATCH 27/42] 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 @@ <?xml version="1.0" ?> -<race name="goblin" magres="-5" maxaura="1.0" regaura="1.0" +<race name="goblin" magres="-5" maxaura="1.0" 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" diff --git a/res/races/goblin-3.xml b/res/races/goblin-3.xml index 3fd594939..a65d4c99a 100644 --- a/res/races/goblin-3.xml +++ b/res/races/goblin-3.xml @@ -1,5 +1,5 @@ <?xml version="1.0" ?> -<race name="goblin" magres="-5" maxaura="1.0" regaura="1.0" +<race name="goblin" magres="-5" maxaura="1.0" 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" diff --git a/res/races/goblin.xml b/res/races/goblin.xml index a05d127e3..84d2c5079 100644 --- a/res/races/goblin.xml +++ b/res/races/goblin.xml @@ -1,6 +1,6 @@ <?xml version="1.0" ?> <race name="goblin" magres="-5" maxaura="1.000000" -regaura="1.000000" recruitcost="40" maintenance="10" weight="600" +recruitcost="40" maintenance="10" weight="600" capacity="440" speed="1.000000" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes" From 9871d6f23f79711d7777022ba1f2c83aa5cea6ef Mon Sep 17 00:00:00 2001 From: Enno Rehling <enno.rehling@gmail.com> Date: Tue, 28 Feb 2017 04:03:36 +0100 Subject: [PATCH 28/42] 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 @@ -<?xml version="1.0" ?> -<races xmlns:xi="http://www.w3.org/2001/XInclude"> - <xi:include href="races/aquarian.xml"/> - <xi:include href="races/cat.xml"/> - <xi:include href="races/demon.xml"/> - <xi:include href="races/dwarf.xml"/> - <xi:include href="races/elf.xml"/> - <xi:include href="races/goblin.xml"/> - <xi:include href="races/halfling.xml"/> - <xi:include href="races/human.xml"/> - <xi:include href="races/insect.xml"/> - <xi:include href="races/orc.xml"/> - <xi:include href="races/troll.xml"/> -</races> 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 @@ -<?xml version="1.0" ?> -<race name="goblin" magres="-5" maxaura="1.0" -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"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <param name="hunger.damage" value="1d8+7"/> - <param name="other_race" value="demon"/> - <param name="recruit_multi" value="0.5"/> - <skill name="building" modifier="1"/> - <skill name="cartmaking" modifier="-1"/> - <skill name="catapult" modifier="1"/> - <skill name="magic" modifier="-99"/> - <skill name="mining" modifier="1"/> - <skill name="roadwork" modifier="-2"/> - <skill name="sailing" modifier="-2"/> - <skill name="shipcraft" modifier="-2"/> - <skill name="tactics" modifier="-2"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="rat" default="yes"/> - <familiar race="imp"/> -</race> From 5a01eae522bf025b4a681aeb13033f2d4a0b8cbe Mon Sep 17 00:00:00 2001 From: Enno Rehling <enno@eressea.de> Date: Tue, 28 Feb 2017 10:48:27 +0100 Subject: [PATCH 29/42] 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 <assert.h> #include <ctype.h> +#include <limits.h> #include <math.h> #include <stdio.h> #include <string.h> @@ -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 <platform.h> #include <kernel/config.h> #include "race.h" -#include <CuTest.h> +#include "item.h" + #include <tests.h> +#include <CuTest.h> #include <stdlib.h> +#include <limits.h> #include <assert.h> 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 <enno@eressea.de> Date: Tue, 28 Feb 2017 10:58:09 +0100 Subject: [PATCH 30/42] 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 <enno@eressea.de> Date: Tue, 28 Feb 2017 11:07:32 +0100 Subject: [PATCH 31/42] 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 @@ <?xml version="1.0"?> <resource name="towershield"> - <item weight="200" score="60"> + <item weight="200" score="60" allow="1"> <function name="canuse" value="lua_canuse_item"/> <construction skill="armorer" minskill="4"> <modifier function="mod_dwarves_only"/> 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 @@ <familiar race="ghost"/> </race> - <race name="halfling" defensemodifier="1" magres="5" maxaura="1.0" 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"> + <race name="halfling" defensemodifier="1" magres="5" maxaura="1.0" + 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"> <ai splitsize="10000" moverandom="yes" learn="yes"/> <param name="other_race" value="dwarf"/> <param name="luxury_trade" value="600"/> @@ -116,7 +120,11 @@ <familiar race="ghost"/> </race> - <race name="elf" magres="10" maxaura="1.0" regaura="1.1" 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"> + <race name="elf" magres="10" maxaura="1.0" regaura="1.1" + 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"> <ai splitsize="10000" moverandom="yes" learn="yes"/> <skill name="armorer" modifier="-1"/> <skill name="bow" modifier="2"/> @@ -156,7 +164,11 @@ <familiar race="rat"/> </race> - <race name="dwarf" magres="5" maxaura="1.0" regaura="0.9" 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"> + <race name="dwarf" magres="5" maxaura="1.0" regaura="0.9" + 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"> <ai splitsize="10000" moverandom="yes" learn="yes"/> <skill name="armorer" modifier="2"/> <skill name="bow" modifier="-1"/> 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"> <ai splitsize="10000" moverandom="yes" learn="yes"/> <param name="hunger.damage" value="1d8+7"/> <param name="other_race" value="demon"/> 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 <enno@eressea.de> Date: Fri, 3 Mar 2017 09:56:27 +0100 Subject: [PATCH 32/42] 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 @@ <?xml version="1.0"?> <resource name="greatbow"> - <item weight="100"> + <item weight="100" allow="elf"> <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="5"> <modifier function="mod_elves_only"/> 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 @@ <?xml version="1.0"?> <resource name="rep_crossbow"> - <item weight="100"> + <item weight="100" allow="dwarf halfling"> <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="5"> <modifier function="mod_dwarves_only"/> 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 @@ <?xml version="1.0"?> <resource name="plate"> - <item weight="400" score="150"> + <item weight="400" score="150" deny="goblin"> <function name="canuse" value="lua_canuse_item"/> <construction skill="armorer" minskill="4"> <requirement type="iron" quantity="4"/> 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 @@ <?xml version="1.0"?> <resource name="scale"> - <item weight="300" score="150"> + <item weight="300" score="150" allow="dwarf halfling"> <function name="canuse" value="lua_canuse_item"/> <construction skill="armorer" minskill="5"> <modifier function="mod_dwarves_only"/> 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 @@ <?xml version="1.0"?> <resource name="towershield"> - <item weight="200" score="60" allow="1"> + <item weight="200" score="60" allow="dwarf"> <function name="canuse" value="lua_canuse_item"/> <construction skill="armorer" minskill="4"> <modifier function="mod_dwarves_only"/> 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"> <ai splitsize="10000" moverandom="yes" learn="yes"/> <param name="other_race" value="dwarf"/> <param name="luxury_trade" value="600"/> @@ -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" > <ai splitsize="10000" moverandom="yes" learn="yes"/> <skill name="armorer" modifier="-1"/> <skill name="bow" modifier="2"/> @@ -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"> <ai splitsize="10000" moverandom="yes" learn="yes"/> <skill name="armorer" modifier="2"/> <skill name="bow" modifier="-1"/> 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 @@ <?xml version="1.0"?> <resources xmlns:xi="http://www.w3.org/2001/XInclude"> - <xi:include href="config://core/weapons/axe.xml"/> <xi:include href="config://core/weapons/bow.xml"/> <xi:include href="config://core/weapons/catapult.xml"/> - <xi:include href="config://core/weapons/lance.xml"/> <xi:include href="config://core/weapons/mallornbow.xml"/> <xi:include href="config://core/weapons/mallornspear.xml"/> <xi:include href="config://core/weapons/rep_crossbow.xml"/> @@ -13,6 +11,8 @@ <xi:include href="config://core/weapons/spear.xml"/> <xi:include href="config://core/weapons/sword.xml"/> <xi:include href="config://core/weapons/firesword.xml"/> + <xi:include href="config://game/weapons/lance.xml"/> + <xi:include href="config://game/weapons/axe.xml"/> <xi:include href="config://game/weapons/crossbow.xml"/> <xi:include href="config://game/weapons/greatbow.xml"/> <xi:include href="config://game/weapons/greatsword.xml"/> 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 --> <resource name="greatbow"> - <item weight="100"> + <item weight="100" allow="elf"> <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="5"> <modifier function="mod_elves_only"/> 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 --> <resource name="halberd"> - <item weight="200"> + <item weight="200" deny="goblin"> <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="3"> <requirement type="log" quantity="2"/> 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 @@ <?xml version="1.0"?> <resource name="mallornlance"> - <item weight="100"> + <item weight="100" deny="goblin"> <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="5"> <requirement type="mallorn" quantity="2"/> 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 --> <resource name="rustyhalberd"> - <item weight="200" score="20"> + <item weight="200" score="20" deny="goblin"> <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="3"> <requirement type="iron" quantity="1"/> 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"> <ai splitsize="10000" moverandom="yes" learn="yes"/> <param name="hunger.damage" value="1d8+7"/> <param name="other_race" value="demon"/> 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 <enno@eressea.de> Date: Fri, 3 Mar 2017 10:35:34 +0100 Subject: [PATCH 33/42] 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 <enno.rehling@gmail.com> Date: Fri, 3 Mar 2017 16:38:28 +0100 Subject: [PATCH 34/42] 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 @@ +<?xml version="1.0"?> +<resource name="axe"> + <item weight="200" deny="goblin"> + <function name="canuse" value="lua_canuse_item"/> + <construction skill="weaponsmithing" minskill="3"> + <requirement type="log" quantity="1"/> + <requirement type="iron" quantity="1"/> + </construction> + <weapon cut="true" skill="melee" offmod="1" defmod="-2"> + <damage type="rider" value="2d6+4"/> + <damage type="footman" value="2d6+4"/> + </weapon> + </item> +</resource> 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 @@ +<?xml version="1.0"?> +<resource name="lance"> + <item weight="200" deny="goblin"> + <function name="canuse" value="lua_canuse_item"/> + <construction skill="weaponsmithing" minskill="2"> + <requirement type="log" quantity="2"/> + </construction> + <weapon pierce="true" skill="polearm" offmod="0" defmod="-2"> + <damage type="footman" value="1d5"/> + <damage type="rider" value="2d6+5"/> + </weapon> + </item> +</resource> From 259d7d9e804f6169c85250688a801a82ddae9654 Mon Sep 17 00:00:00 2001 From: Enno Rehling <enno.rehling@gmail.com> Date: Fri, 3 Mar 2017 16:50:43 +0100 Subject: [PATCH 35/42] 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 <enno.rehling@gmail.com> Date: Fri, 3 Mar 2017 17:27:51 +0100 Subject: [PATCH 36/42] 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 <enno.rehling@gmail.com> Date: Fri, 3 Mar 2017 18:02:43 +0100 Subject: [PATCH 37/42] 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 <enno.rehling@gmail.com> Date: Fri, 3 Mar 2017 18:53:39 +0100 Subject: [PATCH 38/42] 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 <enno.rehling@gmail.com> Date: Fri, 3 Mar 2017 19:17:20 +0100 Subject: [PATCH 39/42] 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 @@ </resource> <resource name="elvenhorse"> - <item weight="5000" notlost="yes" big="yes" score="6000" capacity="7000" animal="yes"> - <function name="give" value="givehorses"/> - </item> + <item weight="5000" notlost="yes" big="yes" score="6000" capacity="7000" animal="yes"/> </resource> <resource name="dolphin"> 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 @@ <?xml version="1.0"?> <resource name="horse" limited="yes"> <item big="yes" weight="5000" score="10" capacity="7000" animal="yes"> - <construction skill="training" minskill="1"/> - <function name="give" value="givehorses"/> + <construction skill="training" minskill="1" /> </item> </resource> 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 @@ </resource> <resource name="charger"> - <item big="yes" weight="5000" score="10" capacity="7000" animal="yes"> + <item big="yes" weight="5000" score="20" capacity="7000" animal="yes"> <construction skill="training" minskill="4"> <requirement type="money" quantity="200"/> <requirement type="iron" quantity="1"/> <requirement type="horse" quantity="1"/> </construction> - <function name="give" value="givehorses"/> </item> </resource> 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 <kernel/ally.h> +#include <kernel/build.h> #include <kernel/curse.h> #include <kernel/faction.h> #include <kernel/item.h> @@ -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 <enno.rehling@gmail.com> Date: Fri, 3 Mar 2017 19:19:33 +0100 Subject: [PATCH 40/42] 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 <enno.rehling@gmail.com> Date: Sat, 4 Mar 2017 17:27:13 +0100 Subject: [PATCH 41/42] 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 @@ <?xml version="1.0"?> <resource name="plate"> <item weight="400" score="150"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="armorer" minskill="4"> <requirement type="iron" quantity="5"/> </construction> 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 @@ <?xml version="1.0"?> <resource name="axe"> <item weight="200"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="3"> <requirement type="log" quantity="1"/> <requirement type="iron" quantity="1"/> 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 @@ <?xml version="1.0"?> <resource name="greatbow"> - <item weight="100" allow="elf"> - <function name="canuse" value="lua_canuse_item"/> + <item weight="100"> <construction skill="weaponsmithing" minskill="5"> <modifier function="mod_elves_only"/> <requirement type="mallorn" quantity="2"/> 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 @@ <?xml version="1.0"?> <resource name="greatsword"> <item weight="200" score="30"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="4"> <requirement type="iron" quantity="2"/> </construction> 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 @@ <?xml version="1.0"?> <resource name="halberd"> <item weight="200"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="3"> <requirement type="log" quantity="2"/> <requirement type="iron" quantity="1"/> 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 @@ <?xml version="1.0"?> <resource name="lance"> <item weight="200"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="2"> <requirement type="log" quantity="2"/> </construction> 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 @@ <?xml version="1.0"?> <resource name="mallornlance"> <item weight="100"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="5"> <requirement type="mallorn" quantity="2"/> </construction> 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 @@ -<?xml version="1.0"?> -<resource name="rep_crossbow"> - <item weight="100" allow="dwarf halfling"> - <function name="canuse" value="lua_canuse_item"/> - <construction skill="weaponsmithing" minskill="5"> - <modifier function="mod_dwarves_only"/> - <requirement type="log" quantity="1"/> - <requirement type="iron" quantity="1"/> - </construction> - <weapon armorpiercing="true" pierce="true" missile="true" skill="crossbow" offmod="0" defmod="0" reload="1"> - <damage type="rider" value="3d4+5"/> - <damage type="footman" value="3d4+5"/> - <modifier type="missile_target" value="0"/> - </weapon> - </item> -</resource> 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 @@ <?xml version="1.0"?> <resource name="rustyaxe"> <item weight="200"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="3"> <requirement type="log" quantity="1"/> <requirement type="iron" quantity="1"/> 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 @@ <?xml version="1.0"?> <resource name="rustyhalberd"> <item weight="200" score="20"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="3"> <requirement type="iron" quantity="1"/> <requirement type="log" quantity="1"/> 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 @@ <?xml version="1.0"?> <resource name="plate"> <item weight="400" score="150" deny="goblin"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="armorer" minskill="4"> <requirement type="iron" quantity="4"/> </construction> 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 @@ <?xml version="1.0"?> <resource name="scale"> <item weight="300" score="150" allow="dwarf halfling"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="armorer" minskill="5"> <modifier function="mod_dwarves_only"/> <requirement type="iron" quantity="2"/> 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 @@ <?xml version="1.0"?> <resource name="towershield"> <item weight="200" score="60" allow="dwarf"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="armorer" minskill="4"> <modifier function="mod_dwarves_only"/> <requirement type="iron" quantity="1"/> 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 @@ <?xml version="1.0"?> <resource name="axe"> <item weight="200" deny="goblin"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="3"> <requirement type="log" quantity="1"/> <requirement type="iron" quantity="1"/> 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 @@ --> <resource name="greatbow"> <item weight="100" allow="elf"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="5"> <modifier function="mod_elves_only"/> <requirement type="mallorn" quantity="2"/> 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 @@ --> <resource name="halberd"> <item weight="200" deny="goblin"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="3"> <requirement type="log" quantity="2"/> <requirement type="iron" quantity="1"/> 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 @@ <?xml version="1.0"?> <resource name="lance"> <item weight="200" deny="goblin"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="2"> <requirement type="log" quantity="2"/> </construction> 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 @@ <?xml version="1.0"?> <resource name="mallornlance"> <item weight="100" deny="goblin"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="5"> <requirement type="mallorn" quantity="2"/> </construction> 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 @@ --> <resource name="rustyhalberd"> <item weight="200" score="20" deny="goblin"> - <function name="canuse" value="lua_canuse_item"/> <construction skill="weaponsmithing" minskill="3"> <requirement type="iron" quantity="1"/> <requirement type="log" quantity="1"/> 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 <enno.rehling@gmail.com> Date: Sat, 4 Mar 2017 20:59:43 +0100 Subject: [PATCH 42/42] 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 @@ <?xml version="1.0"?> <resource name="hp" pooled="false"> <function name="change" value="lua_changeresource"/> - <function name="get" value="lua_getresource"/> </resource> 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 @@ <?xml version="1.0"?> <resource name="peasant" pooled="false"> <function name="change" value="lua_changeresource"/> - <function name="get" value="lua_getresource"/> </resource> 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 @@ <xi:include href="config://core/weapons/catapult.xml"/> <xi:include href="config://core/weapons/mallornbow.xml"/> <xi:include href="config://core/weapons/mallornspear.xml"/> - <xi:include href="config://core/weapons/rep_crossbow.xml"/> <xi:include href="config://core/weapons/runesword.xml"/> <xi:include href="config://core/weapons/rustyaxe.xml"/> <xi:include href="config://core/weapons/rustysword.xml"/> <xi:include href="config://core/weapons/spear.xml"/> <xi:include href="config://core/weapons/sword.xml"/> <xi:include href="config://core/weapons/firesword.xml"/> + <xi:include href="config://game/weapons/rep_crossbow.xml"/> <xi:include href="config://game/weapons/lance.xml"/> <xi:include href="config://game/weapons/axe.xml"/> <xi:include href="config://game/weapons/crossbow.xml"/> 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 @@ +<?xml version="1.0"?> +<resource name="rep_crossbow"> + <item weight="100" allow="dwarf halfling"> + <construction skill="weaponsmithing" minskill="5"> + <modifier function="mod_dwarves_only"/> + <requirement type="log" quantity="1"/> + <requirement type="iron" quantity="1"/> + </construction> + <weapon armorpiercing="true" pierce="true" missile="true" skill="crossbow" offmod="0" defmod="0" reload="1"> + <damage type="rider" value="3d4+5"/> + <damage type="footman" value="3d4+5"/> + <modifier type="missile_target" value="0"/> + </weapon> + </item> +</resource> 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 <util/assert.h> #include <util/attrib.h> #include <util/bsdstring.h> #include <util/gamedata.h> @@ -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 <triggers/timeout.h> /* util includes */ +#include <util/assert.h> #include <util/attrib.h> #include <util/base36.h> #include <util/bsdstring.h> @@ -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; }