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;