forked from github/server
refactoring: special directions into their own file (vortex.c).
moving spells.c out of spells. figured that movewhere should be in move.c
This commit is contained in:
parent
ecaeba3058
commit
932a615837
|
@ -51,9 +51,11 @@ ENDIF()
|
||||||
|
|
||||||
set (ERESSEA_SRC
|
set (ERESSEA_SRC
|
||||||
move.c
|
move.c
|
||||||
|
spells.c
|
||||||
battle.c
|
battle.c
|
||||||
alchemy.c
|
alchemy.c
|
||||||
stealth.c
|
stealth.c
|
||||||
|
vortex.c
|
||||||
names.c
|
names.c
|
||||||
reports.c
|
reports.c
|
||||||
eressea.c
|
eressea.c
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
|
|
||||||
#include <spells/spells.h>
|
#include "spells.h"
|
||||||
|
|
||||||
/* kernel includes */
|
/* kernel includes */
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
|
|
|
@ -2,14 +2,9 @@
|
||||||
#include <kernel/types.h>
|
#include <kernel/types.h>
|
||||||
|
|
||||||
#include "direction.h"
|
#include "direction.h"
|
||||||
#include "util/language.h"
|
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
|
|
||||||
#include <kernel/config.h>
|
#include <util/language.h>
|
||||||
#include <kernel/region.h>
|
|
||||||
#include <kernel/unit.h>
|
|
||||||
#include <kernel/race.h>
|
|
||||||
#include <kernel/terrain.h>
|
|
||||||
|
|
||||||
#include <CuTest.h>
|
#include <CuTest.h>
|
||||||
|
|
||||||
|
@ -63,27 +58,6 @@ static void test_get_direction_default(CuTest *tc) {
|
||||||
CuAssertIntEquals(tc, D_EAST, get_direction("east", lang));
|
CuAssertIntEquals(tc, D_EAST, get_direction("east", lang));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_move_to_vortex(CuTest *tc) {
|
|
||||||
region *r1, *r2, *r = 0;
|
|
||||||
terrain_type *t_plain;
|
|
||||||
unit *u;
|
|
||||||
struct locale *lang;
|
|
||||||
|
|
||||||
test_cleanup();
|
|
||||||
lang = get_or_create_locale("en");
|
|
||||||
locale_setstring(lang, "vortex", "wirbel");
|
|
||||||
init_locale(lang);
|
|
||||||
register_special_direction("vortex");
|
|
||||||
t_plain = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION);
|
|
||||||
r1 = test_create_region(0, 0, t_plain);
|
|
||||||
r2 = test_create_region(5, 0, t_plain);
|
|
||||||
CuAssertPtrNotNull(tc, create_special_direction(r1, r2, 10, "", "vortex", true));
|
|
||||||
u = test_create_unit(test_create_faction(rc_get_or_create("hodor")), r1);
|
|
||||||
CuAssertIntEquals(tc, E_MOVE_NOREGION, movewhere(u, "barf", r1, &r));
|
|
||||||
CuAssertIntEquals(tc, E_MOVE_OK, movewhere(u, "wirbel", r1, &r));
|
|
||||||
CuAssertPtrEquals(tc, r2, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SUITE_DISABLE_TEST(suite, test) (void)test
|
#define SUITE_DISABLE_TEST(suite, test) (void)test
|
||||||
|
|
||||||
CuSuite *get_direction_suite(void)
|
CuSuite *get_direction_suite(void)
|
||||||
|
@ -92,7 +66,6 @@ CuSuite *get_direction_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_init_direction);
|
SUITE_ADD_TEST(suite, test_init_direction);
|
||||||
SUITE_ADD_TEST(suite, test_init_directions);
|
SUITE_ADD_TEST(suite, test_init_directions);
|
||||||
SUITE_ADD_TEST(suite, test_finddirection);
|
SUITE_ADD_TEST(suite, test_finddirection);
|
||||||
SUITE_ADD_TEST(suite, test_move_to_vortex);
|
|
||||||
SUITE_DISABLE_TEST(suite, test_get_direction_default);
|
SUITE_DISABLE_TEST(suite, test_get_direction_default);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,9 @@ This program may not be used, modified or distributed
|
||||||
without prior permission by the authors of Eressea.
|
without prior permission by the authors of Eressea.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "helpers.h"
|
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
|
#include "helpers.h"
|
||||||
|
#include "vortex.h"
|
||||||
|
|
||||||
#include <util/attrib.h>
|
#include <util/attrib.h>
|
||||||
#include <util/base36.h>
|
#include <util/base36.h>
|
||||||
|
@ -541,6 +542,7 @@ int tolua_toid(lua_State * L, int idx, int def)
|
||||||
|
|
||||||
void register_tolua_helpers(void)
|
void register_tolua_helpers(void)
|
||||||
{
|
{
|
||||||
|
at_register(&at_direction);
|
||||||
at_register(&at_building_action);
|
at_register(&at_building_action);
|
||||||
|
|
||||||
register_function((pf_generic) & lua_building_protection,
|
register_function((pf_generic) & lua_building_protection,
|
||||||
|
|
|
@ -2667,40 +2667,6 @@ message *movement_error(unit * u, const char *token, order * ord,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int movewhere(const unit * u, const char *token, region * r, region ** resultp)
|
|
||||||
{
|
|
||||||
region *r2;
|
|
||||||
direction_t d;
|
|
||||||
|
|
||||||
if (!token || *token == '\0') {
|
|
||||||
*resultp = NULL;
|
|
||||||
return E_MOVE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
d = get_direction(token, u->faction->locale);
|
|
||||||
switch (d) {
|
|
||||||
case D_PAUSE:
|
|
||||||
*resultp = r;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NODIRECTION:
|
|
||||||
r2 = find_special_direction(r, token, u->faction->locale);
|
|
||||||
if (r2 == NULL) {
|
|
||||||
return E_MOVE_NOREGION;
|
|
||||||
}
|
|
||||||
*resultp = r2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
r2 = rconnect(r, d);
|
|
||||||
if (r2 == NULL || move_blocked(u, r, r2)) {
|
|
||||||
return E_MOVE_BLOCKED;
|
|
||||||
}
|
|
||||||
*resultp = r2;
|
|
||||||
}
|
|
||||||
return E_MOVE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool move_blocked(const unit * u, const region * r, const region * r2)
|
bool move_blocked(const unit * u, const region * r, const region * r2)
|
||||||
{
|
{
|
||||||
connection *b;
|
connection *b;
|
||||||
|
@ -2779,7 +2745,6 @@ void attrib_init(void)
|
||||||
at_register(&at_seenspell);
|
at_register(&at_seenspell);
|
||||||
|
|
||||||
/* neue REGION-Attribute */
|
/* neue REGION-Attribute */
|
||||||
at_register(&at_direction);
|
|
||||||
at_register(&at_moveblock);
|
at_register(&at_moveblock);
|
||||||
at_register(&at_deathcount);
|
at_register(&at_deathcount);
|
||||||
at_register(&at_chaoscount);
|
at_register(&at_chaoscount);
|
||||||
|
|
|
@ -339,15 +339,6 @@ extern "C" {
|
||||||
const struct region *dest);
|
const struct region *dest);
|
||||||
void add_income(struct unit *u, int type, int want, int qty);
|
void add_income(struct unit *u, int type, int want, int qty);
|
||||||
|
|
||||||
/* movewhere error codes */
|
|
||||||
enum {
|
|
||||||
E_MOVE_OK = 0, /* possible to move */
|
|
||||||
E_MOVE_NOREGION, /* no region exists in this direction */
|
|
||||||
E_MOVE_BLOCKED /* cannot see this region, there is a blocking connection. */
|
|
||||||
};
|
|
||||||
int movewhere(const struct unit *u, const char *token,
|
|
||||||
struct region *r, struct region **resultp);
|
|
||||||
|
|
||||||
const char *datapath(void);
|
const char *datapath(void);
|
||||||
void set_datapath(const char *path);
|
void set_datapath(const char *path);
|
||||||
|
|
||||||
|
|
|
@ -189,163 +189,6 @@ void chaoscounts(region * r, int fallen)
|
||||||
a_remove(&r->attribs, a);
|
a_remove(&r->attribs, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************/
|
|
||||||
/* at_direction */
|
|
||||||
/********************/
|
|
||||||
static void a_initdirection(attrib * a)
|
|
||||||
{
|
|
||||||
a->data.v = calloc(1, sizeof(spec_direction));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void a_freedirection(attrib * a)
|
|
||||||
{
|
|
||||||
free(a->data.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int a_agedirection(attrib * a)
|
|
||||||
{
|
|
||||||
spec_direction *d = (spec_direction *) (a->data.v);
|
|
||||||
--d->duration;
|
|
||||||
return (d->duration > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct dir_lookup {
|
|
||||||
char *name;
|
|
||||||
const char *oldname;
|
|
||||||
struct dir_lookup *next;
|
|
||||||
} dir_lookup;
|
|
||||||
|
|
||||||
static dir_lookup *dir_name_lookup;
|
|
||||||
|
|
||||||
void register_special_direction(const char *name)
|
|
||||||
{
|
|
||||||
struct locale *lang;
|
|
||||||
char *str = _strdup(name);
|
|
||||||
|
|
||||||
for (lang = locales; lang; lang = nextlocale(lang)) {
|
|
||||||
void **tokens = get_translations(lang, UT_SPECDIR);
|
|
||||||
const char *token = LOC(lang, name);
|
|
||||||
|
|
||||||
if (token) {
|
|
||||||
variant var;
|
|
||||||
|
|
||||||
var.v = str;
|
|
||||||
addtoken(tokens, token, var);
|
|
||||||
|
|
||||||
if (lang == default_locale) {
|
|
||||||
dir_lookup *dl = malloc(sizeof(dir_lookup));
|
|
||||||
dl->name = str;
|
|
||||||
dl->oldname = token;
|
|
||||||
dl->next = dir_name_lookup;
|
|
||||||
dir_name_lookup = dl;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log_error("no translation for spec_direction '%s' in locale '%s'\n", name, locale_name(lang));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int a_readdirection(attrib * a, void *owner, struct storage *store)
|
|
||||||
{
|
|
||||||
spec_direction *d = (spec_direction *) (a->data.v);
|
|
||||||
|
|
||||||
READ_INT(store, &d->x);
|
|
||||||
READ_INT(store, &d->y);
|
|
||||||
READ_INT(store, &d->duration);
|
|
||||||
if (global.data_version < UNICODE_VERSION) {
|
|
||||||
char lbuf[16];
|
|
||||||
dir_lookup *dl = dir_name_lookup;
|
|
||||||
|
|
||||||
READ_TOK(store, NULL, 0);
|
|
||||||
READ_TOK(store, lbuf, sizeof(lbuf));
|
|
||||||
|
|
||||||
cstring_i(lbuf);
|
|
||||||
for (; dl; dl = dl->next) {
|
|
||||||
if (strcmp(lbuf, dl->oldname) == 0) {
|
|
||||||
d->keyword = _strdup(dl->name);
|
|
||||||
sprintf(lbuf, "%s_desc", d->keyword);
|
|
||||||
d->desc = _strdup(dl->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dl == NULL) {
|
|
||||||
log_error("unknown spec_direction '%s'\n", lbuf);
|
|
||||||
assert(!"not implemented");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
char lbuf[32];
|
|
||||||
READ_TOK(store, lbuf, sizeof(lbuf));
|
|
||||||
d->desc = _strdup(lbuf);
|
|
||||||
READ_TOK(store, lbuf, sizeof(lbuf));
|
|
||||||
d->keyword = _strdup(lbuf);
|
|
||||||
}
|
|
||||||
d->active = true;
|
|
||||||
return AT_READ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
a_writedirection(const attrib * a, const void *owner, struct storage *store)
|
|
||||||
{
|
|
||||||
spec_direction *d = (spec_direction *) (a->data.v);
|
|
||||||
|
|
||||||
WRITE_INT(store, d->x);
|
|
||||||
WRITE_INT(store, d->y);
|
|
||||||
WRITE_INT(store, d->duration);
|
|
||||||
WRITE_TOK(store, d->desc);
|
|
||||||
WRITE_TOK(store, d->keyword);
|
|
||||||
}
|
|
||||||
|
|
||||||
attrib_type at_direction = {
|
|
||||||
"direction",
|
|
||||||
a_initdirection,
|
|
||||||
a_freedirection,
|
|
||||||
a_agedirection,
|
|
||||||
a_writedirection,
|
|
||||||
a_readdirection
|
|
||||||
};
|
|
||||||
|
|
||||||
region *find_special_direction(const region * r, const char *token,
|
|
||||||
const struct locale *lang)
|
|
||||||
{
|
|
||||||
attrib *a;
|
|
||||||
spec_direction *d;
|
|
||||||
|
|
||||||
if (strlen(token) == 0)
|
|
||||||
return NULL;
|
|
||||||
for (a = a_find(r->attribs, &at_direction); a && a->type == &at_direction;
|
|
||||||
a = a->next) {
|
|
||||||
d = (spec_direction *) (a->data.v);
|
|
||||||
|
|
||||||
if (d->active) {
|
|
||||||
void **tokens = get_translations(lang, UT_SPECDIR);
|
|
||||||
variant var;
|
|
||||||
if (findtoken(*tokens, token, &var) == E_TOK_SUCCESS) {
|
|
||||||
if (strcmp((const char *)var.v, d->keyword) == 0) {
|
|
||||||
return findregion(d->x, d->y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
attrib *create_special_direction(region * r, region * rt, int duration,
|
|
||||||
const char *desc, const char *keyword, bool active)
|
|
||||||
{
|
|
||||||
attrib *a = a_add(&r->attribs, a_new(&at_direction));
|
|
||||||
spec_direction *d = (spec_direction *) (a->data.v);
|
|
||||||
|
|
||||||
d->active = active;
|
|
||||||
d->x = rt->x;
|
|
||||||
d->y = rt->y;
|
|
||||||
d->duration = duration;
|
|
||||||
d->desc = _strdup(desc);
|
|
||||||
d->keyword = _strdup(keyword);
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Moveblock wird zur Zeit nicht über Attribute, sondern ein Bitfeld
|
/* Moveblock wird zur Zeit nicht über Attribute, sondern ein Bitfeld
|
||||||
r->moveblock gemacht. Sollte umgestellt werden, wenn kompliziertere
|
r->moveblock gemacht. Sollte umgestellt werden, wenn kompliziertere
|
||||||
Dinge gefragt werden. */
|
Dinge gefragt werden. */
|
||||||
|
@ -630,49 +473,6 @@ int distance(const region * r1, const region * r2)
|
||||||
return koor_distance(r1->x, r1->y, r2->x, r2->y);
|
return koor_distance(r1->x, r1->y, r2->x, r2->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static direction_t
|
|
||||||
koor_reldirection(int ax, int ay, int bx, int by, const struct plane *pl)
|
|
||||||
{
|
|
||||||
int dir;
|
|
||||||
for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
|
|
||||||
int x = ax + delta_x[dir];
|
|
||||||
int y = ay + delta_y[dir];
|
|
||||||
pnormalize(&x, &y, pl);
|
|
||||||
if (bx == x && by == y)
|
|
||||||
return (direction_t)dir;
|
|
||||||
}
|
|
||||||
return NODIRECTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
spec_direction *special_direction(const region * from, const region * to)
|
|
||||||
{
|
|
||||||
const attrib *a = a_findc(from->attribs, &at_direction);
|
|
||||||
|
|
||||||
while (a != NULL && a->type == &at_direction) {
|
|
||||||
spec_direction *sd = (spec_direction *) a->data.v;
|
|
||||||
if (sd->x == to->x && sd->y == to->y)
|
|
||||||
return sd;
|
|
||||||
a = a->next;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
direction_t reldirection(const region * from, const region * to)
|
|
||||||
{
|
|
||||||
plane *pl = rplane(from);
|
|
||||||
if (pl == rplane(to)) {
|
|
||||||
direction_t dir = koor_reldirection(from->x, from->y, to->x, to->y, pl);
|
|
||||||
|
|
||||||
if (dir == NODIRECTION) {
|
|
||||||
spec_direction *sd = special_direction(from, to);
|
|
||||||
if (sd != NULL && sd->active)
|
|
||||||
return D_SPECIAL;
|
|
||||||
}
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
return NODIRECTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_regionlist(region_list * rl)
|
void free_regionlist(region_list * rl)
|
||||||
{
|
{
|
||||||
while (rl) {
|
while (rl) {
|
||||||
|
|
|
@ -153,14 +153,6 @@ extern "C" {
|
||||||
struct message *r_addmessage(struct region *r, const struct faction *viewer,
|
struct message *r_addmessage(struct region *r, const struct faction *viewer,
|
||||||
struct message *msg);
|
struct message *msg);
|
||||||
|
|
||||||
typedef struct spec_direction {
|
|
||||||
int x, y;
|
|
||||||
int duration;
|
|
||||||
bool active;
|
|
||||||
char *desc;
|
|
||||||
char *keyword;
|
|
||||||
} spec_direction;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
direction_t dir;
|
direction_t dir;
|
||||||
} moveblock;
|
} moveblock;
|
||||||
|
@ -169,11 +161,9 @@ extern "C" {
|
||||||
|
|
||||||
int distance(const struct region *, const struct region *);
|
int distance(const struct region *, const struct region *);
|
||||||
int koor_distance(int ax, int ay, int bx, int by);
|
int koor_distance(int ax, int ay, int bx, int by);
|
||||||
direction_t reldirection(const struct region *from, const struct region *to);
|
|
||||||
struct region *findregion(int x, int y);
|
struct region *findregion(int x, int y);
|
||||||
struct region *findregionbyid(int uid);
|
struct region *findregionbyid(int uid);
|
||||||
|
|
||||||
extern struct attrib_type at_direction;
|
|
||||||
extern struct attrib_type at_moveblock;
|
extern struct attrib_type at_moveblock;
|
||||||
extern struct attrib_type at_peasantluck;
|
extern struct attrib_type at_peasantluck;
|
||||||
extern struct attrib_type at_horseluck;
|
extern struct attrib_type at_horseluck;
|
||||||
|
@ -189,14 +179,6 @@ extern "C" {
|
||||||
void free_regionlist(region_list * rl);
|
void free_regionlist(region_list * rl);
|
||||||
void add_regionlist(region_list ** rl, struct region *r);
|
void add_regionlist(region_list ** rl, struct region *r);
|
||||||
|
|
||||||
struct region *find_special_direction(const struct region *r,
|
|
||||||
const char *token, const struct locale *lang);
|
|
||||||
void register_special_direction(const char *name);
|
|
||||||
struct spec_direction *special_direction(const region * from,
|
|
||||||
const region * to);
|
|
||||||
struct attrib *create_special_direction(struct region *r, struct region *rt,
|
|
||||||
int duration, const char *desc, const char *keyword, bool active);
|
|
||||||
|
|
||||||
int deathcount(const struct region *r);
|
int deathcount(const struct region *r);
|
||||||
int chaoscount(const struct region *r);
|
int chaoscount(const struct region *r);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ without prior permission by the authors of Eressea.
|
||||||
#include "spellbook.h"
|
#include "spellbook.h"
|
||||||
#include "calendar.h"
|
#include "calendar.h"
|
||||||
|
|
||||||
|
#include "vortex.h"
|
||||||
|
|
||||||
/* util includes */
|
/* util includes */
|
||||||
#include <util/attrib.h>
|
#include <util/attrib.h>
|
||||||
#include <util/bsdstring.h>
|
#include <util/bsdstring.h>
|
||||||
|
|
|
@ -31,8 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#include "bindings.h"
|
#include "bindings.h"
|
||||||
#include "races/races.h"
|
#include "races/races.h"
|
||||||
#include "spells/spells.h"
|
#include "spells.h"
|
||||||
#include "spells/borders.h"
|
|
||||||
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -266,7 +265,6 @@ int main(int argc, char **argv)
|
||||||
L = lua_init();
|
L = lua_init();
|
||||||
game_init();
|
game_init();
|
||||||
register_races();
|
register_races();
|
||||||
register_borders();
|
|
||||||
register_spells();
|
register_spells();
|
||||||
bind_monsters(L);
|
bind_monsters(L);
|
||||||
err = eressea_run(L, luafile);
|
err = eressea_run(L, luafile);
|
||||||
|
|
65
src/move.c
65
src/move.c
|
@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "move.h"
|
#include "move.h"
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
#include "alchemy.h"
|
#include "alchemy.h"
|
||||||
|
#include "vortex.h"
|
||||||
|
|
||||||
#include <kernel/build.h>
|
#include <kernel/build.h>
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
|
@ -543,6 +544,36 @@ void travelthru(const unit * u, region * r)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static direction_t
|
||||||
|
koor_reldirection(int ax, int ay, int bx, int by, const struct plane *pl)
|
||||||
|
{
|
||||||
|
int dir;
|
||||||
|
for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
|
||||||
|
int x = ax + delta_x[dir];
|
||||||
|
int y = ay + delta_y[dir];
|
||||||
|
pnormalize(&x, &y, pl);
|
||||||
|
if (bx == x && by == y)
|
||||||
|
return (direction_t)dir;
|
||||||
|
}
|
||||||
|
return NODIRECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
direction_t reldirection(const region * from, const region * to)
|
||||||
|
{
|
||||||
|
plane *pl = rplane(from);
|
||||||
|
if (pl == rplane(to)) {
|
||||||
|
direction_t dir = koor_reldirection(from->x, from->y, to->x, to->y, pl);
|
||||||
|
|
||||||
|
if (dir == NODIRECTION) {
|
||||||
|
spec_direction *sd = special_direction(from, to);
|
||||||
|
if (sd != NULL && sd->active)
|
||||||
|
return D_SPECIAL;
|
||||||
|
}
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
return NODIRECTION;
|
||||||
|
}
|
||||||
|
|
||||||
static void leave_trail(ship * sh, region * from, region_list * route)
|
static void leave_trail(ship * sh, region * from, region_list * route)
|
||||||
{
|
{
|
||||||
region *r = from;
|
region *r = from;
|
||||||
|
@ -1038,6 +1069,40 @@ unit *is_guarded(region * r, unit * u, unsigned int mask)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int movewhere(const unit * u, const char *token, region * r, region ** resultp)
|
||||||
|
{
|
||||||
|
region *r2;
|
||||||
|
direction_t d;
|
||||||
|
|
||||||
|
if (!token || *token == '\0') {
|
||||||
|
*resultp = NULL;
|
||||||
|
return E_MOVE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
d = get_direction(token, u->faction->locale);
|
||||||
|
switch (d) {
|
||||||
|
case D_PAUSE:
|
||||||
|
*resultp = r;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NODIRECTION:
|
||||||
|
r2 = find_special_direction(r, token, u->faction->locale);
|
||||||
|
if (r2 == NULL) {
|
||||||
|
return E_MOVE_NOREGION;
|
||||||
|
}
|
||||||
|
*resultp = r2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
r2 = rconnect(r, d);
|
||||||
|
if (r2 == NULL || move_blocked(u, r, r2)) {
|
||||||
|
return E_MOVE_BLOCKED;
|
||||||
|
}
|
||||||
|
*resultp = r2;
|
||||||
|
}
|
||||||
|
return E_MOVE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *shortdirections[MAXDIRECTIONS] = {
|
static const char *shortdirections[MAXDIRECTIONS] = {
|
||||||
"dir_nw",
|
"dir_nw",
|
||||||
"dir_ne",
|
"dir_ne",
|
||||||
|
|
79
src/move.h
79
src/move.h
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
|
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -18,61 +18,74 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
#ifndef H_KRNL_MOVEMENT
|
#ifndef H_KRNL_MOVEMENT
|
||||||
#define H_KRNL_MOVEMENT
|
#define H_KRNL_MOVEMENT
|
||||||
|
|
||||||
|
#include "direction.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct unit;
|
struct unit;
|
||||||
struct ship;
|
struct ship;
|
||||||
struct building_type;
|
struct building_type;
|
||||||
|
|
||||||
/* die Zahlen sind genau äquivalent zu den race Flags */
|
extern struct attrib_type at_speedup;
|
||||||
|
|
||||||
|
/* die Zahlen sind genau äquivalent zu den race Flags */
|
||||||
#define MV_CANNOTMOVE (1<<5)
|
#define MV_CANNOTMOVE (1<<5)
|
||||||
#define MV_FLY (1<<7) /* kann fliegen */
|
#define MV_FLY (1<<7) /* kann fliegen */
|
||||||
#define MV_SWIM (1<<8) /* kann schwimmen */
|
#define MV_SWIM (1<<8) /* kann schwimmen */
|
||||||
#define MV_WALK (1<<9) /* kann über Land gehen */
|
#define MV_WALK (1<<9) /* kann über Land gehen */
|
||||||
|
|
||||||
/* Die tragekapaz. ist hardcodiert mit defines, da es bis jetzt sowieso nur 2
|
/* Die tragekapaz. ist hardcodiert mit defines, da es bis jetzt sowieso nur 2
|
||||||
** objekte gibt, die etwas tragen. */
|
** objekte gibt, die etwas tragen. */
|
||||||
#define SILVERWEIGHT 1
|
#define SILVERWEIGHT 1
|
||||||
#define SCALEWEIGHT 100 /* Faktor, um den die Anzeige von gewichten
|
#define SCALEWEIGHT 100 /* Faktor, um den die Anzeige von gewichten
|
||||||
* * skaliert wird */
|
* * skaliert wird */
|
||||||
#define HORSECAPACITY 7000
|
#define HORSECAPACITY 7000
|
||||||
#define WAGONCAPACITY 14000
|
#define WAGONCAPACITY 14000
|
||||||
|
|
||||||
#define HORSESNEEDED 2
|
#define HORSESNEEDED 2
|
||||||
|
|
||||||
/* ein mensch wiegt 10, traegt also 5, ein pferd wiegt 50, traegt also 20. ein
|
/* ein mensch wiegt 10, traegt also 5, ein pferd wiegt 50, traegt also 20. ein
|
||||||
** wagen wird von zwei pferden gezogen und traegt total 140, davon 40 die
|
** wagen wird von zwei pferden gezogen und traegt total 140, davon 40 die
|
||||||
** pferde, macht nur noch 100, aber samt eigenem gewicht (40) macht also 140. */
|
** pferde, macht nur noch 100, aber samt eigenem gewicht (40) macht also 140. */
|
||||||
|
|
||||||
int personcapacity(const struct unit *u);
|
/* movewhere error codes */
|
||||||
void movement(void);
|
enum {
|
||||||
void run_to(struct unit *u, struct region *to);
|
E_MOVE_OK = 0, /* possible to move */
|
||||||
struct unit *is_guarded(struct region *r, struct unit *u, unsigned int mask);
|
E_MOVE_NOREGION, /* no region exists in this direction */
|
||||||
bool is_guard(const struct unit *u, int mask);
|
E_MOVE_BLOCKED /* cannot see this region, there is a blocking connection. */
|
||||||
int enoughsailors(const struct ship *sh, const struct region *r);
|
};
|
||||||
bool canswim(struct unit *u);
|
int movewhere(const struct unit *u, const char *token,
|
||||||
bool canfly(struct unit *u);
|
struct region *r, struct region **resultp);
|
||||||
struct unit *get_captain(const struct ship *sh);
|
direction_t reldirection(const struct region *from, const struct region *to);
|
||||||
void travelthru(const struct unit *u, struct region *r);
|
|
||||||
struct ship *move_ship(struct ship *sh, struct region *from,
|
int personcapacity(const struct unit *u);
|
||||||
struct region *to, struct region_list *route);
|
void movement(void);
|
||||||
int walkingcapacity(const struct unit *u);
|
void run_to(struct unit *u, struct region *to);
|
||||||
void follow_unit(struct unit *u);
|
struct unit *is_guarded(struct region *r, struct unit *u, unsigned int mask);
|
||||||
bool buildingtype_exists(const struct region *r,
|
bool is_guard(const struct unit *u, int mask);
|
||||||
const struct building_type *bt, bool working);
|
int enoughsailors(const struct ship *sh, const struct region *r);
|
||||||
struct unit *owner_buildingtyp(const struct region *r,
|
bool canswim(struct unit *u);
|
||||||
const struct building_type *bt);
|
bool canfly(struct unit *u);
|
||||||
|
struct unit *get_captain(const struct ship *sh);
|
||||||
|
void travelthru(const struct unit *u, struct region *r);
|
||||||
|
struct ship *move_ship(struct ship *sh, struct region *from,
|
||||||
|
struct region *to, struct region_list *route);
|
||||||
|
int walkingcapacity(const struct unit *u);
|
||||||
|
void follow_unit(struct unit *u);
|
||||||
|
bool buildingtype_exists(const struct region *r,
|
||||||
|
const struct building_type *bt, bool working);
|
||||||
|
struct unit *owner_buildingtyp(const struct region *r,
|
||||||
|
const struct building_type *bt);
|
||||||
|
|
||||||
extern struct attrib_type at_speedup;
|
|
||||||
|
|
||||||
#define SA_HARBOUR 2
|
#define SA_HARBOUR 2
|
||||||
#define SA_COAST 1
|
#define SA_COAST 1
|
||||||
#define SA_NO_INSECT -1
|
#define SA_NO_INSECT -1
|
||||||
#define SA_NO_COAST -2
|
#define SA_NO_COAST -2
|
||||||
|
|
||||||
extern int check_ship_allowed(struct ship *sh, const struct region * r);
|
int check_ship_allowed(struct ship *sh, const struct region * r);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
66
src/report.c
66
src/report.c
|
@ -38,6 +38,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "laws.h"
|
#include "laws.h"
|
||||||
#include "move.h"
|
#include "move.h"
|
||||||
#include "alchemy.h"
|
#include "alchemy.h"
|
||||||
|
#include "vortex.h"
|
||||||
|
|
||||||
/* kernel includes */
|
/* kernel includes */
|
||||||
#include <kernel/ally.h>
|
#include <kernel/ally.h>
|
||||||
|
@ -1127,46 +1128,47 @@ static void describe(FILE * F, const seen_region * sr, faction * f)
|
||||||
/* list directions */
|
/* list directions */
|
||||||
|
|
||||||
dh = false;
|
dh = false;
|
||||||
for (d = 0; d != MAXDIRECTIONS; d++)
|
for (d = 0; d != MAXDIRECTIONS; d++) {
|
||||||
if (see[d]) {
|
if (see[d]) {
|
||||||
region *r2 = rconnect(r, d);
|
region *r2 = rconnect(r, d);
|
||||||
if (!r2)
|
if (!r2)
|
||||||
continue;
|
continue;
|
||||||
nrd--;
|
nrd--;
|
||||||
if (dh) {
|
if (dh) {
|
||||||
char regname[4096];
|
char regname[4096];
|
||||||
if (nrd == 0) {
|
if (nrd == 0) {
|
||||||
|
bytes = (int)strlcpy(bufp, " ", size);
|
||||||
|
if (wrptr(&bufp, &size, bytes) != 0)
|
||||||
|
WARN_STATIC_BUFFER();
|
||||||
|
bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_nb_final"), size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_nb_next"), size);
|
||||||
|
}
|
||||||
|
if (wrptr(&bufp, &size, bytes) != 0)
|
||||||
|
WARN_STATIC_BUFFER();
|
||||||
|
bytes = (int)strlcpy(bufp, LOC(f->locale, directions[d]), size);
|
||||||
|
if (wrptr(&bufp, &size, bytes) != 0)
|
||||||
|
WARN_STATIC_BUFFER();
|
||||||
bytes = (int)strlcpy(bufp, " ", size);
|
bytes = (int)strlcpy(bufp, " ", size);
|
||||||
if (wrptr(&bufp, &size, bytes) != 0)
|
if (wrptr(&bufp, &size, bytes) != 0)
|
||||||
WARN_STATIC_BUFFER();
|
WARN_STATIC_BUFFER();
|
||||||
bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_nb_final"), size);
|
f_regionid(r2, f, regname, sizeof(regname));
|
||||||
|
bytes = _snprintf(bufp, size, trailinto(r2, f->locale), regname);
|
||||||
|
if (wrptr(&bufp, &size, bytes) != 0)
|
||||||
|
WARN_STATIC_BUFFER();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_nb_next"), size);
|
bytes = (int)strlcpy(bufp, " ", size);
|
||||||
|
if (wrptr(&bufp, &size, bytes) != 0)
|
||||||
|
WARN_STATIC_BUFFER();
|
||||||
|
MSG(("nr_vicinitystart", "dir region", d, r2), bufp, size, f->locale,
|
||||||
|
f);
|
||||||
|
bufp += strlen(bufp);
|
||||||
|
dh = true;
|
||||||
}
|
}
|
||||||
if (wrptr(&bufp, &size, bytes) != 0)
|
|
||||||
WARN_STATIC_BUFFER();
|
|
||||||
bytes = (int)strlcpy(bufp, LOC(f->locale, directions[d]), size);
|
|
||||||
if (wrptr(&bufp, &size, bytes) != 0)
|
|
||||||
WARN_STATIC_BUFFER();
|
|
||||||
bytes = (int)strlcpy(bufp, " ", size);
|
|
||||||
if (wrptr(&bufp, &size, bytes) != 0)
|
|
||||||
WARN_STATIC_BUFFER();
|
|
||||||
f_regionid(r2, f, regname, sizeof(regname));
|
|
||||||
bytes = _snprintf(bufp, size, trailinto(r2, f->locale), regname);
|
|
||||||
if (wrptr(&bufp, &size, bytes) != 0)
|
|
||||||
WARN_STATIC_BUFFER();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bytes = (int)strlcpy(bufp, " ", size);
|
|
||||||
if (wrptr(&bufp, &size, bytes) != 0)
|
|
||||||
WARN_STATIC_BUFFER();
|
|
||||||
MSG(("nr_vicinitystart", "dir region", d, r2), bufp, size, f->locale,
|
|
||||||
f);
|
|
||||||
bufp += strlen(bufp);
|
|
||||||
dh = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Spezielle Richtungen */
|
/* Spezielle Richtungen */
|
||||||
for (a = a_find(r->attribs, &at_direction); a && a->type == &at_direction;
|
for (a = a_find(r->attribs, &at_direction); a && a->type == &at_direction;
|
||||||
a = a->next) {
|
a = a->next) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,7 +6,6 @@ buildingcurse.c
|
||||||
combatspells.c
|
combatspells.c
|
||||||
regioncurse.c
|
regioncurse.c
|
||||||
shipcurse.c
|
shipcurse.c
|
||||||
spells.c
|
|
||||||
unitcurse.c
|
unitcurse.c
|
||||||
)
|
)
|
||||||
FOREACH(_FILE ${_FILES})
|
FOREACH(_FILE ${_FILES})
|
||||||
|
|
6805
src/spells/spells.c
6805
src/spells/spells.c
File diff suppressed because it is too large
Load Diff
|
@ -44,20 +44,21 @@ int RunAllTests(void)
|
||||||
ADD_TESTS(suite, equipment);
|
ADD_TESTS(suite, equipment);
|
||||||
ADD_TESTS(suite, item);
|
ADD_TESTS(suite, item);
|
||||||
ADD_TESTS(suite, magic);
|
ADD_TESTS(suite, magic);
|
||||||
ADD_TESTS(suite, move);
|
|
||||||
ADD_TESTS(suite, reports);
|
ADD_TESTS(suite, reports);
|
||||||
ADD_TESTS(suite, save);
|
ADD_TESTS(suite, save);
|
||||||
ADD_TESTS(suite, ship);
|
ADD_TESTS(suite, ship);
|
||||||
ADD_TESTS(suite, spellbook);
|
ADD_TESTS(suite, spellbook);
|
||||||
ADD_TESTS(suite, building);
|
ADD_TESTS(suite, building);
|
||||||
ADD_TESTS(suite, spell);
|
ADD_TESTS(suite, spell);
|
||||||
ADD_TESTS(suite, battle);
|
|
||||||
ADD_TESTS(suite, ally);
|
ADD_TESTS(suite, ally);
|
||||||
/* gamecode */
|
/* gamecode */
|
||||||
ADD_TESTS(suite, stealth);
|
ADD_TESTS(suite, battle);
|
||||||
ADD_TESTS(suite, market);
|
|
||||||
ADD_TESTS(suite, laws);
|
|
||||||
ADD_TESTS(suite, economy);
|
ADD_TESTS(suite, economy);
|
||||||
|
ADD_TESTS(suite, laws);
|
||||||
|
ADD_TESTS(suite, market);
|
||||||
|
ADD_TESTS(suite, move);
|
||||||
|
ADD_TESTS(suite, stealth);
|
||||||
|
ADD_TESTS(suite, vortex);
|
||||||
|
|
||||||
CuSuiteRun(suite);
|
CuSuiteRun(suite);
|
||||||
CuSuiteSummary(suite, output);
|
CuSuiteSummary(suite, output);
|
||||||
|
|
|
@ -0,0 +1,190 @@
|
||||||
|
#include <config.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include "vortex.h"
|
||||||
|
|
||||||
|
#include <kernel/config.h>
|
||||||
|
#include <kernel/version.h>
|
||||||
|
#include <kernel/region.h>
|
||||||
|
|
||||||
|
#include <util/attrib.h>
|
||||||
|
#include <util/language.h>
|
||||||
|
#include <util/log.h>
|
||||||
|
#include <util/umlaut.h>
|
||||||
|
#include <util/variant.h>
|
||||||
|
|
||||||
|
#include <storage.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
typedef struct dir_lookup {
|
||||||
|
char *name;
|
||||||
|
const char *oldname;
|
||||||
|
struct dir_lookup *next;
|
||||||
|
} dir_lookup;
|
||||||
|
|
||||||
|
static dir_lookup *dir_name_lookup;
|
||||||
|
|
||||||
|
void register_special_direction(const char *name)
|
||||||
|
{
|
||||||
|
struct locale *lang;
|
||||||
|
char *str = _strdup(name);
|
||||||
|
|
||||||
|
for (lang = locales; lang; lang = nextlocale(lang)) {
|
||||||
|
void **tokens = get_translations(lang, UT_SPECDIR);
|
||||||
|
const char *token = LOC(lang, name);
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
variant var;
|
||||||
|
|
||||||
|
var.v = str;
|
||||||
|
addtoken(tokens, token, var);
|
||||||
|
|
||||||
|
if (lang == default_locale) {
|
||||||
|
dir_lookup *dl = malloc(sizeof(dir_lookup));
|
||||||
|
dl->name = str;
|
||||||
|
dl->oldname = token;
|
||||||
|
dl->next = dir_name_lookup;
|
||||||
|
dir_name_lookup = dl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log_error("no translation for spec_direction '%s' in locale '%s'\n", name, locale_name(lang));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************/
|
||||||
|
/* at_direction */
|
||||||
|
/********************/
|
||||||
|
static void a_initdirection(attrib * a)
|
||||||
|
{
|
||||||
|
a->data.v = calloc(1, sizeof(spec_direction));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void a_freedirection(attrib * a)
|
||||||
|
{
|
||||||
|
free(a->data.v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int a_agedirection(attrib * a)
|
||||||
|
{
|
||||||
|
spec_direction *d = (spec_direction *)(a->data.v);
|
||||||
|
--d->duration;
|
||||||
|
return (d->duration > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int a_readdirection(attrib * a, void *owner, struct storage *store)
|
||||||
|
{
|
||||||
|
spec_direction *d = (spec_direction *)(a->data.v);
|
||||||
|
|
||||||
|
_CRT_UNUSED(owner);
|
||||||
|
READ_INT(store, &d->x);
|
||||||
|
READ_INT(store, &d->y);
|
||||||
|
READ_INT(store, &d->duration);
|
||||||
|
if (global.data_version < UNICODE_VERSION) {
|
||||||
|
char lbuf[16];
|
||||||
|
dir_lookup *dl = dir_name_lookup;
|
||||||
|
|
||||||
|
READ_TOK(store, NULL, 0);
|
||||||
|
READ_TOK(store, lbuf, sizeof(lbuf));
|
||||||
|
|
||||||
|
cstring_i(lbuf);
|
||||||
|
for (; dl; dl = dl->next) {
|
||||||
|
if (strcmp(lbuf, dl->oldname) == 0) {
|
||||||
|
d->keyword = _strdup(dl->name);
|
||||||
|
_snprintf(lbuf, sizeof(lbuf), "%s_desc", d->keyword);
|
||||||
|
d->desc = _strdup(dl->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dl == NULL) {
|
||||||
|
log_error("unknown spec_direction '%s'\n", lbuf);
|
||||||
|
assert(!"not implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char lbuf[32];
|
||||||
|
READ_TOK(store, lbuf, sizeof(lbuf));
|
||||||
|
d->desc = _strdup(lbuf);
|
||||||
|
READ_TOK(store, lbuf, sizeof(lbuf));
|
||||||
|
d->keyword = _strdup(lbuf);
|
||||||
|
}
|
||||||
|
d->active = true;
|
||||||
|
return AT_READ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
a_writedirection(const attrib * a, const void *owner, struct storage *store)
|
||||||
|
{
|
||||||
|
spec_direction *d = (spec_direction *)(a->data.v);
|
||||||
|
|
||||||
|
_CRT_UNUSED(owner);
|
||||||
|
WRITE_INT(store, d->x);
|
||||||
|
WRITE_INT(store, d->y);
|
||||||
|
WRITE_INT(store, d->duration);
|
||||||
|
WRITE_TOK(store, d->desc);
|
||||||
|
WRITE_TOK(store, d->keyword);
|
||||||
|
}
|
||||||
|
attrib_type at_direction = {
|
||||||
|
"direction",
|
||||||
|
a_initdirection,
|
||||||
|
a_freedirection,
|
||||||
|
a_agedirection,
|
||||||
|
a_writedirection,
|
||||||
|
a_readdirection
|
||||||
|
};
|
||||||
|
|
||||||
|
region *find_special_direction(const region * r, const char *token,
|
||||||
|
const struct locale *lang)
|
||||||
|
{
|
||||||
|
attrib *a;
|
||||||
|
spec_direction *d;
|
||||||
|
|
||||||
|
if (strlen(token) == 0)
|
||||||
|
return NULL;
|
||||||
|
for (a = a_find(r->attribs, &at_direction); a && a->type == &at_direction;
|
||||||
|
a = a->next) {
|
||||||
|
d = (spec_direction *)(a->data.v);
|
||||||
|
|
||||||
|
if (d->active) {
|
||||||
|
void **tokens = get_translations(lang, UT_SPECDIR);
|
||||||
|
variant var;
|
||||||
|
if (findtoken(*tokens, token, &var) == E_TOK_SUCCESS) {
|
||||||
|
if (strcmp((const char *)var.v, d->keyword) == 0) {
|
||||||
|
return findregion(d->x, d->y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
attrib *create_special_direction(region * r, region * rt, int duration,
|
||||||
|
const char *desc, const char *keyword, bool active)
|
||||||
|
{
|
||||||
|
attrib *a = a_add(&r->attribs, a_new(&at_direction));
|
||||||
|
spec_direction *d = (spec_direction *)(a->data.v);
|
||||||
|
|
||||||
|
d->active = active;
|
||||||
|
d->x = rt->x;
|
||||||
|
d->y = rt->y;
|
||||||
|
d->duration = duration;
|
||||||
|
d->desc = _strdup(desc);
|
||||||
|
d->keyword = _strdup(keyword);
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
spec_direction *special_direction(const region * from, const region * to)
|
||||||
|
{
|
||||||
|
const attrib *a = a_findc(from->attribs, &at_direction);
|
||||||
|
|
||||||
|
while (a != NULL && a->type == &at_direction) {
|
||||||
|
spec_direction *sd = (spec_direction *)a->data.v;
|
||||||
|
if (sd->x == to->x && sd->y == to->y)
|
||||||
|
return sd;
|
||||||
|
a = a->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef H_VORTEX
|
||||||
|
#define H_VORTEX
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct region;
|
||||||
|
struct attrib;
|
||||||
|
struct locale;
|
||||||
|
|
||||||
|
typedef struct spec_direction {
|
||||||
|
int x, y;
|
||||||
|
int duration;
|
||||||
|
bool active;
|
||||||
|
char *desc;
|
||||||
|
char *keyword;
|
||||||
|
} spec_direction;
|
||||||
|
|
||||||
|
extern struct attrib_type at_direction;
|
||||||
|
|
||||||
|
struct region *find_special_direction(const struct region *r,
|
||||||
|
const char *token, const struct locale *lang);
|
||||||
|
void register_special_direction(const char *name);
|
||||||
|
struct spec_direction *special_direction(const struct region * from,
|
||||||
|
const struct region * to);
|
||||||
|
struct attrib *create_special_direction(struct region *r, struct region *rt,
|
||||||
|
int duration, const char *desc, const char *keyword, bool active);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include <platform.h>
|
||||||
|
#include <kernel/types.h>
|
||||||
|
|
||||||
|
#include "vortex.h"
|
||||||
|
#include "move.h"
|
||||||
|
#include "tests.h"
|
||||||
|
|
||||||
|
#include <kernel/config.h>
|
||||||
|
#include <kernel/region.h>
|
||||||
|
#include <kernel/terrain.h>
|
||||||
|
#include <kernel/unit.h>
|
||||||
|
#include <kernel/race.h>
|
||||||
|
|
||||||
|
#include <util/language.h>
|
||||||
|
|
||||||
|
#include <CuTest.h>
|
||||||
|
|
||||||
|
static void test_move_to_vortex(CuTest *tc) {
|
||||||
|
region *r1, *r2, *r = 0;
|
||||||
|
terrain_type *t_plain;
|
||||||
|
unit *u;
|
||||||
|
struct locale *lang;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
lang = get_or_create_locale("en");
|
||||||
|
locale_setstring(lang, "vortex", "wirbel");
|
||||||
|
init_locale(lang);
|
||||||
|
register_special_direction("vortex");
|
||||||
|
t_plain = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION);
|
||||||
|
r1 = test_create_region(0, 0, t_plain);
|
||||||
|
r2 = test_create_region(5, 0, t_plain);
|
||||||
|
CuAssertPtrNotNull(tc, create_special_direction(r1, r2, 10, "", "vortex", true));
|
||||||
|
u = test_create_unit(test_create_faction(rc_get_or_create("hodor")), r1);
|
||||||
|
CuAssertIntEquals(tc, E_MOVE_NOREGION, movewhere(u, "barf", r1, &r));
|
||||||
|
CuAssertIntEquals(tc, E_MOVE_OK, movewhere(u, "wirbel", r1, &r));
|
||||||
|
CuAssertPtrEquals(tc, r2, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_vortex(CuTest *tc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
CuSuite *get_vortex_suite(void)
|
||||||
|
{
|
||||||
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_vortex);
|
||||||
|
SUITE_ADD_TEST(suite, test_move_to_vortex);
|
||||||
|
return suite;
|
||||||
|
}
|
Loading…
Reference in New Issue