diff --git a/res/core/resources/iron.xml b/res/core/resources/iron.xml index 38ddb33c8..ae4829dd7 100644 --- a/res/core/resources/iron.xml +++ b/res/core/resources/iron.xml @@ -8,7 +8,7 @@ - + diff --git a/res/core/resources/stone.xml b/res/core/resources/stone.xml index b8f91eadc..459e66074 100644 --- a/res/core/resources/stone.xml +++ b/res/core/resources/stone.xml @@ -7,7 +7,7 @@ - + diff --git a/res/core/weapons/greatbow.xml b/res/core/weapons/greatbow.xml index b30cae8c6..ad6a4e018 100644 --- a/res/core/weapons/greatbow.xml +++ b/res/core/weapons/greatbow.xml @@ -2,7 +2,7 @@ - + @@ -11,9 +11,7 @@ - - - + diff --git a/res/core/weapons/mallornbow.xml b/res/core/weapons/mallornbow.xml index 9164d2c4b..b50104e36 100644 --- a/res/core/weapons/mallornbow.xml +++ b/res/core/weapons/mallornbow.xml @@ -10,9 +10,7 @@ - - - + diff --git a/res/e3a/armor.xml b/res/e3a/armor.xml index d0d5138ef..207f873b2 100644 --- a/res/e3a/armor.xml +++ b/res/e3a/armor.xml @@ -2,15 +2,12 @@ - - + - - - + @@ -22,8 +19,7 @@ - - + diff --git a/res/e3a/weapons.xml b/res/e3a/weapons.xml index 3a75fe350..3eea6dc44 100644 --- a/res/e3a/weapons.xml +++ b/res/e3a/weapons.xml @@ -31,7 +31,7 @@ - + @@ -127,7 +127,7 @@ * has a lua canuse function * has lower damage --> - + @@ -136,9 +136,7 @@ - - - + diff --git a/res/eressea/items.xml b/res/eressea/items.xml index 2cfa9e653..ea6ab047d 100644 --- a/res/eressea/items.xml +++ b/res/eressea/items.xml @@ -10,9 +10,7 @@ - - - + diff --git a/src/battle.c b/src/battle.c index f6a1314ea..fb91a1998 100644 --- a/src/battle.c +++ b/src/battle.c @@ -723,6 +723,7 @@ bool missile) } if (wtype->modifiers != NULL) { /* Pferdebonus, Lanzenbonus, usw. */ + const race *rc = u_race(tu); int m; unsigned int flags = WMF_SKILL | (attacking ? WMF_OFFENSIVE : WMF_DEFENSIVE); @@ -738,17 +739,10 @@ bool missile) for (m = 0; wtype->modifiers[m].value; ++m) { if ((wtype->modifiers[m].flags & flags) == flags) { - race_list *rlist = wtype->modifiers[m].races; - if (rlist != NULL) { - while (rlist) { - if (rlist->data == u_race(tu)) - break; - rlist = rlist->next; - } - if (rlist == NULL) - continue; + int mask = wtype->modifiers[m].race_mask; + if ((mask == 0) || (mask & rc->mask_item)) { + skill += wtype->modifiers[m].value; } - skill += wtype->modifiers[m].value; } } } @@ -1029,17 +1023,10 @@ static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_ for (m = 0; wtype->modifiers[m].value; ++m) { /* weapon damage for this weapon, possibly by race */ if (wtype->modifiers[m].flags & WMF_DAMAGE) { - race_list *rlist = wtype->modifiers[m].races; - if (rlist != NULL) { - while (rlist) { - if (rlist->data == ar) - break; - rlist = rlist->next; - } - if (rlist == NULL) - continue; + int mask = wtype->modifiers[m].race_mask; + if ((mask == 0) || (mask & ar->mask_item)) { + modifier += wtype->modifiers[m].value; } - modifier += wtype->modifiers[m].value; } } } @@ -3272,8 +3259,9 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack) adata->atype = itm->type->rtype->atype; adata->count = itm->number; for (aptr = &fig->armors; *aptr; aptr = &(*aptr)->next) { - if (adata->atype->prot > (*aptr)->atype->prot) + if (adata->atype->prot > (*aptr)->atype->prot) { break; + } } adata->next = *aptr; *aptr = adata; diff --git a/src/economy.c b/src/economy.c index 18ca23b8e..4cabb4ab5 100644 --- a/src/economy.c +++ b/src/economy.c @@ -833,7 +833,8 @@ static struct message * get_modifiers(unit *u, skill_t sk, const resource_type * for (mod = rtype->modifiers; mod && mod->type != RMT_END; ++mod) { if (mod->btype == NULL || mod->btype == btype) { - if (mod->race == NULL || mod->race == u_race(u)) { + const race * rc = u_race(u); + if (mod->race_mask == 0 || (mod->race_mask & rc->mask_item)) { switch (mod->type) { case RMT_PROD_SAVE: if (savep) { @@ -845,7 +846,7 @@ static struct message * get_modifiers(unit *u, skill_t sk, const resource_type * mod_skill(mod, sk, &skill); break; case RMT_PROD_REQUIRE: - if (mod->race) need_race |= 1; + if (mod->race_mask) need_race |= 1; if (mod->btype) { need_bldg |= 1; } @@ -857,7 +858,7 @@ static struct message * get_modifiers(unit *u, skill_t sk, const resource_type * } } if (mod->type == RMT_PROD_REQUIRE) { - if (mod->race) need_race |= 2; + if (mod->race_mask) need_race |= 2; if (mod->btype) { btype_needed = mod->btype; need_bldg |= 2; diff --git a/src/economy.test.c b/src/economy.test.c index 282318191..3e5d39007 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -509,7 +509,7 @@ static void test_modify_material(CuTest *tc) { mod = rtype->modifiers = calloc(2, sizeof(resource_mod)); mod[0].type = RMT_USE_SAVE; mod[0].value = frac_make(2, 1); - mod[0].race = u_race(u); + mod[0].race_mask = rc_mask(u_race(u)); itype = test_create_itemtype("sword"); make_item(u, itype, 1); @@ -574,7 +574,7 @@ static void test_modify_skill(CuTest *tc) { mod[0].type = RMT_PROD_SKILL; mod[0].value.sa[0] = SK_WEAPONSMITH; mod[0].value.sa[1] = 1; - mod[0].race = u_race(u); + mod[0].race_mask = rc_mask(u_race(u)); set_item(u, rtype->itype, 2); /* 2 iron should get us 2 swords */ make_item(u, itype, 2); @@ -647,7 +647,7 @@ static void test_modify_production(CuTest *tc) { rtype->modifiers = calloc(3, sizeof(resource_mod)); rtype->modifiers[0].type = RMT_PROD_SAVE; - rtype->modifiers[0].race = u->_race; + rtype->modifiers[0].race_mask = rc_mask(u->_race); rtype->modifiers[0].value.sa[0] = (short)(0.5+100*d); rtype->modifiers[0].value.sa[1] = 100; rtype->modifiers[1].type = RMT_END; @@ -668,7 +668,7 @@ static void test_modify_production(CuTest *tc) { CuAssertIntEquals(tc, 280, region_getresource(u->region, rtype)); /* 50% saving = 3 stones make 6 stones */ rtype->modifiers[0].type = RMT_PROD_REQUIRE; - rtype->modifiers[0].race = NULL; + rtype->modifiers[0].race_mask = 0; rtype->modifiers[0].btype = bt_get_or_create("mine"); test_clear_messages(u->faction); @@ -677,7 +677,7 @@ static void test_modify_production(CuTest *tc) { CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "building_needed")); rtype->modifiers[0].type = RMT_PROD_REQUIRE; - rtype->modifiers[0].race = test_create_race("smurf"); + rtype->modifiers[0].race_mask = rc_mask(test_create_race("smurf")); rtype->modifiers[0].btype = NULL; test_clear_messages(u->faction); @@ -686,7 +686,7 @@ static void test_modify_production(CuTest *tc) { CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error117")); rtype->modifiers[1].type = RMT_PROD_REQUIRE; - rtype->modifiers[1].race = u_race(u); + rtype->modifiers[1].race_mask = rc_mask(u_race(u)); rtype->modifiers[1].btype = NULL; rtype->modifiers[2].type = RMT_END; diff --git a/src/kernel/build.c b/src/kernel/build.c index b2774fbd7..96aee5662 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -419,7 +419,7 @@ static int matmod(const unit * u, const resource_type * rtype, int value) for (mod = rtype->modifiers; mod->type != RMT_END; ++mod) { if (mod->type == RMT_USE_SAVE) { if (!mod->btype || mod->btype == btype) { - if (!mod->race || mod->race == rc) { + if (!mod->race_mask || (mod->race_mask & rc->mask_item)) { save = frac_mul(save, mod->value); } } diff --git a/src/kernel/item.c b/src/kernel/item.c index ef0f46768..c60ce0cdf 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -609,16 +609,6 @@ mod_elves_only(const unit * u, const region * r, skill_t sk, int value) return -118; } -static int -mod_dwarves_only(const unit * u, const region * r, skill_t sk, int value) -{ - UNUSED_ARG(r); - if (u_race(u) == get_race(RC_DWARF) || (u_race(u)->ec_flags & ECF_IRONGOLEM)) { - return value; - } - return -118; -} - void register_item_give(int(*foo) (struct unit *, struct unit *, const struct item_type *, int, struct order *), const char *name) @@ -979,7 +969,6 @@ void register_resources(void) registered = true; register_function((pf_generic)mod_elves_only, "mod_elves_only"); - register_function((pf_generic)mod_dwarves_only, "mod_dwarves_only"); register_function((pf_generic)res_changeitem, "changeitem"); register_function((pf_generic)res_changeperson, "changeperson"); register_function((pf_generic)res_changepeasants, "changepeasants"); diff --git a/src/kernel/item.h b/src/kernel/item.h index f0ee6050b..a8815722f 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -151,8 +151,8 @@ extern "C" { struct race_list; typedef struct weapon_mod { int value; - unsigned int flags; - struct race_list *races; + int flags; + int race_mask; } weapon_mod; #define ATF_NONE 0x00 diff --git a/src/kernel/race.c b/src/kernel/race.c index c9299d5bd..ac81f7f78 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -259,7 +259,10 @@ void racelist_insert(struct race_list **rl, const struct race *r) *rl = rl2; } +static int race_mask = 0; + void free_races(void) { + race_mask = 0; while (races) { int i; race * rc = races->next; @@ -347,6 +350,10 @@ race *rc_create(const char *zName) assert(zName); rc = (race *)calloc(sizeof(race), 1); + + rc->mask_item = 1 << race_mask; + ++race_mask; + rc->magres.sa[1] = 1; rc->hitpoints = 1; rc->weight = PERSON_WEIGHT; @@ -575,18 +582,17 @@ void register_race_function(race_func func, const char *name) { register_function((pf_generic)func, name); } -static int race_mask = 1; +int rc_mask(const race * rc) { + assert(rc->mask_item); + return rc->mask_item; +} -int rc_mask(char *list) { +int rc_get_mask(char *list) { int mask = 0; char * tok = strtok(list, " ,"); 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; + mask |= rc_mask(rc); tok = strtok(NULL, " ,"); } return mask; diff --git a/src/kernel/race.h b/src/kernel/race.h index 042cb5e78..7c38eec57 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -198,7 +198,8 @@ extern "C" { #define MIGRANTS_LOG10 1 int rc_migrants_formula(const race *rc); - int rc_mask(char *list); + int rc_mask(const race *rc); + int rc_get_mask(char *list); /* Flags. Do not reorder these without changing json_race() in jsonconf.c */ #define RCF_NPC (1<<0) /* cannot be the race for a player faction (and other limits?) */ diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index 2f34c127e..d695969b7 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -178,10 +178,10 @@ static void test_rc_mask(CuTest *tc) { char list[64]; test_setup(); strcpy(list, "goblin dwarf"); - mask = rc_mask(list); + mask = rc_get_mask(list); CuAssertIntEquals(tc, 3, mask); CuAssertStrEquals(tc, "goblin", list); - mask = rc_mask(list); + mask = rc_get_mask(list); CuAssertIntEquals(tc, 1, mask); test_teardown(); } diff --git a/src/kernel/resources.h b/src/kernel/resources.h index 2daa44dd8..8f291c305 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -50,7 +50,7 @@ extern "C" { resource_modifier_type type; variant value; const struct building_type *btype; - const struct race *race; + int race_mask; } resource_mod; typedef struct rawmaterial_type { diff --git a/src/xmlreader.c b/src/xmlreader.c index c65a4ca9c..b3822e0bc 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -61,6 +61,17 @@ without prior permission by the authors of Eressea. #include +static void mask_races(xmlNodePtr node, const char *key, int *maskp) { + xmlChar *propValue = xmlGetProp(node, BAD_CAST key); + int mask = 0; + assert(maskp); + if (propValue) { + mask = rc_get_mask((char *)propValue); + xmlFree(propValue); + } + *maskp = mask; +} + static variant xml_fraction(xmlNodePtr node, const char *name) { xmlChar *propValue = xmlGetProp(node, BAD_CAST name); if (propValue != NULL) { @@ -129,16 +140,8 @@ static resource_mod * xml_readmodifiers(xmlXPathObjectPtr result, xmlNodePtr nod xmlNodePtr node = result->nodesetval->nodeTab[k]; xmlChar *propValue; building_type *btype = NULL; - const race *rc = NULL; - propValue = xmlGetProp(node, BAD_CAST "race"); - if (propValue != NULL) { - rc = rc_find((const char *)propValue); - if (rc == NULL) - rc = rc_get_or_create((const char *)propValue); - xmlFree(propValue); - } - modifiers[k].race = rc; + mask_races(node, "races", &modifiers[k].race_mask); propValue = xmlGetProp(node, BAD_CAST "building"); if (propValue != NULL) { @@ -592,8 +595,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) wtype->modifiers = calloc(result->nodesetval->nodeNr + 1, sizeof(weapon_mod)); for (k = 0; k != result->nodesetval->nodeNr; ++k) { xmlNodePtr node = result->nodesetval->nodeTab[k]; - xmlXPathObjectPtr races; - int r, flags = 0; + int flags = 0; if (xml_bvalue(node, "walking", false)) flags |= WMF_WALKING; @@ -620,21 +622,8 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) wtype->modifiers[k].flags = flags; wtype->modifiers[k].value = xml_ivalue(node, "value", 0); - xpath->node = node; - races = xmlXPathEvalExpression(BAD_CAST "race", xpath); - for (r = 0; r != races->nodesetval->nodeNr; ++r) { - xmlNodePtr node = races->nodesetval->nodeTab[r]; - - propValue = xmlGetProp(node, BAD_CAST "name"); - if (propValue != NULL) { - const race *rc = rc_find((const char *)propValue); - if (rc == NULL) - rc = rc_get_or_create((const char *)propValue); - racelist_insert(&wtype->modifiers[k].races, rc); - xmlFree(propValue); - } - } - xmlXPathFreeObject(races); + mask_races(node, "races", &wtype->modifiers[k].race_mask); + wtype->modifiers[k].race_mask = 0; } xmlXPathFreeObject(result); @@ -667,17 +656,6 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) return wtype; } -static void mask_races(xmlNodePtr node, const char *key, int *maskp) { - xmlChar *propValue = xmlGetProp(node, BAD_CAST key); - int mask = 0; - assert(maskp); - if (propValue) { - mask = rc_mask((char *)propValue); - xmlFree(propValue); - } - *maskp = mask; -} - static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) { xmlNodePtr node = xpath->node; @@ -1318,7 +1296,7 @@ static void parse_ai(race * rc, xmlNodePtr node) rc->flags |= RCF_ATTACK_MOVED; } -static void set_study_speed(race *rc, skill_t sk, int modifier){ +static void set_study_speed(race *rc, skill_t sk, int modifier) { if (!rc->study_speed) rc->study_speed = calloc(1, MAXSKILLS); rc->study_speed[sk] = (char)modifier;