forked from github/server
refactor monster movement planning, test at_hate.
This commit is contained in:
parent
fc4b7ba73d
commit
0171c74e19
5 changed files with 67 additions and 24 deletions
|
@ -55,7 +55,6 @@
|
||||||
/* util includes */
|
/* util includes */
|
||||||
#include <util/attrib.h>
|
#include <util/attrib.h>
|
||||||
#include <util/base36.h>
|
#include <util/base36.h>
|
||||||
#include <util/bsdstring.h>
|
|
||||||
#include <util/event.h>
|
#include <util/event.h>
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
#include <util/lists.h>
|
#include <util/lists.h>
|
||||||
|
@ -502,41 +501,30 @@ static attrib *set_new_dragon_target(unit * u, region * r, int range)
|
||||||
return NULL;
|
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 *))
|
bool(*allowed) (const region *, const region *))
|
||||||
{
|
{
|
||||||
region *r = u->region;
|
region *r = u->region;
|
||||||
region **plan;
|
region **plan;
|
||||||
int position = 0;
|
direction_t steps[DRAGON_RANGE];
|
||||||
char zOrder[128], *bufp = zOrder;
|
int position;
|
||||||
size_t size = sizeof(zOrder) - 1;
|
|
||||||
|
|
||||||
if (monster_is_waiting(u))
|
if (monster_is_waiting(u))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
plan = path_find(r, target, DRAGON_RANGE * 5, allowed);
|
plan = path_find(r, target, DRAGON_RANGE, allowed);
|
||||||
if (plan == NULL)
|
if (plan == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while (position != moves && plan[position + 1]) {
|
for (position = 0; position != moves && plan[position + 1]; ++position) {
|
||||||
int bytes;
|
|
||||||
region *prev = plan[position];
|
region *prev = plan[position];
|
||||||
region *next = plan[++position];
|
region *next = plan[position + 1];
|
||||||
direction_t dir = reldirection(prev, next);
|
direction_t dir = reldirection(prev, next);
|
||||||
assert(dir != NODIRECTION && dir != D_SPECIAL);
|
assert(dir != NODIRECTION && dir != D_SPECIAL);
|
||||||
if (size > 1 && bufp != zOrder) {
|
steps[position] = dir;
|
||||||
*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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*bufp = 0;
|
return make_movement_order(u->faction->locale, steps, position);
|
||||||
return create_order(K_MOVE, u->faction->locale, zOrder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void random_growl(const unit *u, region *target, int rand)
|
void random_growl(const unit *u, region *target, int rand)
|
||||||
|
@ -689,15 +677,15 @@ static order *plan_dragon(unit * u)
|
||||||
assert(long_order == NULL);
|
assert(long_order == NULL);
|
||||||
/* TODO: per-race planning functions? */
|
/* TODO: per-race planning functions? */
|
||||||
if (rc == rc_wyrm) {
|
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 {
|
else {
|
||||||
switch (old_race(rc)) {
|
switch (old_race(rc)) {
|
||||||
case RC_FIREDRAGON:
|
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;
|
break;
|
||||||
case RC_DRAGON:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -793,7 +781,7 @@ void plan_monsters(faction * f)
|
||||||
if (canfly(u)) {
|
if (canfly(u)) {
|
||||||
allowed = allowed_fly;
|
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
|
else
|
||||||
a_remove(&u->attribs, ta);
|
a_remove(&u->attribs, ta);
|
||||||
|
|
|
@ -28,6 +28,8 @@ extern "C" {
|
||||||
struct unit;
|
struct unit;
|
||||||
struct region;
|
struct region;
|
||||||
struct faction;
|
struct faction;
|
||||||
|
struct order;
|
||||||
|
struct locale;
|
||||||
|
|
||||||
struct unit *spawn_seaserpent(struct region *r, struct faction *f);
|
struct unit *spawn_seaserpent(struct region *r, struct faction *f);
|
||||||
void spawn_dragons(void);
|
void spawn_dragons(void);
|
||||||
|
|
|
@ -18,10 +18,13 @@
|
||||||
#include "skill.h"
|
#include "skill.h"
|
||||||
#include "study.h"
|
#include "study.h"
|
||||||
|
|
||||||
|
#include <util/attrib.h>
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
#include <util/message.h>
|
#include <util/message.h>
|
||||||
#include <util/nrmessage.h>
|
#include <util/nrmessage.h>
|
||||||
|
|
||||||
|
#include <attributes/hate.h>
|
||||||
|
|
||||||
#include <CuTest.h>
|
#include <CuTest.h>
|
||||||
#include <tests.h>
|
#include <tests.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -267,10 +270,35 @@ static void test_spawn_seaserpent(CuTest *tc) {
|
||||||
test_teardown();
|
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 *get_monsters_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
SUITE_ADD_TEST(suite, test_monsters_attack);
|
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_spawn_seaserpent);
|
||||||
SUITE_ADD_TEST(suite, test_monsters_attack_ocean);
|
SUITE_ADD_TEST(suite, test_monsters_attack_ocean);
|
||||||
SUITE_ADD_TEST(suite, test_seaserpent_piracy);
|
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;
|
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)
|
static bool transport(unit * ut, unit * u)
|
||||||
{
|
{
|
||||||
order *ord;
|
order *ord;
|
||||||
|
|
|
@ -98,6 +98,7 @@ extern "C" {
|
||||||
int check_ship_allowed(struct ship *sh, const struct region * r);
|
int check_ship_allowed(struct ship *sh, const struct region * r);
|
||||||
direction_t drift_target(struct ship *sh);
|
direction_t drift_target(struct ship *sh);
|
||||||
struct order * cycle_route(struct order * ord, const struct locale *lang, int gereist);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue