forked from github/server
Refactor: extract can_recruit, write tests for insects.
This commit is contained in:
parent
3880960acf
commit
8d88579570
152
src/economy.c
152
src/economy.c
|
@ -426,6 +426,59 @@ static int recruit_cost(const faction * f, const race * rc)
|
|||
return -1;
|
||||
}
|
||||
|
||||
message *can_recruit(unit *u, const race *rc, order *ord, int now)
|
||||
{
|
||||
region *r = u->region;
|
||||
|
||||
/* this is a very special case because the recruiting unit may be empty
|
||||
* at this point and we have to look at the creating unit instead. This
|
||||
* is done in cansee, which is called indirectly by is_guarded(). */
|
||||
if (is_guarded(r, u)) {
|
||||
return msg_error(u, ord, 70);
|
||||
}
|
||||
|
||||
if (rc == get_race(RC_INSECT)) {
|
||||
gamedate date;
|
||||
get_gamedate(now, &date);
|
||||
if (date.season == SEASON_WINTER && r->terrain != newterrain(T_DESERT)) {
|
||||
bool usepotion = false;
|
||||
unit *u2;
|
||||
|
||||
for (u2 = r->units; u2; u2 = u2->next) {
|
||||
if (fval(u2, UFL_WARMTH)) {
|
||||
usepotion = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!usepotion) {
|
||||
return msg_error(u, ord, 98);
|
||||
}
|
||||
}
|
||||
/* in Gletschern, Eisbergen gar nicht rekrutieren */
|
||||
if (r_insectstalled(r)) {
|
||||
return msg_error(u, ord, 97);
|
||||
}
|
||||
}
|
||||
if (is_cursed(r->attribs, &ct_riotzone)) {
|
||||
/* Die Region befindet sich in Aufruhr */
|
||||
return msg_error(u, ord, 237);
|
||||
}
|
||||
|
||||
if (rc && !playerrace(rc)) {
|
||||
return msg_error(u, ord, 139);
|
||||
}
|
||||
|
||||
if (fval(u, UFL_HERO)) {
|
||||
return msg_feedback(u, ord, "error_herorecruit", "");
|
||||
}
|
||||
if (has_skill(u, SK_MAGIC)) {
|
||||
/* error158;de;{unit} in {region}: '{command}' - Magier arbeiten
|
||||
* grunds<EFBFBD>tzlich nur alleine! */
|
||||
return msg_error(u, ord, 158);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void recruit(unit * u, struct order *ord, econ_request ** recruitorders)
|
||||
{
|
||||
region *r = u->region;
|
||||
|
@ -434,6 +487,7 @@ static void recruit(unit * u, struct order *ord, econ_request ** recruitorders)
|
|||
const faction *f = u->faction;
|
||||
const struct race *rc = u_race(u);
|
||||
int n;
|
||||
message *msg;
|
||||
|
||||
init_order_depr(ord);
|
||||
n = getint();
|
||||
|
@ -456,6 +510,7 @@ static void recruit(unit * u, struct order *ord, econ_request ** recruitorders)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recruitcost < 0) {
|
||||
rc = u_race(u);
|
||||
recruitcost = recruit_cost(f, rc);
|
||||
|
@ -463,95 +518,46 @@ static void recruit(unit * u, struct order *ord, econ_request ** recruitorders)
|
|||
recruitcost = INT_MAX;
|
||||
}
|
||||
}
|
||||
assert(rc);
|
||||
u_setrace(u, rc);
|
||||
|
||||
/* this is a very special case because the recruiting unit may be empty
|
||||
* at this point and we have to look at the creating unit instead. This
|
||||
* is done in cansee, which is called indirectly by is_guarded(). */
|
||||
if (is_guarded(r, u)) {
|
||||
cmistake(u, ord, 70, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == get_race(RC_INSECT)) {
|
||||
gamedate date;
|
||||
get_gamedate(turn, &date);
|
||||
if (date.season == SEASON_WINTER && r->terrain != newterrain(T_DESERT)) {
|
||||
bool usepotion = false;
|
||||
unit *u2;
|
||||
|
||||
for (u2 = r->units; u2; u2 = u2->next)
|
||||
if (fval(u2, UFL_WARMTH)) {
|
||||
usepotion = true;
|
||||
break;
|
||||
}
|
||||
if (!usepotion)
|
||||
{
|
||||
cmistake(u, ord, 98, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* in Gletschern, Eisbergen gar nicht rekrutieren */
|
||||
if (r_insectstalled(r)) {
|
||||
cmistake(u, ord, 97, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (is_cursed(r->attribs, &ct_riotzone)) {
|
||||
/* Die Region befindet sich in Aufruhr */
|
||||
cmistake(u, ord, 237, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (recruitcost) {
|
||||
if (recruitcost > 0) {
|
||||
int pool;
|
||||
plane *pl = getplane(r);
|
||||
if (pl && fval(pl, PFL_NORECRUITS)) {
|
||||
|
||||
if (pl && (pl->flags & PFL_NORECRUITS)) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_pflnorecruit", ""));
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT,
|
||||
recruitcost) < recruitcost) {
|
||||
pool = get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, recruitcost * n);
|
||||
if (pool < recruitcost) {
|
||||
cmistake(u, ord, 142, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
pool /= recruitcost;
|
||||
if (n > pool) n = pool;
|
||||
}
|
||||
if (!playerrace(rc)) {
|
||||
cmistake(u, ord, 139, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fval(u, UFL_HERO)) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_herorecruit", ""));
|
||||
return;
|
||||
}
|
||||
if (has_skill(u, SK_MAGIC)) {
|
||||
/* error158;de;{unit} in {region}: '{command}' - Magier arbeiten
|
||||
* grunds<EFBFBD>tzlich nur alleine! */
|
||||
cmistake(u, ord, 158, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
if (has_skill(u, SK_ALCHEMY)
|
||||
&& count_skill(u->faction, SK_ALCHEMY) + n >
|
||||
skill_limit(u->faction, SK_ALCHEMY)) {
|
||||
cmistake(u, ord, 156, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
if (recruitcost > 0) {
|
||||
int pooled =
|
||||
get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, recruitcost * n);
|
||||
int pr = pooled / recruitcost;
|
||||
if (n > pr) n = pr;
|
||||
}
|
||||
|
||||
u->wants = n;
|
||||
|
||||
if (!n) {
|
||||
cmistake(u, ord, 142, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
if (has_skill(u, SK_ALCHEMY)) {
|
||||
if (count_skill(u->faction, SK_ALCHEMY) + n > skill_limit(u->faction, SK_ALCHEMY)) {
|
||||
cmistake(u, ord, 156, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(rc);
|
||||
msg = can_recruit(u, rc, ord, turn);
|
||||
if (msg) {
|
||||
add_message(&u->faction->msgs, msg);
|
||||
msg_release(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
u_setrace(u, rc);
|
||||
u->wants = n;
|
||||
o = (econ_request *)calloc(1, sizeof(econ_request));
|
||||
o->qty = n;
|
||||
o->unit = u;
|
||||
|
|
|
@ -44,6 +44,7 @@ extern "C" {
|
|||
#define MAXNEWBIES 5
|
||||
|
||||
struct unit;
|
||||
struct race;
|
||||
struct region;
|
||||
struct faction;
|
||||
struct order;
|
||||
|
@ -94,6 +95,7 @@ extern "C" {
|
|||
void steal_cmd(struct unit * u, struct order *ord, struct econ_request ** stealorders);
|
||||
void expandstealing(struct region * r, struct econ_request * stealorders);
|
||||
|
||||
struct message *can_recruit(struct unit *u, const struct race *rc, struct order *ord, int now);
|
||||
void add_recruits(struct unit * u, int number, int wanted);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -480,6 +480,35 @@ static void test_recruit(CuTest *tc) {
|
|||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_recruit_insect(CuTest *tc) {
|
||||
unit *u;
|
||||
faction *f;
|
||||
message * msg;
|
||||
|
||||
test_setup();
|
||||
test_create_calendar();
|
||||
f = test_create_faction(test_create_race("insect"));
|
||||
u = test_create_unit(f, test_create_region(0, 0, NULL));
|
||||
u->thisorder = create_order(K_RECRUIT, f->locale, "%d", 1);
|
||||
|
||||
msg = can_recruit(u, f->race, u->thisorder, 1083); /* Autumn */
|
||||
CuAssertPtrEquals(tc, NULL, msg);
|
||||
|
||||
msg = can_recruit(u, f->race, u->thisorder, 1084); /* Insects, Winter */
|
||||
CuAssertPtrNotNull(tc, msg);
|
||||
msg_release(msg);
|
||||
|
||||
u->flags |= UFL_WARMTH;
|
||||
msg = can_recruit(u, f->race, u->thisorder, 1084); /* Insects, potion, Winter */
|
||||
CuAssertPtrEquals(tc, NULL, msg);
|
||||
|
||||
u->flags = 0;
|
||||
msg = can_recruit(u, NULL, u->thisorder, 1084); /* Other races, Winter */
|
||||
CuAssertPtrEquals(tc, NULL, msg);
|
||||
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_income(CuTest *tc)
|
||||
{
|
||||
race *rc;
|
||||
|
@ -764,6 +793,7 @@ CuSuite *get_economy_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_trade_insect);
|
||||
SUITE_ADD_TEST(suite, test_maintain_buildings);
|
||||
SUITE_ADD_TEST(suite, test_recruit);
|
||||
SUITE_ADD_TEST(suite, test_recruit_insect);
|
||||
SUITE_ADD_TEST(suite, test_loot);
|
||||
SUITE_ADD_TEST(suite, test_expand_production);
|
||||
return suite;
|
||||
|
|
|
@ -785,27 +785,12 @@ static void test_stealth_modifier(CuTest *tc) {
|
|||
test_teardown();
|
||||
}
|
||||
|
||||
static void setup_calendar(void) {
|
||||
months_per_year = 9;
|
||||
month_season = malloc(sizeof(int) * months_per_year);
|
||||
month_season[0] = SEASON_SUMMER;
|
||||
month_season[1] = SEASON_AUTUMN;
|
||||
month_season[2] = SEASON_AUTUMN;
|
||||
month_season[3] = SEASON_WINTER;
|
||||
month_season[4] = SEASON_WINTER;
|
||||
month_season[5] = SEASON_WINTER;
|
||||
month_season[6] = SEASON_SPRING;
|
||||
month_season[7] = SEASON_SPRING;
|
||||
month_season[8] = SEASON_SUMMER;
|
||||
}
|
||||
|
||||
static void test_insect_warnings(CuTest *tc) {
|
||||
faction *f;
|
||||
gamedate gd;
|
||||
|
||||
test_setup();
|
||||
setup_calendar();
|
||||
config_set_int("game.start", 184);
|
||||
test_create_calendar();
|
||||
test_inject_messagetypes();
|
||||
f = test_create_faction(test_create_race("insect"));
|
||||
|
||||
|
|
15
src/tests.c
15
src/tests.c
|
@ -260,6 +260,21 @@ static void test_reset(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void test_create_calendar(void) {
|
||||
config_set_int("game.start", 184);
|
||||
months_per_year = 9;
|
||||
month_season = malloc(sizeof(int) * months_per_year);
|
||||
month_season[0] = SEASON_SUMMER;
|
||||
month_season[1] = SEASON_AUTUMN;
|
||||
month_season[2] = SEASON_AUTUMN;
|
||||
month_season[3] = SEASON_WINTER;
|
||||
month_season[4] = SEASON_WINTER;
|
||||
month_season[5] = SEASON_WINTER;
|
||||
month_season[6] = SEASON_SPRING;
|
||||
month_season[7] = SEASON_SPRING;
|
||||
month_season[8] = SEASON_SUMMER;
|
||||
}
|
||||
|
||||
void test_inject_messagetypes(void)
|
||||
{
|
||||
message_handle_missing(MESSAGE_MISSING_REPLACE);
|
||||
|
|
|
@ -40,6 +40,7 @@ extern "C" {
|
|||
struct log_t * test_log_start(int flags, struct strlist **slist);
|
||||
void test_log_stop(struct log_t *log, struct strlist *slist);
|
||||
|
||||
void test_create_calendar(void);
|
||||
struct locale * test_create_locale(void);
|
||||
struct terrain_type * test_create_terrain(const char * name, int flags);
|
||||
struct race *test_create_race(const char *name);
|
||||
|
|
Loading…
Reference in New Issue