XML simplificatio: unified system for masking races on modifiers.

This commit is contained in:
Enno Rehling 2018-04-29 13:46:17 +02:00
parent ac786e034c
commit 837ab325f9
13 changed files with 48 additions and 52 deletions

View File

@ -8,7 +8,7 @@
<modifier building="smithy" type="save" value="2"/>
<modifier building="mine" type="skill" value="1"/>
<modifier building="mine" type="material" value="0.5"/>
<modifier race="dwarf" type="material" value="0.6"/>
<modifier races="dwarf" type="material" value="0.6"/>
</resource>
</resources>
</eressea>

View File

@ -7,7 +7,7 @@
</item>
<modifier building="quarry" type="skill" value="1"/>
<modifier building="quarry" type="material" value="0.5"/>
<modifier race="troll" type="material" value="0.75"/>
<modifier races="troll" type="material" value="0.75"/>
</resource>
</resources>
</eressea>

View File

@ -2,7 +2,7 @@
<eressea>
<resources>
<resource name="greatbow">
<modifier type="require" race="elf"/>
<modifier type="require" races="elf"/>
<item weight="100">
<construction skill="weaponsmithing" minskill="5">
<requirement type="mallorn" quantity="2"/>

View File

@ -2,8 +2,7 @@
<eressea>
<resources>
<resource name="towershield">
<modifier type="require" race="dwarf"/>
<modifier type="require" race="irongolem"/>
<modifier type="require" races="dwarf irongolem"/>
<item weight="200" score="60" allow="dwarf">
<construction skill="armorer" minskill="4">
<requirement type="iron" quantity="1"/>
@ -20,8 +19,7 @@
</item>
</resource>
<resource name="scale">
<modifier type="require" race="dwarf"/>
<modifier type="require" race="irongolem"/>
<modifier type="require" races="dwarf irongolem"/>
<item weight="300" score="150" allow="dwarf halfling">
<construction skill="armorer" minskill="5">
<requirement type="iron" quantity="2"/>

View File

@ -31,7 +31,7 @@
</item>
</resource>
<resource name="rep_crossbow">
<modifier type="require" race="dwarf"/>
<modifier type="require" races="dwarf"/>
<item weight="100" allow="dwarf halfling">
<construction skill="weaponsmithing" minskill="5">
<requirement type="log" quantity="1"/>
@ -127,7 +127,7 @@
* has a lua canuse function
* has lower damage
-->
<modifier type="require" race="elf"/>
<modifier type="require" races="elf"/>
<item weight="100" allow="elf">
<construction skill="weaponsmithing" minskill="5">
<requirement type="mallorn" quantity="2"/>

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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?) */

View File

@ -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();
}

View File

@ -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 {

View File

@ -61,6 +61,17 @@ without prior permission by the authors of Eressea.
#include <string.h>
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) {
@ -520,8 +523,6 @@ static armor_type *xml_readarmor(xmlXPathContextPtr xpath, item_type * itype)
return atype;
}
static void mask_races(xmlNodePtr node, const char *key, int *maskp);
static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype)
{
xmlNodePtr node = xpath->node;
@ -656,17 +657,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;