forked from github/server
refactor: extract damage calculation from terminate
start writing tests (WIP)
This commit is contained in:
parent
91a6324a97
commit
15ff621cbb
3 changed files with 116 additions and 81 deletions
166
src/battle.c
166
src/battle.c
|
@ -1078,66 +1078,14 @@ static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_
|
||||||
return modifier;
|
return modifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awtype, double *magres) {
|
||||||
terminate(troop dt, troop at, int type, const char *damage, bool missile)
|
|
||||||
{
|
|
||||||
item **pitm;
|
|
||||||
fighter *df = dt.fighter;
|
|
||||||
fighter *af = at.fighter;
|
|
||||||
unit *au = af->unit;
|
|
||||||
unit *du = df->unit;
|
|
||||||
battle *b = df->side->battle;
|
|
||||||
int heiltrank = 0;
|
|
||||||
static int rule_armor = -1;
|
static int rule_armor = -1;
|
||||||
|
fighter *df = dt.fighter;
|
||||||
/* Schild */
|
unit *du = df->unit;
|
||||||
side *ds = df->side;
|
|
||||||
int hp;
|
|
||||||
|
|
||||||
int ar = 0, an, am;
|
int ar = 0, an, am;
|
||||||
const armor_type *armor = select_armor(dt, false);
|
const armor_type *armor = select_armor(dt, false);
|
||||||
const armor_type *shield = select_armor(dt, true);
|
const armor_type *shield = select_armor(dt, true);
|
||||||
|
|
||||||
const weapon_type *dwtype = NULL;
|
|
||||||
const weapon_type *awtype = NULL;
|
|
||||||
const weapon *weapon;
|
|
||||||
|
|
||||||
int rda, sk = 0, sd;
|
|
||||||
bool magic = false;
|
|
||||||
int da = dice_rand(damage);
|
|
||||||
|
|
||||||
assert(du->number > 0);
|
|
||||||
++at.fighter->hits;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case AT_STANDARD:
|
|
||||||
weapon = select_weapon(at, true, missile);
|
|
||||||
sk = weapon_effskill(at, dt, weapon, true, missile);
|
|
||||||
if (weapon)
|
|
||||||
awtype = weapon->type;
|
|
||||||
if (awtype && fval(awtype, WTF_MAGICAL))
|
|
||||||
magic = true;
|
|
||||||
break;
|
|
||||||
case AT_NATURAL:
|
|
||||||
sk = weapon_effskill(at, dt, NULL, true, missile);
|
|
||||||
break;
|
|
||||||
case AT_SPELL:
|
|
||||||
case AT_COMBATSPELL:
|
|
||||||
magic = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
weapon = select_weapon(dt, false, true); /* missile=true to get the unmodified best weapon she has */
|
|
||||||
sd = weapon_effskill(dt, at, weapon, false, false);
|
|
||||||
if (weapon != NULL)
|
|
||||||
dwtype = weapon->type;
|
|
||||||
|
|
||||||
if (is_riding(at) && (awtype == NULL || (fval(awtype, WTF_HORSEBONUS)
|
|
||||||
&& !fval(awtype, WTF_MISSILE)))) {
|
|
||||||
da += CavalryBonus(au, dt, BONUS_DAMAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (armor) {
|
if (armor) {
|
||||||
ar += armor->prot;
|
ar += armor->prot;
|
||||||
if (armor->projectile > 0 && chance(armor->projectile)) {
|
if (armor->projectile > 0 && chance(armor->projectile)) {
|
||||||
|
@ -1182,6 +1130,90 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
|
||||||
|
|
||||||
ar += am;
|
ar += am;
|
||||||
|
|
||||||
|
if (magres) {
|
||||||
|
/* magic_resistance gib x% Resistenzbonus zurück */
|
||||||
|
double res = *magres - magic_resistance(du) * 3.0;
|
||||||
|
|
||||||
|
if (u_race(du)->battle_flags & BF_EQUIPMENT) {
|
||||||
|
/* der Effekt von Laen steigt nicht linear */
|
||||||
|
if (armor && fval(armor, ATF_LAEN))
|
||||||
|
res *= (1 - armor->magres);
|
||||||
|
if (shield && fval(shield, ATF_LAEN))
|
||||||
|
res *= (1 - shield->magres);
|
||||||
|
if (dwtype)
|
||||||
|
res *= (1 - dwtype->magres);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gegen Magie wirkt nur natürliche und magische Rüstung */
|
||||||
|
ar = an + am;
|
||||||
|
*magres = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ar;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
terminate(troop dt, troop at, int type, const char *damage, bool missile)
|
||||||
|
{
|
||||||
|
item **pitm;
|
||||||
|
fighter *df = dt.fighter;
|
||||||
|
fighter *af = at.fighter;
|
||||||
|
unit *au = af->unit;
|
||||||
|
unit *du = df->unit;
|
||||||
|
battle *b = df->side->battle;
|
||||||
|
int heiltrank = 0;
|
||||||
|
|
||||||
|
/* Schild */
|
||||||
|
side *ds = df->side;
|
||||||
|
int hp, ar;
|
||||||
|
|
||||||
|
const weapon_type *dwtype = NULL;
|
||||||
|
const weapon_type *awtype = NULL;
|
||||||
|
const weapon *weapon;
|
||||||
|
double res = 0.0;
|
||||||
|
|
||||||
|
int rda, sk = 0, sd;
|
||||||
|
bool magic = false;
|
||||||
|
int da = dice_rand(damage);
|
||||||
|
|
||||||
|
assert(du->number > 0);
|
||||||
|
++at.fighter->hits;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case AT_STANDARD:
|
||||||
|
weapon = select_weapon(at, true, missile);
|
||||||
|
sk = weapon_effskill(at, dt, weapon, true, missile);
|
||||||
|
if (weapon)
|
||||||
|
awtype = weapon->type;
|
||||||
|
if (awtype && fval(awtype, WTF_MAGICAL))
|
||||||
|
magic = true;
|
||||||
|
break;
|
||||||
|
case AT_NATURAL:
|
||||||
|
sk = weapon_effskill(at, dt, NULL, true, missile);
|
||||||
|
break;
|
||||||
|
case AT_SPELL:
|
||||||
|
case AT_COMBATSPELL:
|
||||||
|
magic = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
weapon = select_weapon(dt, false, true); /* missile=true to get the unmodified best weapon she has */
|
||||||
|
sd = weapon_effskill(dt, at, weapon, false, false);
|
||||||
|
if (weapon != NULL)
|
||||||
|
dwtype = weapon->type;
|
||||||
|
|
||||||
|
if (is_riding(at) && (awtype == NULL || (fval(awtype, WTF_HORSEBONUS)
|
||||||
|
&& !fval(awtype, WTF_MISSILE)))) {
|
||||||
|
da += CavalryBonus(au, dt, BONUS_DAMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ar = calculate_armor(dt, dwtype, awtype, magic ? &res : 0);
|
||||||
|
|
||||||
|
if (magic) {
|
||||||
|
da = (int)(_max(da * res, 0));
|
||||||
|
}
|
||||||
|
|
||||||
if (type != AT_COMBATSPELL && type != AT_SPELL) {
|
if (type != AT_COMBATSPELL && type != AT_SPELL) {
|
||||||
if (damage_rules & DAMAGE_CRITICAL) {
|
if (damage_rules & DAMAGE_CRITICAL) {
|
||||||
double kritchance = (sk * 3 - sd) / 200.0;
|
double kritchance = (sk * 3 - sd) / 200.0;
|
||||||
|
@ -1218,30 +1250,6 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (magic) {
|
|
||||||
/* Magischer Schaden durch Spruch oder magische Waffe */
|
|
||||||
double res = 1.0;
|
|
||||||
|
|
||||||
/* magic_resistance gib x% Resistenzbonus zurück */
|
|
||||||
res -= magic_resistance(du) * 3.0;
|
|
||||||
|
|
||||||
if (u_race(du)->battle_flags & BF_EQUIPMENT) {
|
|
||||||
/* der Effekt von Laen steigt nicht linear */
|
|
||||||
if (armor && fval(armor, ATF_LAEN))
|
|
||||||
res *= (1 - armor->magres);
|
|
||||||
if (shield && fval(shield, ATF_LAEN))
|
|
||||||
res *= (1 - shield->magres);
|
|
||||||
if (dwtype)
|
|
||||||
res *= (1 - dwtype->magres);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res > 0) {
|
|
||||||
da = (int)(_max(da * res, 0));
|
|
||||||
}
|
|
||||||
/* gegen Magie wirkt nur natürliche und magische Rüstung */
|
|
||||||
ar = an + am;
|
|
||||||
}
|
|
||||||
|
|
||||||
rda = _max(da - ar, 0);
|
rda = _max(da - ar, 0);
|
||||||
|
|
||||||
if ((u_race(du)->battle_flags & BF_INV_NONMAGIC) && !magic)
|
if ((u_race(du)->battle_flags & BF_INV_NONMAGIC) && !magic)
|
||||||
|
|
|
@ -241,9 +241,10 @@ extern "C" {
|
||||||
extern troop select_ally(struct fighter *af, int minrow, int maxrow,
|
extern troop select_ally(struct fighter *af, int minrow, int maxrow,
|
||||||
int allytype);
|
int allytype);
|
||||||
|
|
||||||
extern int count_enemies(struct battle *b, const struct fighter *af,
|
int count_enemies(struct battle *b, const struct fighter *af,
|
||||||
int minrow, int maxrow, int select);
|
int minrow, int maxrow, int select);
|
||||||
extern bool terminate(troop dt, troop at, int type, const char *damage,
|
int calculate_armor(troop dt, const struct weapon_type *dwtype, const struct weapon_type *awtype, double *magres);
|
||||||
|
bool terminate(troop dt, troop at, int type, const char *damage,
|
||||||
bool missile);
|
bool missile);
|
||||||
extern void message_all(battle * b, struct message *m);
|
extern void message_all(battle * b, struct message *m);
|
||||||
extern int hits(troop at, troop dt, weapon * awp);
|
extern int hits(troop at, troop dt, weapon * awp);
|
||||||
|
|
|
@ -204,6 +204,31 @@ static void test_building_defence_bonus(CuTest * tc)
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_calculate_armor(CuTest * tc)
|
||||||
|
{
|
||||||
|
troop dt;
|
||||||
|
battle *b;
|
||||||
|
region *r;
|
||||||
|
unit *du;
|
||||||
|
side *ds;
|
||||||
|
fighter *df;
|
||||||
|
weapon_type *awtype = 0, *dwtype = 0;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
r = test_create_region(0, 0, 0);
|
||||||
|
du = test_create_unit(test_create_faction(NULL), r);
|
||||||
|
|
||||||
|
b = make_battle(r);
|
||||||
|
ds = make_side(b, du->faction, 0, 0, 0);
|
||||||
|
df = make_fighter(b, du, ds, false);
|
||||||
|
dt.fighter = df;
|
||||||
|
dt.index = 0;
|
||||||
|
result = calculate_armor(dt, dwtype, awtype, 0);
|
||||||
|
CuAssertIntEquals(tc, 0, result);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_battle_suite(void)
|
CuSuite *get_battle_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
@ -212,5 +237,6 @@ CuSuite *get_battle_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_attackers_get_no_building_bonus);
|
SUITE_ADD_TEST(suite, test_attackers_get_no_building_bonus);
|
||||||
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);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue