forked from github/server
* fix magic resistance calculation in calculate_armor. * add related tests. * refactor BF_CANATTACK -> BF_NO_ATTACK because it is easier.
This commit is contained in:
parent
2942babb0d
commit
62ee1468b8
|
@ -1181,7 +1181,7 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
|
||||||
const weapon_type *dwtype = NULL;
|
const weapon_type *dwtype = NULL;
|
||||||
const weapon_type *awtype = NULL;
|
const weapon_type *awtype = NULL;
|
||||||
const weapon *weapon;
|
const weapon *weapon;
|
||||||
double res = 0.0;
|
double res = 1.0;
|
||||||
|
|
||||||
int rda, sk = 0, sd;
|
int rda, sk = 0, sd;
|
||||||
bool magic = false;
|
bool magic = false;
|
||||||
|
@ -3996,7 +3996,7 @@ static bool start_battle(region * r, battle ** bp)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((u_race(u)->battle_flags & BF_CANATTACK) == 0) {
|
if (u_race(u)->battle_flags & BF_NO_ATTACK) {
|
||||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "race_no_attack",
|
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "race_no_attack",
|
||||||
"race", u_race(u)));
|
"race", u_race(u)));
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -248,6 +248,7 @@ static void test_calculate_armor(CuTest * tc)
|
||||||
i_change(&du->items, ishield, 1);
|
i_change(&du->items, ishield, 1);
|
||||||
i_change(&du->items, ichain, 1);
|
i_change(&du->items, ichain, 1);
|
||||||
dt.fighter = setup_fighter(&b, du);
|
dt.fighter = setup_fighter(&b, du);
|
||||||
|
rc->battle_flags &= ~BF_EQUIPMENT;
|
||||||
CuAssertIntEquals_Msg(tc, "require BF_EQUIPMENT", 1, calculate_armor(dt, 0, 0, 0));
|
CuAssertIntEquals_Msg(tc, "require BF_EQUIPMENT", 1, calculate_armor(dt, 0, 0, 0));
|
||||||
free_battle(b);
|
free_battle(b);
|
||||||
|
|
||||||
|
@ -274,6 +275,70 @@ static void test_calculate_armor(CuTest * tc)
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_magic_resistance(CuTest *tc)
|
||||||
|
{
|
||||||
|
troop dt;
|
||||||
|
battle *b;
|
||||||
|
region *r;
|
||||||
|
unit *du;
|
||||||
|
weapon_type *wtype;
|
||||||
|
armor_type *ashield, *achain;
|
||||||
|
item_type *ibelt, *ishield, *ichain;
|
||||||
|
race *rc;
|
||||||
|
double magres = 0.0;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
r = test_create_region(0, 0, 0);
|
||||||
|
ibelt = it_get_or_create(rt_get_or_create("trollbelt"));
|
||||||
|
ishield = it_get_or_create(rt_get_or_create("shield"));
|
||||||
|
ashield = new_armortype(ishield, 0.0, 0.5, 1, ATF_SHIELD);
|
||||||
|
ichain = it_get_or_create(rt_get_or_create("chainmail"));
|
||||||
|
achain = new_armortype(ichain, 0.0, 0.5, 3, ATF_NONE);
|
||||||
|
wtype = new_weapontype(it_get_or_create(rt_get_or_create("sword")), 0, 0.5, 0, 0, 0, 0, SK_MELEE, 1);
|
||||||
|
rc = test_create_race("human");
|
||||||
|
du = test_create_unit(test_create_faction(rc), r);
|
||||||
|
dt.index = 0;
|
||||||
|
|
||||||
|
dt.fighter = setup_fighter(&b, du);
|
||||||
|
calculate_armor(dt, 0, 0, &magres);
|
||||||
|
CuAssertDblEquals_Msg(tc, "magres unmodified", 0.0, magres, 0.01);
|
||||||
|
|
||||||
|
magres = 1.0;
|
||||||
|
calculate_armor(dt, 0, 0, &magres);
|
||||||
|
CuAssertDblEquals_Msg(tc, "no magres bonus", 0.0, magic_resistance(du), 0.01);
|
||||||
|
CuAssertDblEquals_Msg(tc, "no magres bonus", 1.0, magres, 0.01);
|
||||||
|
|
||||||
|
ashield->flags |= ATF_LAEN;
|
||||||
|
ashield->magres = 0.1;
|
||||||
|
magres = 1.0;
|
||||||
|
calculate_armor(dt, 0, 0, &magres);
|
||||||
|
free_battle(b);
|
||||||
|
|
||||||
|
i_change(&du->items, ishield, 1);
|
||||||
|
i_change(&du->items, ichain, 1);
|
||||||
|
achain->flags |= ATF_LAEN;
|
||||||
|
achain->magres = 0.1;
|
||||||
|
ashield->flags |= ATF_LAEN;
|
||||||
|
ashield->magres = 0.1;
|
||||||
|
dt.fighter = setup_fighter(&b, du);
|
||||||
|
magres = 1.0;
|
||||||
|
calculate_armor(dt, 0, 0, &magres);
|
||||||
|
CuAssertDblEquals_Msg(tc, "laen bonus", 0.81, magres, 0.01);
|
||||||
|
free_battle(b);
|
||||||
|
|
||||||
|
i_change(&du->items, ishield, -1);
|
||||||
|
i_change(&du->items, ichain, -1);
|
||||||
|
set_level(du, SK_MAGIC, 2);
|
||||||
|
dt.fighter = setup_fighter(&b, du);
|
||||||
|
magres = 1.0;
|
||||||
|
calculate_armor(dt, 0, 0, &magres);
|
||||||
|
CuAssertDblEquals_Msg(tc, "magic bonus", 0.1, magic_resistance(du), 0.01);
|
||||||
|
CuAssertDblEquals_Msg(tc, "magic bonus", 0.7, magres, 0.01);
|
||||||
|
|
||||||
|
free_battle(b);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
static void test_projectile_armor(CuTest * tc)
|
static void test_projectile_armor(CuTest * tc)
|
||||||
{
|
{
|
||||||
troop dt;
|
troop dt;
|
||||||
|
@ -321,6 +386,7 @@ CuSuite *get_battle_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_building_bonus_respects_size);
|
SUITE_ADD_TEST(suite, test_building_bonus_respects_size);
|
||||||
SUITE_ADD_TEST(suite, test_building_defence_bonus);
|
SUITE_ADD_TEST(suite, test_building_defence_bonus);
|
||||||
SUITE_ADD_TEST(suite, test_calculate_armor);
|
SUITE_ADD_TEST(suite, test_calculate_armor);
|
||||||
|
SUITE_ADD_TEST(suite, test_magic_resistance);
|
||||||
SUITE_ADD_TEST(suite, test_projectile_armor);
|
SUITE_ADD_TEST(suite, test_projectile_armor);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#define VERSION_MAJOR 3
|
#define VERSION_MAJOR 3
|
||||||
#define VERSION_MINOR 7
|
#define VERSION_MINOR 7
|
||||||
#define VERSION_BUILD 3
|
#define VERSION_BUILD 4
|
||||||
|
|
|
@ -183,7 +183,7 @@ race *rc_get_or_create(const char *zName)
|
||||||
rc->recruit_multi = 1.0F;
|
rc->recruit_multi = 1.0F;
|
||||||
rc->regaura = 1.0F;
|
rc->regaura = 1.0F;
|
||||||
rc->speed = 1.0F;
|
rc->speed = 1.0F;
|
||||||
rc->battle_flags = BF_CANATTACK;
|
rc->battle_flags = 0;
|
||||||
if (strchr(zName, ' ') != NULL) {
|
if (strchr(zName, ' ') != NULL) {
|
||||||
log_error("race '%s' has an invalid name. remove spaces\n", zName);
|
log_error("race '%s' has an invalid name. remove spaces\n", zName);
|
||||||
assert(strchr(zName, ' ') == NULL);
|
assert(strchr(zName, ' ') == NULL);
|
||||||
|
|
|
@ -231,7 +231,7 @@ extern "C" {
|
||||||
#define BF_RES_CUT (1<<3) /* Halber Schaden durch CUT */
|
#define BF_RES_CUT (1<<3) /* Halber Schaden durch CUT */
|
||||||
#define BF_RES_BASH (1<<4) /* Halber Schaden durch BASH */
|
#define BF_RES_BASH (1<<4) /* Halber Schaden durch BASH */
|
||||||
#define BF_INV_NONMAGIC (1<<5) /* Immun gegen nichtmagischen Schaden */
|
#define BF_INV_NONMAGIC (1<<5) /* Immun gegen nichtmagischen Schaden */
|
||||||
#define BF_CANATTACK (1<<6) /* Kann keine ATTACKIERE Befehle ausfuehren */
|
#define BF_NO_ATTACK (1<<6) /* Kann keine ATTACKIERE Befehle ausfuehren */
|
||||||
|
|
||||||
extern int unit_old_max_hp(struct unit *u);
|
extern int unit_old_max_hp(struct unit *u);
|
||||||
extern const char *racename(const struct locale *lang, const struct unit *u,
|
extern const char *racename(const struct locale *lang, const struct unit *u,
|
||||||
|
|
|
@ -36,6 +36,7 @@ static void test_rc_defaults(CuTest *tc) {
|
||||||
CuAssertIntEquals(tc, 0, rc->armor);
|
CuAssertIntEquals(tc, 0, rc->armor);
|
||||||
CuAssertIntEquals(tc, 0, rc->at_bonus);
|
CuAssertIntEquals(tc, 0, rc->at_bonus);
|
||||||
CuAssertIntEquals(tc, 0, rc->df_bonus);
|
CuAssertIntEquals(tc, 0, rc->df_bonus);
|
||||||
|
CuAssertIntEquals(tc, 0, rc->battle_flags);
|
||||||
CuAssertIntEquals(tc, PERSON_WEIGHT, rc->weight);
|
CuAssertIntEquals(tc, PERSON_WEIGHT, rc->weight);
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1721,7 +1721,7 @@ static int parse_races(xmlDocPtr doc)
|
||||||
rc->ec_flags |= ECF_REC_UNLIMITED;
|
rc->ec_flags |= ECF_REC_UNLIMITED;
|
||||||
|
|
||||||
if (xml_bvalue(node, "equipment", false))
|
if (xml_bvalue(node, "equipment", false))
|
||||||
rc->battle_flags |= BF_EQUIPMENT;
|
rc->battle_flags |= BF_EQUIPMENT; // TODO: invert this flag, so rc_get_or_create gets simpler
|
||||||
if (xml_bvalue(node, "noblock", false))
|
if (xml_bvalue(node, "noblock", false))
|
||||||
rc->battle_flags |= BF_NOBLOCK;
|
rc->battle_flags |= BF_NOBLOCK;
|
||||||
if (xml_bvalue(node, "invinciblenonmagic", false))
|
if (xml_bvalue(node, "invinciblenonmagic", false))
|
||||||
|
@ -1732,8 +1732,8 @@ static int parse_races(xmlDocPtr doc)
|
||||||
rc->battle_flags |= BF_RES_CUT;
|
rc->battle_flags |= BF_RES_CUT;
|
||||||
if (xml_bvalue(node, "resistpierce", false))
|
if (xml_bvalue(node, "resistpierce", false))
|
||||||
rc->battle_flags |= BF_RES_PIERCE;
|
rc->battle_flags |= BF_RES_PIERCE;
|
||||||
if (xml_bvalue(node, "canattack", true))
|
if (xml_bvalue(node, "noattack", false))
|
||||||
rc->battle_flags |= BF_CANATTACK; // TODO: invert this flag, so rc_get_or_create gets simpler
|
rc->battle_flags |= BF_NO_ATTACK;
|
||||||
|
|
||||||
for (child = node->children; child; child = child->next) {
|
for (child = node->children; child; child = child->next) {
|
||||||
if (strcmp((const char *)child->name, "ai") == 0) {
|
if (strcmp((const char *)child->name, "ai") == 0) {
|
||||||
|
|
|
@ -36,6 +36,7 @@ struct race *test_create_race(const char *name)
|
||||||
race *rc = rc_get_or_create(name);
|
race *rc = rc_get_or_create(name);
|
||||||
rc->maintenance = 10;
|
rc->maintenance = 10;
|
||||||
rc->ec_flags |= GETITEM;
|
rc->ec_flags |= GETITEM;
|
||||||
|
rc->battle_flags = BF_EQUIPMENT;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue