forked from github/server
refactor monster movement planning, test at_hate.
This commit is contained in:
parent
fc4b7ba73d
commit
0171c74e19
|
@ -55,7 +55,6 @@
|
|||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
#include <util/base36.h>
|
||||
#include <util/bsdstring.h>
|
||||
#include <util/event.h>
|
||||
#include <util/language.h>
|
||||
#include <util/lists.h>
|
||||
|
@ -502,41 +501,30 @@ static attrib *set_new_dragon_target(unit * u, region * r, int range)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static order *make_movement_order(unit * u, const region * target, int moves,
|
||||
static order *plan_move_to_target(unit * u, const region * target, int moves,
|
||||
bool(*allowed) (const region *, const region *))
|
||||
{
|
||||
region *r = u->region;
|
||||
region **plan;
|
||||
int position = 0;
|
||||
char zOrder[128], *bufp = zOrder;
|
||||
size_t size = sizeof(zOrder) - 1;
|
||||
direction_t steps[DRAGON_RANGE];
|
||||
int position;
|
||||
|
||||
if (monster_is_waiting(u))
|
||||
return NULL;
|
||||
|
||||
plan = path_find(r, target, DRAGON_RANGE * 5, allowed);
|
||||
plan = path_find(r, target, DRAGON_RANGE, allowed);
|
||||
if (plan == NULL)
|
||||
return NULL;
|
||||
|
||||
while (position != moves && plan[position + 1]) {
|
||||
int bytes;
|
||||
for (position = 0; position != moves && plan[position + 1]; ++position) {
|
||||
region *prev = plan[position];
|
||||
region *next = plan[++position];
|
||||
region *next = plan[position + 1];
|
||||
direction_t dir = reldirection(prev, next);
|
||||
assert(dir != NODIRECTION && dir != D_SPECIAL);
|
||||
if (size > 1 && bufp != zOrder) {
|
||||
*bufp++ = ' ';
|
||||
--size;
|
||||
}
|
||||
bytes =
|
||||
(int)str_strlcpy(bufp,
|
||||
(const char *)LOC(u->faction->locale, directions[dir]), size);
|
||||
if (wrptr(&bufp, &size, bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
steps[position] = dir;
|
||||
}
|
||||
|
||||
*bufp = 0;
|
||||
return create_order(K_MOVE, u->faction->locale, zOrder);
|
||||
return make_movement_order(u->faction->locale, steps, position);
|
||||
}
|
||||
|
||||
void random_growl(const unit *u, region *target, int rand)
|
||||
|
@ -689,15 +677,15 @@ static order *plan_dragon(unit * u)
|
|||
assert(long_order == NULL);
|
||||
/* TODO: per-race planning functions? */
|
||||
if (rc == rc_wyrm) {
|
||||
long_order = make_movement_order(u, tr, 1, allowed_dragon);
|
||||
long_order = plan_move_to_target(u, tr, 1, allowed_dragon);
|
||||
}
|
||||
else {
|
||||
switch (old_race(rc)) {
|
||||
case RC_FIREDRAGON:
|
||||
long_order = make_movement_order(u, tr, 4, allowed_dragon);
|
||||
long_order = plan_move_to_target(u, tr, 4, allowed_dragon);
|
||||
break;
|
||||
case RC_DRAGON:
|
||||
long_order = make_movement_order(u, tr, 3, allowed_dragon);
|
||||
long_order = plan_move_to_target(u, tr, 3, allowed_dragon);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -793,7 +781,7 @@ void plan_monsters(faction * f)
|
|||
if (canfly(u)) {
|
||||
allowed = allowed_fly;
|
||||
}
|
||||
long_order = make_movement_order(u, tu->region, 2, allowed);
|
||||
long_order = plan_move_to_target(u, tu->region, 2, allowed);
|
||||
}
|
||||
else
|
||||
a_remove(&u->attribs, ta);
|
||||
|
|
|
@ -28,6 +28,8 @@ extern "C" {
|
|||
struct unit;
|
||||
struct region;
|
||||
struct faction;
|
||||
struct order;
|
||||
struct locale;
|
||||
|
||||
struct unit *spawn_seaserpent(struct region *r, struct faction *f);
|
||||
void spawn_dragons(void);
|
||||
|
|
|
@ -18,10 +18,13 @@
|
|||
#include "skill.h"
|
||||
#include "study.h"
|
||||
|
||||
#include <util/attrib.h>
|
||||
#include <util/language.h>
|
||||
#include <util/message.h>
|
||||
#include <util/nrmessage.h>
|
||||
|
||||
#include <attributes/hate.h>
|
||||
|
||||
#include <CuTest.h>
|
||||
#include <tests.h>
|
||||
#include <assert.h>
|
||||
|
@ -267,10 +270,35 @@ static void test_spawn_seaserpent(CuTest *tc) {
|
|||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_monsters_hate(CuTest *tc) {
|
||||
unit *mu, *tu;
|
||||
order *ord;
|
||||
char buffer[32];
|
||||
const struct locale *lang;
|
||||
|
||||
test_setup();
|
||||
tu = test_create_unit(test_create_faction(NULL), test_create_plain(1, 0));
|
||||
mu = test_create_unit(get_monsters(), test_create_plain(0, 0));
|
||||
lang = mu->faction->locale;
|
||||
a_add(&mu->attribs, make_hate(tu));
|
||||
plan_monsters(mu->faction);
|
||||
CuAssertPtrNotNull(tc, mu->orders);
|
||||
for (ord = mu->orders; ord; ord = ord->next) {
|
||||
if (K_MOVE == getkeyword(ord)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
CuAssertPtrNotNull(tc, ord);
|
||||
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||
CuAssertStrEquals(tc, "move east", get_command(ord, lang, buffer, sizeof(buffer)));
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
CuSuite *get_monsters_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_monsters_attack);
|
||||
SUITE_ADD_TEST(suite, test_monsters_hate);
|
||||
SUITE_ADD_TEST(suite, test_spawn_seaserpent);
|
||||
SUITE_ADD_TEST(suite, test_monsters_attack_ocean);
|
||||
SUITE_ADD_TEST(suite, test_seaserpent_piracy);
|
||||
|
|
24
src/move.c
24
src/move.c
|
@ -1131,6 +1131,30 @@ order * cycle_route(order * ord, const struct locale *lang, int gereist)
|
|||
return norder;
|
||||
}
|
||||
|
||||
order * make_movement_order(const struct locale *lang, direction_t steps[], int length)
|
||||
{
|
||||
char zOrder[128], *bufp = zOrder;
|
||||
size_t size = sizeof(zOrder) - 1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i != length; ++i) {
|
||||
int bytes;
|
||||
direction_t dir = steps[i];
|
||||
if (size > 1 && bufp != zOrder) {
|
||||
*bufp++ = ' ';
|
||||
--size;
|
||||
}
|
||||
bytes =
|
||||
(int)str_strlcpy(bufp,
|
||||
(const char *)LOC(lang, directions[dir]), size);
|
||||
if (wrptr(&bufp, &size, bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
|
||||
*bufp = 0;
|
||||
return create_order(K_MOVE, lang, zOrder);
|
||||
}
|
||||
|
||||
static bool transport(unit * ut, unit * u)
|
||||
{
|
||||
order *ord;
|
||||
|
|
|
@ -98,6 +98,7 @@ extern "C" {
|
|||
int check_ship_allowed(struct ship *sh, const struct region * r);
|
||||
direction_t drift_target(struct ship *sh);
|
||||
struct order * cycle_route(struct order * ord, const struct locale *lang, int gereist);
|
||||
struct order * make_movement_order(const struct locale *lang, direction_t steps[], int length);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue