diff --git a/src/kernel/config.c b/src/kernel/config.c index ece8ca72f..8698fde51 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -1681,6 +1681,11 @@ void kernel_init(void) } static order * defaults[MAXLOCALES]; +keyword_t default_keyword = NOKEYWORD; + +void set_default_order(int kwd) { + default_keyword = (keyword_t)kwd; +} order *default_order(const struct locale *lang) { @@ -1688,6 +1693,11 @@ order *default_order(const struct locale *lang) int i = locale_index(lang); order *result = 0; assert(i < MAXLOCALES); + + if (default_keyword!=NOKEYWORD) { + return create_order(default_keyword, lang, 0); + } + result = defaults[i]; if (!result && usedefault) { const char * str = LOC(lang, "defaultorder"); diff --git a/src/kernel/config.h b/src/kernel/config.h index 62fa2d4d6..5e7e77899 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -286,7 +286,10 @@ extern "C" { int AllianceAuto(void); /* flags that allied factions get automatically */ int AllianceRestricted(void); /* flags restricted to allied factions */ int HelpMask(void); /* flags restricted to allied factions */ + struct order *default_order(const struct locale *lang); + void set_default_order(int kwd); + int entertainmoney(const struct region *r); void free_gamedata(void); diff --git a/src/kernel/order.c b/src/kernel/order.c index 08d16088f..008bfe0fe 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -252,6 +252,19 @@ static order_data *create_data(keyword_t kwd, const char *sptr, int lindex) return data; } +static void free_localedata(int lindex) { + int i; + for (i = 0; i != MAXKEYWORDS; ++i) { + release_data(locale_array[lindex]->short_orders[i]); + locale_array[lindex]->short_orders[i] = 0; + } + for (i = 0; i != MAXSKILLS; ++i) { + release_data(locale_array[lindex]->study_orders[i]); + locale_array[lindex]->study_orders[i] = 0; + } + locale_array[lindex]->lang = 0; +} + static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent, const struct locale *lang) { @@ -276,7 +289,12 @@ static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent, lindex = locale_index(lang); assert(lindex < MAXLOCALES); - locale_array[lindex] = (locale_data *)calloc(1, sizeof(locale_data)); + if (!locale_array[lindex]) { + locale_array[lindex] = (locale_data *)calloc(1, sizeof(locale_data)); + } + else if (locale_array[lindex]->lang != lang) { + free_localedata(lindex); + } locale_array[lindex]->lang = lang; ord = (order *)malloc(sizeof(order)); @@ -292,13 +310,13 @@ order *create_order(keyword_t kwd, const struct locale * lang, const char *params, ...) { char zBuffer[DISPLAYSIZE]; - assert(lang); if (params) { char *bufp = zBuffer; int bytes; size_t size = sizeof(zBuffer) - 1; va_list marker; + assert(lang); va_start(marker, params); while (*params) { if (*params == '%') { diff --git a/src/laws.test.c b/src/laws.test.c index b6b13d37c..900336d5c 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -768,22 +768,146 @@ static void test_luck_message(CuTest *tc) { test_cleanup(); } -static void test_update_long_order(CuTest *tc) { +static void test_long_order_normal(CuTest *tc) { + // TODO: write more tests + unit *u; + order *ord; + test_cleanup(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + fset(u, UFL_MOVED); + fset(u, UFL_LONGACTION); + u->faction->locale = get_or_create_locale("de"); + ord = create_order(K_MOVE, u->faction->locale, 0); + unit_addorder(u, ord); + update_long_order(u); + CuAssertPtrEquals(tc, ord->data, u->thisorder->data); + CuAssertIntEquals(tc, 0, fval(u, UFL_MOVED)); + CuAssertIntEquals(tc, 0, fval(u, UFL_LONGACTION)); + CuAssertPtrNotNull(tc, u->orders); + CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, 0, u->old_orders); + test_cleanup(); +} + +static void test_long_order_none(CuTest *tc) { // TODO: write more tests unit *u; test_cleanup(); u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + u->faction->locale = get_or_create_locale("de"); update_long_order(u); CuAssertPtrEquals(tc, 0, u->thisorder); CuAssertPtrEquals(tc, 0, u->orders); - CuAssertPtrEquals(tc, 0, u->old_orders); + CuAssertPtrEquals(tc, 0, u->faction->msgs); + test_cleanup(); +} + +static void test_long_order_cast(CuTest *tc) { + // TODO: write more tests + unit *u; + test_cleanup(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + u->faction->locale = get_or_create_locale("de"); + unit_addorder(u, create_order(K_CAST, u->faction->locale, 0)); + unit_addorder(u, create_order(K_CAST, u->faction->locale, 0)); + update_long_order(u); + CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrNotNull(tc, u->orders); + CuAssertPtrEquals(tc, 0, u->faction->msgs); + test_cleanup(); +} + +static void test_long_order_buy_sell(CuTest *tc) { + // TODO: write more tests + unit *u; + test_cleanup(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + u->faction->locale = get_or_create_locale("de"); + unit_addorder(u, create_order(K_BUY, u->faction->locale, 0)); + unit_addorder(u, create_order(K_SELL, u->faction->locale, 0)); + unit_addorder(u, create_order(K_SELL, u->faction->locale, 0)); + update_long_order(u); + CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrNotNull(tc, u->orders); + CuAssertPtrEquals(tc, 0, u->faction->msgs); + test_cleanup(); +} + +static void test_long_order_multi_long(CuTest *tc) { + // TODO: write more tests + unit *u; + test_cleanup(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + u->faction->locale = get_or_create_locale("de"); + unit_addorder(u, create_order(K_MOVE, u->faction->locale, 0)); + unit_addorder(u, create_order(K_DESTROY, u->faction->locale, 0)); + update_long_order(u); + CuAssertPtrNotNull(tc, u->thisorder); + CuAssertPtrNotNull(tc, u->orders); + CuAssertStrEquals(tc, "error52", test_get_messagetype(u->faction->msgs->begin->msg)); + test_cleanup(); +} + +static void test_long_order_multi_buy(CuTest *tc) { + // TODO: write more tests + unit *u; + test_cleanup(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + u->faction->locale = get_or_create_locale("de"); + unit_addorder(u, create_order(K_BUY, u->faction->locale, 0)); + unit_addorder(u, create_order(K_BUY, u->faction->locale, 0)); + update_long_order(u); + CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrNotNull(tc, u->orders); + CuAssertStrEquals(tc, "error52", test_get_messagetype(u->faction->msgs->begin->msg)); + test_cleanup(); +} + +static void test_long_order_buy_cast(CuTest *tc) { + // TODO: write more tests + unit *u; + test_cleanup(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + u->faction->locale = get_or_create_locale("de"); + unit_addorder(u, create_order(K_BUY, u->faction->locale, 0)); + unit_addorder(u, create_order(K_CAST, u->faction->locale, 0)); + update_long_order(u); + CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrNotNull(tc, u->orders); + CuAssertStrEquals(tc, "error52", test_get_messagetype(u->faction->msgs->begin->msg)); + test_cleanup(); +} + +static void test_long_order_hungry(CuTest *tc) { + // TODO: write more tests + unit *u; + test_cleanup(); + set_param(&global.parameters, "hunger.long", "1"); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + fset(u, UFL_HUNGER); + u->faction->locale = get_or_create_locale("de"); + unit_addorder(u, create_order(K_MOVE, u->faction->locale, 0)); + unit_addorder(u, create_order(K_DESTROY, u->faction->locale, 0)); + set_default_order(K_WORK); + update_long_order(u); + CuAssertIntEquals(tc, K_WORK, getkeyword(u->thisorder)); + CuAssertPtrNotNull(tc, u->orders); + CuAssertPtrEquals(tc, 0, u->faction->msgs); + set_default_order(NOKEYWORD); test_cleanup(); } CuSuite *get_laws_suite(void) { CuSuite *suite = CuSuiteNew(); - SUITE_ADD_TEST(suite, test_update_long_order); + SUITE_ADD_TEST(suite, test_long_order_normal); + SUITE_ADD_TEST(suite, test_long_order_none); + SUITE_ADD_TEST(suite, test_long_order_cast); + SUITE_ADD_TEST(suite, test_long_order_buy_sell); + SUITE_ADD_TEST(suite, test_long_order_multi_long); + SUITE_ADD_TEST(suite, test_long_order_multi_buy); + SUITE_ADD_TEST(suite, test_long_order_buy_cast); + SUITE_ADD_TEST(suite, test_long_order_hungry); SUITE_ADD_TEST(suite, test_new_building_can_be_renamed); SUITE_ADD_TEST(suite, test_rename_building); SUITE_ADD_TEST(suite, test_rename_building_twice);