From 8ddca8ab0e4dcd1980ae217caaaf8ea1242a82b6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 25 Aug 2019 15:14:21 +0200 Subject: [PATCH] Bug 2458 strikes again: wrong insect warning. simplify calendar code, add tests. --- src/bindings.c | 7 +++---- src/economy.c | 6 +----- src/economy.test.c | 8 +++++--- src/kernel/calendar.c | 9 +++++++- src/kernel/calendar.h | 18 ++++++++-------- src/kernel/calendar.test.c | 42 ++++++++++++++++++++++++++++++++++---- src/kernel/save.c | 1 - src/laws.c | 16 ++++----------- src/recruit.c | 15 +++++++------- src/reports.c | 10 ++++----- src/tests.c | 2 +- 11 files changed, 83 insertions(+), 51 deletions(-) diff --git a/src/bindings.c b/src/bindings.c index c46c0e80e..5cb758175 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -259,10 +259,9 @@ static int tolua_dice_rand(lua_State * L) static int tolua_get_season(lua_State * L) { - int turnno = (int)tolua_tonumber(L, 1, 0); - gamedate gd; - get_gamedate(turnno, &gd); - tolua_pushstring(L, seasonnames[gd.season]); + int turn_no = (int)tolua_tonumber(L, 1, 0); + season_t season = calendar_season(turn_no); + tolua_pushstring(L, seasonnames[season]); return 1; } diff --git a/src/economy.c b/src/economy.c index 829b205a1..ecbd27db0 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1758,12 +1758,8 @@ static void breedtrees(unit * u, int raw) { int n, i, skill, planted = 0; const resource_type *rtype; - int current_season; + season_t current_season = calendar_season(turn); region *r = u->region; - gamedate date; - - get_gamedate(turn, &date); - current_season = date.season; /* Baeume zuechten geht nur im Fruehling */ if (current_season != SEASON_SPRING) { diff --git a/src/economy.test.c b/src/economy.test.c index 024ccadbd..f4fe84340 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -5,10 +5,11 @@ #include "economy.h" #include "recruit.h" -#include +#include #include -#include +#include #include +#include #include #include #include @@ -20,9 +21,9 @@ #include #include -#include #include #include +#include #include #include @@ -494,6 +495,7 @@ static void test_recruit_insect(CuTest *tc) { u = test_create_unit(f, test_create_region(0, 0, NULL)); u->thisorder = create_order(K_RECRUIT, f->locale, "%d", 1); + CuAssertIntEquals(tc, SEASON_AUTUMN, calendar_season(1083)); msg = can_recruit(u, f->race, u->thisorder, 1083); /* Autumn */ CuAssertPtrEquals(tc, NULL, msg); diff --git a/src/kernel/calendar.c b/src/kernel/calendar.c index e028580ff..849664093 100644 --- a/src/kernel/calendar.c +++ b/src/kernel/calendar.c @@ -18,7 +18,7 @@ int months_per_year = 12; const char *seasonnames[CALENDAR_SEASONS] = { "winter", "spring", "summer", "fall" }; char **weeknames = NULL; char **weeknames2 = NULL; -int *month_season = NULL; +season_t *month_season = NULL; const char *calendar_month(int index) { @@ -27,6 +27,13 @@ const char *calendar_month(int index) return result; } +season_t calendar_season(int now) { + gamedate date; + get_gamedate(now, &date); + + return date.season; +} + const char *calendar_era(void) { static char result[20]; diff --git a/src/kernel/calendar.h b/src/kernel/calendar.h index 164a96bf4..d1a82f037 100644 --- a/src/kernel/calendar.h +++ b/src/kernel/calendar.h @@ -5,12 +5,12 @@ extern "C" { #endif - enum { + typedef enum season_t { SEASON_WINTER, SEASON_SPRING, SEASON_SUMMER, SEASON_AUTUMN - }; + } season_t; #define CALENDAR_SEASONS 4 extern const char *seasonnames[CALENDAR_SEASONS]; @@ -26,16 +26,18 @@ extern "C" { typedef struct gamedate { int turn; int year; - int season; + season_t season; int month; int week; } gamedate; -const gamedate *get_gamedate(int turn, gamedate * gd); -void calendar_cleanup(void); -const char *calendar_month(int index); -const char *calendar_era(void); -int first_turn(void); + const gamedate *get_gamedate(int turn, gamedate * gd); + season_t calendar_season(int turn); + + void calendar_cleanup(void); + const char *calendar_month(int index); + const char *calendar_era(void); + int first_turn(void); #ifdef __cplusplus } diff --git a/src/kernel/calendar.test.c b/src/kernel/calendar.test.c index 6e1edf5b6..1a951efb3 100644 --- a/src/kernel/calendar.test.c +++ b/src/kernel/calendar.test.c @@ -65,26 +65,59 @@ static void test_calendar(CuTest * tc) test_teardown(); } +static void setup_calendar() { + int i; + + months_per_year = 4; + weeks_per_month = 2; + free(month_season); + month_season = calloc(months_per_year, sizeof(int)); + for (i = 0; i != 4; ++i) { + month_season[i] = (season_t)i; + } +} + static void test_calendar_season(CuTest * tc) +{ + test_setup(); + setup_calendar(); + + CuAssertIntEquals(tc, SEASON_WINTER, calendar_season(0)); + CuAssertIntEquals(tc, SEASON_WINTER, calendar_season(1)); + CuAssertIntEquals(tc, SEASON_SPRING, calendar_season(2)); + CuAssertIntEquals(tc, SEASON_SPRING, calendar_season(3)); + CuAssertIntEquals(tc, SEASON_SUMMER, calendar_season(4)); + CuAssertIntEquals(tc, SEASON_SUMMER, calendar_season(5)); + CuAssertIntEquals(tc, SEASON_AUTUMN, calendar_season(6)); + CuAssertIntEquals(tc, SEASON_AUTUMN, calendar_season(7)); + CuAssertIntEquals(tc, SEASON_WINTER, calendar_season(8)); + + free(month_season); + month_season = NULL; + test_teardown(); +} + +static void test_gamedate(CuTest * tc) { gamedate gd; test_setup(); - month_season = calloc(months_per_year, sizeof(int)); + setup_calendar(); get_gamedate(0, &gd); CuAssertIntEquals(tc, 1, gd.year); - CuAssertIntEquals(tc, 0, gd.season); + CuAssertIntEquals(tc, SEASON_WINTER, gd.season); CuAssertIntEquals(tc, 0, gd.month); CuAssertIntEquals(tc, 0, gd.week); - month_season[1] = 1; get_gamedate(weeks_per_month + 1, &gd); CuAssertIntEquals(tc, 1, gd.year); - CuAssertIntEquals(tc, 1, gd.season); + CuAssertIntEquals(tc, SEASON_SPRING, gd.season); CuAssertIntEquals(tc, 1, gd.month); CuAssertIntEquals(tc, 1, gd.week); + free(month_season); + month_season = NULL; test_teardown(); } @@ -94,5 +127,6 @@ CuSuite *get_calendar_suite(void) SUITE_ADD_TEST(suite, test_calendar_config); SUITE_ADD_TEST(suite, test_calendar); SUITE_ADD_TEST(suite, test_calendar_season); + SUITE_ADD_TEST(suite, test_gamedate); return suite; } diff --git a/src/kernel/save.c b/src/kernel/save.c index 43699391e..9b4a30236 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -630,7 +630,6 @@ static void fix_resource_levels(region *r) { } } } - } } diff --git a/src/laws.c b/src/laws.c index 36d914cde..113cd6252 100644 --- a/src/laws.c +++ b/src/laws.c @@ -613,7 +613,7 @@ growing_trees_e3(region * r, const int current_season, } static void -growing_trees(region * r, const int current_season, const int last_weeks_season) +growing_trees(region * r, const season_t current_season, const season_t last_weeks_season) { int grownup_trees, i, seeds, sprout; attrib *a; @@ -755,7 +755,7 @@ growing_trees(region * r, const int current_season, const int last_weeks_season) } static void -growing_herbs(region * r, const int current_season, const int last_weeks_season) +growing_herbs(region * r, const int current_season, const season_t last_weeks_season) { /* Jetzt die Kraeutervermehrung. Vermehrt wird logistisch: * @@ -849,20 +849,12 @@ void nmr_warnings(void) void demographics(void) { region *r; - static int last_weeks_season = -1; - static int current_season = -1; int plant_rules = config_get_int("rules.grow.formula", 2); int horse_rules = config_get_int("rules.horses.growth", 1); int peasant_rules = config_get_int("rules.peasants.growth", 1); const struct building_type *bt_harbour = bt_find("harbour"); - - if (current_season < 0) { - gamedate date; - get_gamedate(turn, &date); - current_season = date.season; - get_gamedate(turn - 1, &date); - last_weeks_season = date.season; - } + season_t current_season = calendar_season(turn); + season_t last_weeks_season = calendar_season(turn - 1); for (r = regions; r; r = r->next) { ++r->age; /* also oceans. no idea why we didn't always do that */ diff --git a/src/recruit.c b/src/recruit.c index 541202f08..2dc3eb526 100644 --- a/src/recruit.c +++ b/src/recruit.c @@ -351,9 +351,14 @@ message *can_recruit(unit *u, const race *rc, order *ord, int now) } if (rc == get_race(RC_INSECT)) { - gamedate date; - get_gamedate(now, &date); - if (date.season == SEASON_WINTER && r->terrain != newterrain(T_DESERT)) { + + /* in Gletschern, Eisbergen gar nicht rekrutieren */ + if (r_insectstalled(r)) { + return msg_error(u, ord, 97); + } + + /* in Wüsten ganzjährig rekrutieren, sonst im Winter nur mit Trank */ + if (r->terrain != newterrain(T_DESERT) && calendar_season(now) == SEASON_WINTER) { bool usepotion = false; unit *u2; @@ -367,10 +372,6 @@ message *can_recruit(unit *u, const race *rc, order *ord, int now) 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 */ diff --git a/src/reports.c b/src/reports.c index aa49c4653..7a3271b71 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1466,14 +1466,14 @@ void report_warnings(faction *f, int now) } if (f->race == get_race(RC_INSECT)) { - gamedate date; - get_gamedate(now + 1, &date); + season_t season = calendar_season(now + 1); - if (date.season == SEASON_WINTER) { + if (season == SEASON_WINTER) { ADDMSG(&f->msgs, msg_message("nr_insectwinter", "")); } - else if (date.season == SEASON_AUTUMN) { - if (get_gamedate(now + 2 + 2, &date)->season == SEASON_WINTER) { + else if (season == SEASON_AUTUMN) { + /* warning: next turn is the last week of autumn */ + if (calendar_season(now + 2) == SEASON_WINTER) { ADDMSG(&f->msgs, msg_message("nr_insectfall", "")); } } diff --git a/src/tests.c b/src/tests.c index 5a13c97da..c0350a9de 100644 --- a/src/tests.c +++ b/src/tests.c @@ -277,7 +277,7 @@ 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 = malloc(sizeof(season_t) * months_per_year); if (!month_season) abort(); month_season[0] = SEASON_SUMMER; month_season[1] = SEASON_AUTUMN;