forked from github/server
merge conflicts, race masking.
This commit is contained in:
commit
1ef57ef4f0
18 changed files with 68 additions and 117 deletions
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"/>
|
||||
|
@ -11,9 +11,7 @@
|
|||
<damage type="rider" value="2d6+4"/>
|
||||
<damage type="footman" value="2d6+4"/>
|
||||
<modifier type="missile_target" value="2"/>
|
||||
<modifier type="damage" value="1">
|
||||
<race name="elf"/>
|
||||
</modifier>
|
||||
<modifier type="damage" value="1" races="elf"/>
|
||||
</weapon>
|
||||
</item>
|
||||
</resource>
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
<damage type="rider" value="1d11+2"/>
|
||||
<damage type="footman" value="1d11+2"/>
|
||||
<modifier type="missile_target" value="2"/>
|
||||
<modifier type="damage" value="1">
|
||||
<race name="elf"/>
|
||||
</modifier>
|
||||
<modifier type="damage" value="1" races="elf"/>
|
||||
</weapon>
|
||||
</item>
|
||||
</resource>
|
||||
|
|
|
@ -2,15 +2,12 @@
|
|||
<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"/>
|
||||
</construction>
|
||||
<armor ac="0" penalty="-0.15" projectile="0.25" magres="0.0" shield="yes">
|
||||
<modifier type="canuse" function="mod_dwarves_only"/>
|
||||
</armor>
|
||||
<armor ac="0" penalty="-0.15" projectile="0.25" magres="0.0" shield="yes"/>
|
||||
</item>
|
||||
</resource>
|
||||
<resource name="shield">
|
||||
|
@ -22,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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
@ -136,9 +136,7 @@
|
|||
<damage type="rider" value="2d4+5"/>
|
||||
<damage type="footman" value="2d4+5"/>
|
||||
<modifier type="missile_target" value="2"/>
|
||||
<modifier type="damage" value="1">
|
||||
<race name="elf"/>
|
||||
</modifier>
|
||||
<modifier type="damage" value="1" races="elf"/>
|
||||
</weapon>
|
||||
</item>
|
||||
</resource>
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
<damage type="footman" value="3d8+8"/>
|
||||
<modifier type="missile_target" value="2"/>
|
||||
<modifier type="skill" value="-90"/>
|
||||
<modifier type="skill" value="100">
|
||||
<race name="snowman"/>
|
||||
</modifier>
|
||||
<modifier type="skill" value="100" races="snowman"/>
|
||||
</weapon>
|
||||
</item>
|
||||
</resource>
|
||||
|
|
30
src/battle.c
30
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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?) */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue