forked from github/server
reduce complexity of building_protection.
This commit is contained in:
parent
bfb5a9b692
commit
3274065004
|
@ -39,3 +39,6 @@ tmp/
|
|||
tests/config.lua
|
||||
tests/reports/
|
||||
tests/data/185.dat
|
||||
/quicklist/
|
||||
/cutest/
|
||||
/critbit/
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
<?xml version="1.0"?>
|
||||
<building name="castle" capacity="1" fort="yes">
|
||||
<function name="name" value="castle_name_2"/>
|
||||
<function name="protection" value="building_protection"/>
|
||||
<function name="taxes" value="lua_building_taxes"/>
|
||||
<construction skill="building" minskill="1" maxsize="10" defense_bonus="0">
|
||||
<construction skill="building" minskill="1" maxsize="10">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="2" maxsize="40" defense_bonus="1">
|
||||
<construction skill="building" minskill="2" maxsize="40">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="3" maxsize="200" defense_bonus="3">
|
||||
<construction skill="building" minskill="3" maxsize="200">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="4" maxsize="1000" defense_bonus="5">
|
||||
<construction skill="building" minskill="4" maxsize="1000">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="5" maxsize="5000" defense_bonus="8">
|
||||
<construction skill="building" minskill="5" maxsize="5000">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="6" defense_bonus="12">
|
||||
<construction skill="building" minskill="6">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
</building>
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
<?xml version="1.0"?>
|
||||
<building name="castle" capacity="1" fort="yes">
|
||||
<function name="name" value="castle_name"/>
|
||||
<function name="protection" value="building_protection"/>
|
||||
<construction skill="building" minskill="1" maxsize="2" defense_bonus="0">
|
||||
<construction skill="building" minskill="1" maxsize="2">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="1" maxsize="8" defense_bonus="0">
|
||||
<construction skill="building" minskill="1" maxsize="8">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="2" maxsize="40" defense_bonus="1">
|
||||
<construction skill="building" minskill="2" maxsize="40">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="3" maxsize="200" defense_bonus="3">
|
||||
<construction skill="building" minskill="3" maxsize="200">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="4" maxsize="1000" defense_bonus="5">
|
||||
<construction skill="building" minskill="4" maxsize="1000">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="5" maxsize="5000" defense_bonus="8">
|
||||
<construction skill="building" minskill="5" maxsize="5000">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="6" defense_bonus="12">
|
||||
<construction skill="building" minskill="6">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
</building>
|
||||
|
|
|
@ -5,15 +5,14 @@
|
|||
|
||||
<building name="watch" maxsize="10" capacity="1" fort="yes">
|
||||
<function name="name" value="fort_name"/>
|
||||
<function name="protection" value="building_protection"/>
|
||||
<function name="taxes" value="lua_building_taxes"/>
|
||||
<construction skill="building" minskill="1" maxsize="5" defense_bonus="0">
|
||||
<construction skill="building" minskill="1" maxsize="5">
|
||||
<requirement type="log" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="2" maxsize="5" defense_bonus="1">
|
||||
<construction skill="building" minskill="2" maxsize="5">
|
||||
<requirement type="log" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="2" defense_bonus="2">
|
||||
<construction skill="building" minskill="2">
|
||||
<requirement type="log" quantity="1"/>
|
||||
</construction>
|
||||
</building>
|
||||
|
|
18
src/battle.c
18
src/battle.c
|
@ -1892,10 +1892,11 @@ int skilldiff(troop at, troop dt, int dist)
|
|||
}
|
||||
|
||||
if (df->building) {
|
||||
if (df->building->attribs) {
|
||||
building *b = df->building;
|
||||
if (b->attribs) {
|
||||
const curse_type *strongwall_ct = ct_find("strongwall");
|
||||
if (strongwall_ct) {
|
||||
curse *c = get_curse(df->building->attribs, strongwall_ct);
|
||||
curse *c = get_curse(b->attribs, strongwall_ct);
|
||||
if (curse_active(c)) {
|
||||
/* wirkt auf alle Geb<65>ude */
|
||||
skdiff -= curse_geteffect_int(c);
|
||||
|
@ -1903,15 +1904,16 @@ int skilldiff(troop at, troop dt, int dist)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (df->building->type->protection) {
|
||||
int beff = df->building->type->protection(df->building, du, DEFENSE_BONUS);
|
||||
if (beff) {
|
||||
if (b->type->flags & BTF_FORTIFICATION) {
|
||||
int stage = buildingeffsize(b, false);
|
||||
int beff = building_protection(b->type, stage);
|
||||
if (beff > 0) {
|
||||
skdiff -= beff;
|
||||
is_protected = 2;
|
||||
if (df->building->attribs) {
|
||||
if (b->attribs) {
|
||||
const curse_type *magicwalls_ct = ct_find("magicwalls");
|
||||
if (magicwalls_ct
|
||||
&& curse_active(get_curse(df->building->attribs, magicwalls_ct))) {
|
||||
&& curse_active(get_curse(b->attribs, magicwalls_ct))) {
|
||||
/* Verdoppelt Burgenbonus */
|
||||
skdiff -= beff;
|
||||
}
|
||||
|
@ -2022,7 +2024,7 @@ void damage_building(battle * b, building * bldg, int damage_abs)
|
|||
|
||||
/* Wenn Burg, dann gucken, ob die Leute alle noch in das Geb<65>ude passen. */
|
||||
|
||||
if (bldg->type->protection) {
|
||||
if (bldg->type->flags & BTF_FORTIFICATION) {
|
||||
side *s;
|
||||
|
||||
bldg->sizeleft = bldg->size;
|
||||
|
|
|
@ -60,10 +60,23 @@ static void test_make_fighter(CuTest * tc)
|
|||
test_cleanup();
|
||||
}
|
||||
|
||||
static int add_two(const building * b, const unit * u, building_bonus bonus) {
|
||||
static int add_two(const building * b, const unit * u) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
static building_type * setup_castle(void) {
|
||||
building_type * btype;
|
||||
construction *cons;
|
||||
|
||||
btype = bt_get_or_create("castle");
|
||||
btype->flags |= BTF_FORTIFICATION;
|
||||
cons = btype->construction = calloc(1, sizeof(construction));
|
||||
cons->maxsize = 5;
|
||||
cons = cons->improvement = calloc(1, sizeof(construction));
|
||||
cons->maxsize = -1;
|
||||
return btype;
|
||||
}
|
||||
|
||||
static void test_defenders_get_building_bonus(CuTest * tc)
|
||||
{
|
||||
unit *du, *au;
|
||||
|
@ -72,16 +85,13 @@ static void test_defenders_get_building_bonus(CuTest * tc)
|
|||
fighter *df, *af;
|
||||
battle *b;
|
||||
side *ds, *as;
|
||||
int diff;
|
||||
troop dt, at;
|
||||
building_type * btype;
|
||||
|
||||
test_cleanup();
|
||||
btype = setup_castle();
|
||||
r = test_create_region(0, 0, 0);
|
||||
btype = bt_get_or_create("castle");
|
||||
btype->protection = &add_two;
|
||||
bld = test_create_building(r, btype);
|
||||
bld->size = 10;
|
||||
|
||||
du = test_create_unit(test_create_faction(NULL), r);
|
||||
au = test_create_unit(test_create_faction(NULL), r);
|
||||
|
@ -101,11 +111,14 @@ static void test_defenders_get_building_bonus(CuTest * tc)
|
|||
at.fighter = af;
|
||||
at.index = 0;
|
||||
|
||||
diff = skilldiff(at, dt, 0);
|
||||
CuAssertIntEquals(tc, -2, diff);
|
||||
bld->size = 10; /* stage 1 building */
|
||||
CuAssertIntEquals(tc, -1, skilldiff(at, dt, 0));
|
||||
CuAssertIntEquals(tc, 0, skilldiff(dt, at, 0));
|
||||
|
||||
bld->size = 1; /* stage 0 building */
|
||||
CuAssertIntEquals(tc, 0, skilldiff(at, dt, 0));
|
||||
CuAssertIntEquals(tc, 0, skilldiff(dt, at, 0));
|
||||
|
||||
diff = skilldiff(dt, at, 0);
|
||||
CuAssertIntEquals(tc, 0, diff);
|
||||
free_battle(b);
|
||||
test_cleanup();
|
||||
}
|
||||
|
@ -122,8 +135,8 @@ static void test_attackers_get_no_building_bonus(CuTest * tc)
|
|||
|
||||
test_cleanup();
|
||||
r = test_create_region(0, 0, 0);
|
||||
btype = bt_get_or_create("castle");
|
||||
btype->protection = &add_two;
|
||||
btype = setup_castle();
|
||||
btype->flags |= BTF_FORTIFICATION;
|
||||
bld = test_create_building(r, btype);
|
||||
bld->size = 10;
|
||||
|
||||
|
@ -151,9 +164,9 @@ static void test_building_bonus_respects_size(CuTest * tc)
|
|||
faction * f;
|
||||
|
||||
test_cleanup();
|
||||
btype = setup_castle();
|
||||
r = test_create_region(0, 0, 0);
|
||||
btype = bt_get_or_create("castle");
|
||||
btype->protection = &add_two;
|
||||
btype->flags |= BTF_FORTIFICATION;
|
||||
bld = test_create_building(r, btype);
|
||||
bld->size = 10;
|
||||
|
||||
|
@ -178,28 +191,25 @@ static void test_building_bonus_respects_size(CuTest * tc)
|
|||
|
||||
static void test_building_defence_bonus(CuTest * tc)
|
||||
{
|
||||
unit *au;
|
||||
region *r;
|
||||
building * bld;
|
||||
building_type * btype;
|
||||
faction * f;
|
||||
int def;
|
||||
|
||||
test_cleanup();
|
||||
r = test_create_region(0, 0, 0);
|
||||
btype = test_create_buildingtype("castle");
|
||||
btype->protection = (int(*)(const struct building *, const struct unit *, building_bonus))get_function("building_protection");
|
||||
btype->construction->defense_bonus = 3;
|
||||
bld = test_create_building(r, btype);
|
||||
bld->size = 1;
|
||||
btype = setup_castle();
|
||||
|
||||
f = test_create_faction(NULL);
|
||||
au = test_create_unit(f, r);
|
||||
scale_number(au, 1);
|
||||
u_set_building(au, bld);
|
||||
btype->maxsize = -1; /* unlimited buildigs get the castle bonus */
|
||||
CuAssertIntEquals(tc, 0, building_protection(btype, 0));
|
||||
CuAssertIntEquals(tc, 1, building_protection(btype, 1));
|
||||
CuAssertIntEquals(tc, 3, building_protection(btype, 2));
|
||||
CuAssertIntEquals(tc, 5, building_protection(btype, 3));
|
||||
CuAssertIntEquals(tc, 8, building_protection(btype, 4));
|
||||
CuAssertIntEquals(tc, 12, building_protection(btype, 5));
|
||||
CuAssertIntEquals(tc, 12, building_protection(btype, 6));
|
||||
|
||||
def = btype->protection(bld, au, DEFENSE_BONUS);
|
||||
CuAssertIntEquals(tc, 3, def);
|
||||
btype->maxsize = 10; /* limited-size buildings are treated like an E3 watchtower */
|
||||
CuAssertIntEquals(tc, 0, building_protection(btype, 0));
|
||||
CuAssertIntEquals(tc, 1, building_protection(btype, 1));
|
||||
CuAssertIntEquals(tc, 2, building_protection(btype, 2));
|
||||
CuAssertIntEquals(tc, 2, building_protection(btype, 3));
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -441,10 +451,6 @@ static void test_battle_skilldiff(CuTest *tc)
|
|||
test_cleanup();
|
||||
}
|
||||
|
||||
static int protect(const building *b, const unit *u, building_bonus bonus) {
|
||||
return (bonus == DEFENSE_BONUS) ? 4 : 0;
|
||||
}
|
||||
|
||||
static void test_battle_skilldiff_building(CuTest *tc)
|
||||
{
|
||||
troop ta, td;
|
||||
|
@ -455,7 +461,7 @@ static void test_battle_skilldiff_building(CuTest *tc)
|
|||
const curse_type *strongwall_ct, *magicwalls_ct;
|
||||
|
||||
test_cleanup();
|
||||
btype = test_create_buildingtype("castle");
|
||||
btype = setup_castle();
|
||||
strongwall_ct = ct_find("strongwall");
|
||||
magicwalls_ct = ct_find("magicwalls");
|
||||
|
||||
|
@ -470,14 +476,14 @@ static void test_battle_skilldiff_building(CuTest *tc)
|
|||
ua = test_create_unit(test_create_faction(0), r);
|
||||
CuAssertIntEquals(tc, 0, skilldiff(ta, td, 0));
|
||||
|
||||
btype->protection = protect;
|
||||
CuAssertIntEquals(tc, -4, skilldiff(ta, td, 0));
|
||||
ud->building->size = 10;
|
||||
CuAssertIntEquals(tc, -1, skilldiff(ta, td, 0));
|
||||
|
||||
create_curse(NULL, &ud->building->attribs, magicwalls_ct, 1, 1, 1, 1);
|
||||
CuAssertIntEquals(tc, -8, skilldiff(ta, td, 0));
|
||||
CuAssertIntEquals(tc, -2, skilldiff(ta, td, 0));
|
||||
|
||||
create_curse(NULL, &ud->building->attribs, strongwall_ct, 1, 1, 2, 1);
|
||||
CuAssertIntEquals(tc, -10, skilldiff(ta, td, 0));
|
||||
CuAssertIntEquals(tc, -4, skilldiff(ta, td, 0));
|
||||
|
||||
free_battle(b);
|
||||
test_cleanup();
|
||||
|
|
|
@ -45,9 +45,6 @@ extern "C" {
|
|||
|
||||
int maxsize; /* maximum size of this type */
|
||||
int reqsize; /* size of object using up 1 set of requirement. */
|
||||
int defense_bonus; /* protection bonus (defense) during combat */
|
||||
int close_combat_bonus; /* close combat attack bonus*/
|
||||
int ranged_bonus; /* ranged attack bonus */
|
||||
requirement *materials; /* material req'd to build one object */
|
||||
const struct building_type *btype;
|
||||
/* building type required to make this thing */
|
||||
|
|
|
@ -337,40 +337,24 @@ const building_type *findbuildingtype(const char *name,
|
|||
|
||||
int cmp_castle_size(const building * b, const building * a)
|
||||
{
|
||||
if (!b || !b->type->protection || !building_owner(b)) {
|
||||
if (!b || !(b->type->flags & BTF_FORTIFICATION) || !building_owner(b)) {
|
||||
return -1;
|
||||
}
|
||||
if (!a || !a->type->protection || !building_owner(a)) {
|
||||
if (!a || !(a->type->flags & BTF_FORTIFICATION) || !building_owner(a)) {
|
||||
return 1;
|
||||
}
|
||||
return b->size - a->size;
|
||||
}
|
||||
|
||||
int building_protection(const building * b, const unit * u, building_bonus bonus)
|
||||
static const int castle_bonus[6] = { 0, 1, 3, 5, 8, 12 };
|
||||
static const int watch_bonus[3] = { 0, 1, 2 };
|
||||
|
||||
int building_protection(const building_type * btype, int stage)
|
||||
{
|
||||
int i = 0;
|
||||
int bsize = buildingeffsize(b, false);
|
||||
const construction *cons = b->type->construction;
|
||||
if (!cons) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < bsize; i++)
|
||||
{
|
||||
cons = cons->improvement;
|
||||
}
|
||||
|
||||
switch (bonus)
|
||||
{
|
||||
case DEFENSE_BONUS:
|
||||
return cons->defense_bonus;
|
||||
case CLOSE_COMBAT_ATTACK_BONUS:
|
||||
return cons->close_combat_bonus;
|
||||
case RANGED_ATTACK_BONUS:
|
||||
return cons->ranged_bonus;
|
||||
default:
|
||||
return 0;
|
||||
if (btype->maxsize < 0) {
|
||||
return castle_bonus[MIN(stage, 5)];
|
||||
}
|
||||
return watch_bonus[MIN(stage, 2)];
|
||||
}
|
||||
|
||||
void write_building_reference(const struct building *b, struct storage *store)
|
||||
|
@ -925,8 +909,6 @@ int cmp_current_owner(const building * b, const building * a)
|
|||
void register_buildings(void)
|
||||
{
|
||||
register_function((pf_generic)minimum_wage, "minimum_wage");
|
||||
register_function((pf_generic)building_protection,
|
||||
"building_protection");
|
||||
register_function((pf_generic)init_smithy, "init_smithy");
|
||||
register_function((pf_generic)castle_name, "castle_name");
|
||||
register_function((pf_generic)castle_name_2, "castle_name_2");
|
||||
|
|
|
@ -51,13 +51,7 @@ extern "C" {
|
|||
#define BTF_MAGIC 0x40 /* magical effect */
|
||||
#define BTF_ONEPERTURN 0x80 /* one one sizepoint can be added per turn */
|
||||
#define BTF_NAMECHANGE 0x100 /* name and description can be changed more than once */
|
||||
#define BTF_FORTIFICATION 0x200 /* safe from monsters */
|
||||
|
||||
typedef enum {
|
||||
DEFENSE_BONUS,
|
||||
CLOSE_COMBAT_ATTACK_BONUS, /* TODO: only DEFENSE_BONUS is in use? */
|
||||
RANGED_ATTACK_BONUS
|
||||
} building_bonus;
|
||||
#define BTF_FORTIFICATION 0x200 /* building_protection, safe from monsters */
|
||||
|
||||
typedef struct building_type {
|
||||
char *_name;
|
||||
|
@ -77,7 +71,6 @@ extern "C" {
|
|||
const struct building * b, int size);
|
||||
void(*init) (struct building_type *);
|
||||
void(*age) (struct building *);
|
||||
int(*protection) (const struct building *, const struct unit *, building_bonus bonus);
|
||||
double(*taxes) (const struct building *, int size);
|
||||
struct attrib *attribs;
|
||||
} building_type;
|
||||
|
@ -85,8 +78,8 @@ extern "C" {
|
|||
extern struct selist *buildingtypes;
|
||||
extern struct attrib_type at_building_action;
|
||||
|
||||
int cmp_castle_size(const struct building * b, const struct building * a);
|
||||
int building_protection(const struct building * b, const struct unit * u, building_bonus bonus);
|
||||
int cmp_castle_size(const struct building *b, const struct building *a);
|
||||
int building_protection(const struct building_type *btype, int stage);
|
||||
building_type *bt_get_or_create(const char *name);
|
||||
bool bt_changed(int *cache);
|
||||
const building_type *bt_find(const char *name);
|
||||
|
|
|
@ -376,7 +376,6 @@ static void test_btype_defaults(CuTest *tc) {
|
|||
CuAssertTrue(tc, !btype->name);
|
||||
CuAssertTrue(tc, !btype->init);
|
||||
CuAssertTrue(tc, !btype->age);
|
||||
CuAssertTrue(tc, !btype->protection);
|
||||
CuAssertTrue(tc, !btype->taxes);
|
||||
CuAssertDblEquals(tc, 1.0, btype->auraregen, 0.0);
|
||||
CuAssertIntEquals(tc, -1, btype->maxsize);
|
||||
|
|
|
@ -167,9 +167,6 @@ construction ** consPtr)
|
|||
con->maxsize = xml_ivalue(node, "maxsize", -1);
|
||||
con->minskill = xml_ivalue(node, "minskill", -1);
|
||||
con->reqsize = xml_ivalue(node, "reqsize", 1);
|
||||
con->defense_bonus = xml_ivalue(node, "defense_bonus", 0);
|
||||
con->close_combat_bonus = xml_ivalue(node, "close_combat_bonus", 0);
|
||||
con->ranged_bonus = xml_ivalue(node, "ranged_bonus", 0);
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "building");
|
||||
if (propValue != NULL) {
|
||||
|
@ -301,9 +298,6 @@ static int parse_buildings(xmlDocPtr doc)
|
|||
else if (strcmp((const char *)propValue, "age") == 0) {
|
||||
btype->age = (void(*)(struct building *))fun;
|
||||
}
|
||||
else if (strcmp((const char *)propValue, "protection") == 0) {
|
||||
btype->protection = (int(*)(const struct building *, const struct unit *, building_bonus))fun;
|
||||
}
|
||||
else if (strcmp((const char *)propValue, "taxes") == 0) {
|
||||
btype->taxes = (double(*)(const struct building *, int))fun;
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ building * test_create_building(region * r, const building_type * btype)
|
|||
assert(r);
|
||||
if (!btype) {
|
||||
building_type *bt_castle = test_create_buildingtype("castle");
|
||||
bt_castle->protection = building_protection;
|
||||
bt_castle->flags |= BTF_FORTIFICATION;
|
||||
btype = bt_castle;
|
||||
}
|
||||
b = new_building(btype, r, default_locale);
|
||||
|
|
Loading…
Reference in New Issue