From 89b3b3161f63915538816a581f8c20192cbd9ee1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 12 Mar 2011 17:01:20 -0800 Subject: [PATCH] Add a test for the effect of buildings in battles, and a file to test pieces of the combat code from C in the future. Add some testing support for terrains and buildings. --- src/gamecode/market_test.c | 5 +-- src/kernel.vcxproj | 1 + src/kernel.vcxproj.filters | 3 ++ src/kernel/battle.c | 20 ++++++------ src/kernel/battle.h | 10 ++++-- src/kernel/battle_test.c | 64 ++++++++++++++++++++++++++++++++++++++ src/tests.c | 50 +++++++++++++++++++---------- src/tests.h | 2 ++ 8 files changed, 122 insertions(+), 33 deletions(-) create mode 100644 src/kernel/battle_test.c diff --git a/src/gamecode/market_test.c b/src/gamecode/market_test.c index edf27b2bb..b697ccc53 100644 --- a/src/gamecode/market_test.c +++ b/src/gamecode/market_test.c @@ -29,10 +29,7 @@ static void market_curse(CuTest * tc) btype->_name = "market"; bt_register(btype); - terrain = calloc(1, sizeof(terrain_type)); - terrain->_name = strdup("plain"); - register_terrain(terrain); - terrain->flags = LAND_REGION | WALK_INTO; + terrain = test_create_terrain("plain", LAND_REGION | WALK_INTO); for (x = 0; x != 3; ++x) { for (y = 0; y != 3; ++y) { diff --git a/src/kernel.vcxproj b/src/kernel.vcxproj index 1cce4c98b..81ea82887 100644 --- a/src/kernel.vcxproj +++ b/src/kernel.vcxproj @@ -90,6 +90,7 @@ + diff --git a/src/kernel.vcxproj.filters b/src/kernel.vcxproj.filters index 566a12419..caadb2064 100644 --- a/src/kernel.vcxproj.filters +++ b/src/kernel.vcxproj.filters @@ -295,6 +295,9 @@ kernel + + kernel + diff --git a/src/kernel/battle.c b/src/kernel/battle.c index 2a7356a7c..5e8e83cda 100644 --- a/src/kernel/battle.c +++ b/src/kernel/battle.c @@ -1892,7 +1892,7 @@ static void do_extra_spell(troop at, const att * a) } } -static int skilldiff(troop at, troop dt, int dist) +int skilldiff(troop at, troop dt, int dist) { fighter *af = at.fighter, *df = dt.fighter; unit *au = af->unit, *du = df->unit; @@ -2442,7 +2442,7 @@ double fleechance(unit * u) /** add a new army to the conflict * beware: armies need to be added _at the beginning_ of the list because * otherwise join_allies() will get into trouble */ -static side *make_side(battle * b, const faction * f, const group * g, +side *make_side(battle * b, const faction * f, const group * g, unsigned int flags, const faction * stealthfaction) { side *s1 = b->sides + b->nsides; @@ -3656,13 +3656,18 @@ static const char *simplename(region * r) return name; } -static battle *make_battle(region * r) +battle *make_battle(region * r) { - battle *b = calloc(1, sizeof(struct battle)); + battle *b = (battle *)calloc(1, sizeof(battle)); unit *u; bfaction *bf; + building * bld; static int max_fac_no = 0; /* need this only once */ + /* Alle Mann raus aus der Burg! */ + for (bld = r->buildings; bld != NULL; bld = bld->next) + bld->sizeleft = bld->size; + if (battledebug) { char zText[MAX_PATH]; char zFilename[MAX_PATH]; @@ -3693,7 +3698,7 @@ static battle *make_battle(region * r) break; } if (!bf) { - bf = calloc(sizeof(bfaction), 1); + bf = (bfaction *)calloc(sizeof(bfaction), 1); ++b->nfactions; bf->faction = u->faction; bf->next = b->factions; @@ -4062,11 +4067,6 @@ static boolean init_battle(region * r, battle ** bp) battle *b = NULL; unit *u; boolean fighting = false; - building *bu; - - /* Alle Mann raus aus der Burg! */ - for (bu = r->buildings; bu != NULL; bu = bu->next) - bu->sizeleft = bu->size; /* list_foreach geht nicht, wegen flucht */ for (u = r->units; u != NULL; u = u->next) { diff --git a/src/kernel/battle.h b/src/kernel/battle.h index 46cd3c4ce..b7fbf9f2f 100644 --- a/src/kernel/battle.h +++ b/src/kernel/battle.h @@ -261,14 +261,20 @@ extern "C" { extern struct region *fleeregion(const struct unit *u); #endif extern struct fighter *select_corpse(struct battle *b, struct fighter *af); - extern fighter *make_fighter(struct battle *b, struct unit *u, side * s, - boolean attack); extern int statusrow(int status); extern void drain_exp(struct unit *u, int d); extern void kill_troop(troop dt); extern void remove_troop(troop dt); /* not the same as the badly named rmtroop */ extern boolean is_attacker(const fighter * fig); + extern struct battle *make_battle(struct region * r); + extern fighter *make_fighter(struct battle *b, struct unit *u, side * s, + boolean attack); + extern struct side *make_side(struct battle * b, const struct faction * f, + const struct group * g, unsigned int flags, + const struct faction * stealthfaction); + extern int skilldiff(troop at, troop dt, int dist); + #ifdef __cplusplus } #endif diff --git a/src/kernel/battle_test.c b/src/kernel/battle_test.c new file mode 100644 index 000000000..34d9c9913 --- /dev/null +++ b/src/kernel/battle_test.c @@ -0,0 +1,64 @@ +#include +#include +#include "battle.h" +#include "building.h" +#include "faction.h" +#include "race.h" +#include "region.h" +#include "unit.h" +#include "tests.h" +#include + +static int add_two(building * b, unit * u) { + return 2; +} + +static void test_building_bonus(CuTest * tc) +{ + unit *du, *au; + region *r; + building * bld; + fighter *df, *af; + battle *b; + side *ds, *as; + int diff; + troop dt, at; + building_type * btype; + + test_cleanup(); + test_create_world(); + r = findregion(0, 0); + btype = bt_find("castle"); + btype->protection = &add_two; + bld = test_create_building(r, btype); + bld->size = 10; + + du = test_create_unit(test_create_faction(rc_find("human")), r); + du->building = bld; + + au = test_create_unit(test_create_faction(rc_find("human")), r); + + b = make_battle(r); + ds = make_side(b, du->faction, 0, 0, 0); + df = make_fighter(b, du, ds, false); + CuAssertPtrEquals(tc, bld, df->building); + + as = make_side(b, au->faction, 0, 0, 0); + af = make_fighter(b, au, as, true); + CuAssertPtrEquals(tc, 0, af->building); + + dt.fighter = df; + dt.index = 0; + at.fighter = af; + at.index = 0; + + diff = skilldiff(at, dt, 0); + CuAssertIntEquals(tc, -2, diff); +} + +CuSuite *get_battle_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_building_bonus); + return suite; +} diff --git a/src/tests.c b/src/tests.c index d736a7444..7224b4dbf 100644 --- a/src/tests.c +++ b/src/tests.c @@ -8,6 +8,7 @@ #include #include #include +#include #include CuSuite *get_market_suite(void); @@ -20,6 +21,8 @@ CuSuite *get_market_suite(void); #include #include #include +#include +#include #include int RunAllTests(void) @@ -37,6 +40,7 @@ int RunAllTests(void) CuSuiteAddSuite(suite, get_market_suite()); CuSuiteAddSuite(suite, get_move_suite()); CuSuiteAddSuite(suite, get_laws_suite()); + CuSuiteAddSuite(suite, get_battle_suite()); CuSuiteRun(suite); CuSuiteSummary(suite, output); @@ -49,12 +53,13 @@ int RunAllTests(void) struct race *test_create_race(const char *name) { - race *rc = rc_add(rc_new("human")); + race *rc = rc_add(rc_new(name)); + rc->flags |= RCF_PLAYERRACE; + rc->maintenance = 10; return rc; } -struct region *test_create_region(int x, int y, - const struct terrain_type *terrain) +struct region *test_create_region(int x, int y, const terrain_type *terrain) { region *r = new_region(x, y, NULL, 0); terraform_region(r, terrain); @@ -80,11 +85,31 @@ struct unit *test_create_unit(struct faction *f, struct region *r) void test_cleanup(void) { + test_clear_terrains(); global.functions.maintenance = NULL; global.functions.wage = NULL; free_gamedata(); } +terrain_type * +test_create_terrain(const char * name, unsigned int flags) +{ + terrain_type * t; + + assert(!get_terrain(name)); + t = (terrain_type*)calloc(1, sizeof(terrain_type)); + t->_name = strdup(name); + t->flags = flags; + register_terrain(t); + return t; +} + +building * test_create_building(region * r, const building_type * btype) +{ + building * b = new_building(btype, r, default_locale); + b->size = btype->maxsize>0?btype->maxsize:1; + return b; +} /** creates a small world and some stuff in it. * two terrains: 'plain' and 'ocean' * one race: 'human' @@ -101,15 +126,8 @@ void test_create_world(void) building_type *btype; ship_type *stype; - t_plain = (terrain_type*)calloc(1, sizeof(terrain_type)); - t_plain->_name = strdup("plain"); - t_plain->flags = LAND_REGION | FOREST_REGION | WALK_INTO; - register_terrain(t_plain); - - t_ocean = (terrain_type*)calloc(1, sizeof(terrain_type)); - t_ocean->_name = strdup("ocean"); - t_ocean->flags = SEA_REGION | SAIL_INTO | SWIM_INTO; - register_terrain(t_ocean); + t_plain = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO); + t_ocean = test_create_terrain("ocean", SEA_REGION | SAIL_INTO | SWIM_INTO); island[0] = test_create_region(0, 0, t_plain); island[1] = test_create_region(1, 0, t_plain); @@ -124,17 +142,15 @@ void test_create_world(void) } } - rc_human = rc_add(rc_new("human")); - rc_human->maintenance = 10; + rc_human = test_create_race("human"); - btype = calloc(sizeof(building_type), 1); + btype = (building_type*)calloc(sizeof(building_type), 1); btype->flags = BTF_NAMECHANGE; btype->_name = strdup("castle"); bt_register(btype); - stype = calloc(sizeof(ship_type), 1); + stype = (ship_type*)calloc(sizeof(ship_type), 1); stype->name[0] = strdup("boat"); stype->name[1] = strdup("boat_p"); st_register(stype); - } diff --git a/src/tests.h b/src/tests.h index 51ee4aecb..01cef3516 100644 --- a/src/tests.h +++ b/src/tests.h @@ -5,12 +5,14 @@ extern "C" { #ifndef DISABLE_TESTS void test_cleanup(void); + struct terrain_type * test_create_terrain(const char * name, unsigned int flags); struct race *test_create_race(const char *name); struct region *test_create_region(int x, int y, const struct terrain_type *terrain); struct faction *test_create_faction(const struct race *rc); struct unit *test_create_unit(struct faction *f, struct region *r); void test_create_world(void); + struct building * test_create_building(struct region * r, const struct building_type * btype); int RunAllTests(void); #else