diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 655c210fa..d0a419109 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1124,6 +1124,19 @@ function test_route() assert_equal(r2, u.region) end +function test_route_horse() + local r1 = region.create(0, 0, "plain") + local r2 = region.create(1, 0, "plain") + local f = faction.create("human", "route@example.com") + local u = unit.create(f, r1, 1) + u:add_order("ROUTE O P W P") + u:add_item('horse', 1) + u:set_skill('riding', 1) + process_orders() + assert_equal("ROUTE West PAUSE Ost PAUSE", u:get_order(0)) + assert_equal(r2, u.region) +end + function test_route_pause() local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") diff --git a/src/direction.c b/src/direction.c index 5e2333bbe..13feff13b 100644 --- a/src/direction.c +++ b/src/direction.c @@ -8,6 +8,15 @@ #include +const char *shortdirections[MAXDIRECTIONS] = { + "dir_nw", + "dir_ne", + "dir_east", + "dir_se", + "dir_sw", + "dir_west" +}; + void init_direction(const struct locale *lang, direction_t dir, const char *str) { void **tokens = get_translations(lang, UT_DIRECTIONS); variant token; diff --git a/src/direction.h b/src/direction.h index 14ced4c1c..724878663 100644 --- a/src/direction.h +++ b/src/direction.h @@ -21,6 +21,8 @@ extern "C" NODIRECTION = -1 } direction_t; + extern const char *shortdirections[MAXDIRECTIONS]; + direction_t get_direction(const char *s, const struct locale *); void init_directions(struct locale *lang); void init_direction(const struct locale *lang, direction_t dir, const char *str); diff --git a/src/move.c b/src/move.c index 798c3da27..592ca606f 100644 --- a/src/move.c +++ b/src/move.c @@ -1042,15 +1042,6 @@ int movewhere(const unit * u, const char *token, region * r, region ** resultp) return E_MOVE_OK; } -static const char *shortdirections[MAXDIRECTIONS] = { - "dir_nw", - "dir_ne", - "dir_east", - "dir_se", - "dir_sw", - "dir_west" -}; - static void cycle_route(order * ord, unit * u, int gereist) { int cm = 0; @@ -1063,13 +1054,11 @@ static void cycle_route(order * ord, unit * u, int gereist) order *norder; size_t size = sizeof(tail) - 1; - if (getkeyword(ord) != K_ROUTE) - return; + assert(getkeyword(ord) == K_ROUTE); tail[0] = '\0'; + neworder[0] = '\0'; + init_order(ord, u->faction->locale); - init_order_depr(ord); - - neworder[0] = 0; for (cm = 0;; ++cm) { const char *s; const struct locale *lang = u->faction->locale; @@ -1092,6 +1081,7 @@ static void cycle_route(order * ord, unit * u, int gereist) assert(!pause); if (!pause) { const char *loc = LOC(lang, shortdirections[d]); + assert(loc); if (bufp != tail) { bufp = STRLCPY_EX(bufp, " ", &size, "cycle_route"); } @@ -1371,7 +1361,7 @@ static void make_route(unit * u, order * ord, region_list ** routep) current = next; s = gettoken(token, sizeof(token)); error = movewhere(u, s, current, &next); - if (error) { + if (error != E_MOVE_OK) { message *msg = movement_error(u, s, ord, error); if (msg != NULL) { add_message(&u->faction->msgs, msg); @@ -1606,7 +1596,9 @@ static const region_list *travel_route(unit * u, int walkmode; setguard(u, false); - cycle_route(ord, u, steps); + if (getkeyword(ord) == K_ROUTE) { + cycle_route(ord, u, steps); + } if (mode == TRAVEL_RUNNING) { walkmode = 0; @@ -1936,7 +1928,9 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting) unit *harbourmaster; /* nachdem alle Richtungen abgearbeitet wurden, und alle Einheiten * transferiert wurden, kann der aktuelle Befehl gelöscht werden. */ - cycle_route(ord, u, step); + if (getkeyword(ord) == K_ROUTE) { + cycle_route(ord, u, step); + } set_order(&u->thisorder, NULL); set_coast(sh, last_point, current_point); @@ -2026,7 +2020,7 @@ static const region_list *travel_i(unit * u, const region_list * route_begin, region *r = u->region; int mp; if (u->building && !can_leave(u)) { - cmistake(u, u->thisorder, 150, MSG_MOVE); + cmistake(u, ord, 150, MSG_MOVE); return route_begin; } switch (canwalk(u)) { @@ -2115,7 +2109,7 @@ static const region_list *travel_i(unit * u, const region_list * route_begin, /** traveling without ships * walking, flying or riding units use this function */ -static void travel(unit * u, region_list ** routep) +static void travel(unit * u, order *ord, region_list ** routep) { region *r = u->region; region_list *route_begin; @@ -2129,7 +2123,7 @@ static void travel(unit * u, region_list ** routep) ship *sh = u->ship; if (!can_leave(u)) { - cmistake(u, u->thisorder, 150, MSG_MOVE); + cmistake(u, ord, 150, MSG_MOVE); return; } @@ -2142,28 +2136,28 @@ static void travel(unit * u, region_list ** routep) if (sh) { unit *guard = is_guarded(r, u); if (guard) { - ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "region_guarded", "guard", guard)); return; } } if (u->ship && u_race(u)->flags & RCF_SWIM) { - cmistake(u, u->thisorder, 143, MSG_MOVE); + cmistake(u, ord, 143, MSG_MOVE); return; } } else if (u->ship && fval(u->ship, SF_MOVED)) { /* die Einheit ist auf einem Schiff, das sich bereits bewegt hat */ - cmistake(u, u->thisorder, 13, MSG_MOVE); + cmistake(u, ord, 13, MSG_MOVE); return; } - make_route(u, u->thisorder, routep); + make_route(u, ord, routep); route_begin = *routep; if (route_begin) { /* und ab die post: */ - travel_i(u, route_begin, NULL, u->thisorder, TRAVEL_NORMAL, &followers); + travel_i(u, route_begin, NULL, ord, TRAVEL_NORMAL, &followers); /* followers */ while (followers != NULL) { @@ -2204,7 +2198,7 @@ void move_cmd(unit * u, order * ord) sail(u, ord, &route, drifting); } else { - travel(u, &route); + travel(u, ord, &route); } fset(u, UFL_LONGACTION | UFL_NOTMOVING); diff --git a/src/move.test.c b/src/move.test.c index 7095da855..edb070bfb 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -545,6 +545,52 @@ static void test_movement_speed(CuTest *tc) { test_cleanup(); } +static void test_route_cycle(CuTest *tc) { + unit *u; + region *r; + struct locale *lang; + char buffer[32]; + + test_setup(); + test_create_region(1, 0, NULL); + r = test_create_region(2, 0, NULL); + lang = test_create_locale(); + CuAssertPtrNotNull(tc, LOC(lang, shortdirections[D_WEST])); + u = test_create_unit(test_create_faction(NULL), r); + u->faction->locale = lang; + CuAssertIntEquals(tc, RCF_WALK, u->_race->flags & RCF_WALK); + u->orders = create_order(K_ROUTE, u->faction->locale, "WEST EAST NW"); + CuAssertStrEquals(tc, "route WEST EAST NW", get_command(u->orders, lang, buffer, sizeof(buffer))); + init_order(u->orders, u->faction->locale); + move_cmd(u, u->orders); + CuAssertIntEquals(tc, 1, u->region->x); + CuAssertStrEquals(tc, "route east nw west", get_command(u->orders, lang, buffer, sizeof(buffer))); + test_cleanup(); +} + +static void test_route_pause(CuTest *tc) { + unit *u; + region *r; + struct locale *lang; + char buffer[32]; + + test_setup(); + test_create_region(1, 0, NULL); + r = test_create_region(2, 0, NULL); + lang = test_create_locale(); + CuAssertPtrNotNull(tc, LOC(lang, shortdirections[D_WEST])); + u = test_create_unit(test_create_faction(NULL), r); + u->faction->locale = lang; + CuAssertIntEquals(tc, RCF_WALK, u->_race->flags & RCF_WALK); + u->orders = create_order(K_ROUTE, u->faction->locale, "PAUSE EAST NW"); + CuAssertStrEquals(tc, "route PAUSE EAST NW", get_command(u->orders, lang, buffer, sizeof(buffer))); + init_order(u->orders, u->faction->locale); + move_cmd(u, u->orders); + CuAssertIntEquals(tc, 2, u->region->x); + CuAssertStrEquals(tc, "route PAUSE EAST NW", get_command(u->orders, lang, buffer, sizeof(buffer))); + test_cleanup(); +} + CuSuite *get_move_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -570,5 +616,7 @@ CuSuite *get_move_suite(void) SUITE_ADD_TEST(suite, test_ship_damage_overload); SUITE_ADD_TEST(suite, test_follow_ship_msg); SUITE_ADD_TEST(suite, test_drifting_ships); + SUITE_ADD_TEST(suite, test_route_cycle); + SUITE_ADD_TEST(suite, test_route_pause); return suite; } diff --git a/src/tests.c b/src/tests.c index d07124af3..70f006ef6 100644 --- a/src/tests.c +++ b/src/tests.c @@ -44,6 +44,7 @@ struct race *test_create_race(const char *name) rc->maintenance = 10; rc->hitpoints = 20; rc->maxaura = 100; + rc->flags |= RCF_WALK; rc->ec_flags |= ECF_GETITEM; rc->battle_flags = BF_EQUIPMENT; return rc; @@ -120,6 +121,7 @@ struct locale * test_create_locale(void) { locale_setstring(loc, alliance_kwd[i], alliance_kwd[i]); } for (i = 0; i != MAXDIRECTIONS; ++i) { + locale_setstring(loc, shortdirections[i], shortdirections[i] + 4); locale_setstring(loc, directions[i], directions[i]); init_direction(loc, i, directions[i]); init_direction(loc, i, coasts[i] + 7);