test magicwalls and strongwalls effects on buildings.

This commit is contained in:
Enno Rehling 2016-08-29 08:53:09 +01:00
parent 23a91be9c1
commit 0d609f2115
6 changed files with 74 additions and 39 deletions

View File

@ -1922,20 +1922,8 @@ int skilldiff(troop at, troop dt, int dist)
}
if (df->building) {
bool init = false;
static const curse_type *strongwall_ct, *magicwalls_ct;
if (!init) {
strongwall_ct = ct_find("strongwall");
magicwalls_ct = ct_find("magicwalls");
init = true;
}
if (df->building->type->protection) {
int beff = df->building->type->protection(df->building, du, DEFENSE_BONUS);
if (beff) {
skdiff -= beff;
is_protected = 2;
}
}
static const curse_type *strongwall_ct;
strongwall_ct = ct_find("strongwall");
if (strongwall_ct) {
curse *c = get_curse(df->building->attribs, strongwall_ct);
if (curse_active(c)) {
@ -1944,11 +1932,19 @@ int skilldiff(troop at, troop dt, int dist)
is_protected = 2;
}
}
if (df->building->type->protection) {
if (magicwalls_ct
&& curse_active(get_curse(df->building->attribs, magicwalls_ct))) {
/* Verdoppelt Burgenbonus */
skdiff -= df->building->type->protection(df->building, du, DEFENSE_BONUS);
int beff = df->building->type->protection(df->building, du, DEFENSE_BONUS);
if (beff) {
static const curse_type *magicwalls_ct;
skdiff -= beff;
is_protected = 2;
magicwalls_ct = ct_find("magicwalls");
if (magicwalls_ct
&& curse_active(get_curse(df->building->attribs, magicwalls_ct))) {
/* Verdoppelt Burgenbonus */
skdiff -= beff;
}
}
}
}

View File

@ -6,6 +6,7 @@
#include <kernel/config.h>
#include <kernel/building.h>
#include <kernel/faction.h>
#include <kernel/curse.h>
#include <kernel/item.h>
#include <kernel/race.h>
#include <kernel/region.h>
@ -59,7 +60,7 @@ static void test_make_fighter(CuTest * tc)
test_cleanup();
}
static int add_two(building * b, unit * u, building_bonus bonus) {
static int add_two(const building * b, const unit * u, building_bonus bonus) {
return 2;
}
@ -187,7 +188,7 @@ static void test_building_defence_bonus(CuTest * tc)
test_cleanup();
r = test_create_region(0, 0, 0);
btype = test_create_buildingtype("castle");
btype->protection = (int(*)(struct building *, struct unit *, building_bonus))get_function("building_protection");
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;
@ -403,7 +404,7 @@ static void test_projectile_armor(CuTest * tc)
test_cleanup();
}
static void test_battle_skilldiff(CuTest *tc)
static void test_battle_skilldiff(CuTest *tc)
{
troop ta, td;
region *r;
@ -411,6 +412,7 @@ static void test_battle_skilldiff(CuTest *tc)
battle *b = NULL;
test_cleanup();
r = test_create_region(0, 0, 0);
ud = test_create_unit(test_create_faction(0), r);
ua = test_create_unit(test_create_faction(0), r);
@ -425,6 +427,54 @@ static void test_battle_skilldiff(CuTest *tc)
td.fighter->person[0].defence = 1;
CuAssertIntEquals(tc, 1, skilldiff(ta, td, 0));
td.fighter->person[0].flags |= FL_SLEEPING;
CuAssertIntEquals(tc, 3, skilldiff(ta, td, 0));
// TODO: unarmed halfling vs. dragon: +5
// TODO: rule_goblin_bonus
free_battle(b);
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;
region *r;
unit *ua, *ud;
battle *b = NULL;
building_type *btype;
static const curse_type *strongwall_ct, *magicwalls_ct;
test_cleanup();
btype = test_create_buildingtype("castle");
strongwall_ct = ct_find("strongwall");
magicwalls_ct = ct_find("magicwalls");
r = test_create_region(0, 0, 0);
ud = test_create_unit(test_create_faction(0), r);
ud->building = test_create_building(ud->region, btype);
ua = test_create_unit(test_create_faction(0), r);
td.fighter = setup_fighter(&b, ud);
td.index = 0;
ta.fighter = setup_fighter(&b, ua);
ta.index = 0;
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));
create_curse(NULL, &ud->building->attribs, magicwalls_ct, 1, 1, 1, 1);
CuAssertIntEquals(tc, -8, skilldiff(ta, td, 0));
create_curse(NULL, &ud->building->attribs, strongwall_ct, 1, 1, 2, 1);
CuAssertIntEquals(tc, -10, skilldiff(ta, td, 0));
free_battle(b);
test_cleanup();
}
@ -434,6 +484,7 @@ CuSuite *get_battle_suite(void)
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_make_fighter);
SUITE_ADD_TEST(suite, test_battle_skilldiff);
SUITE_ADD_TEST(suite, test_battle_skilldiff_building);
SUITE_ADD_TEST(suite, test_defenders_get_building_bonus);
SUITE_ADD_TEST(suite, test_attackers_get_no_building_bonus);
SUITE_ADD_TEST(suite, test_building_bonus_respects_size);

View File

@ -322,9 +322,8 @@ const building_type *findbuildingtype(const char *name,
return (const building_type *)type.v;
}
static int building_protection(building * b, unit * u, building_bonus bonus)
static int building_protection(const building * b, const unit * u, building_bonus bonus)
{
int i = 0;
int bsize = buildingeffsize(b, false);
const construction *cons = b->type->construction;
@ -350,17 +349,10 @@ static int building_protection(building * b, unit * u, building_bonus bonus)
}
}
static int meropis_building_protection(building * b, unit * u)
{
return 2;
}
void register_buildings(void)
{
register_function((pf_generic)building_protection,
"building_protection");
register_function((pf_generic)meropis_building_protection,
"meropis_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");

View File

@ -75,7 +75,7 @@ extern "C" {
const struct building * b, int size);
void(*init) (struct building_type *);
void(*age) (struct building *);
int(*protection) (struct building *, struct unit *, building_bonus);
int(*protection) (const struct building *, const struct unit *, building_bonus bonus);
double(*taxes) (const struct building *, int size);
struct attrib *attribs;
} building_type;

View File

@ -1217,16 +1217,12 @@ static int item_modification(const unit * u, skill_t sk, int val)
static int att_modification(const unit * u, skill_t sk)
{
double result = 0;
static bool init = false; // TODO: static variables are bad global state
static const curse_type *skillmod_ct, *gbdream_ct, *worse_ct;
curse *c;
if (!init) {
init = true;
skillmod_ct = ct_find("skillmod");
gbdream_ct = ct_find("gbdream");
worse_ct = ct_find("worse");
}
skillmod_ct = ct_find("skillmod");
gbdream_ct = ct_find("gbdream");
worse_ct = ct_find("worse");
c = get_curse(u->attribs, worse_ct);
if (c != NULL)

View File

@ -305,7 +305,7 @@ static int parse_buildings(xmlDocPtr doc)
btype->age = (void(*)(struct building *))fun;
}
else if (strcmp((const char *)propValue, "protection") == 0) {
btype->protection = (int(*)(struct building *, struct unit *, building_bonus))fun;
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;