server/src/vortex.c

161 lines
3.7 KiB
C

#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>
#include <string.h>
#include <stdlib.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(struct locale *lang, const char *name)
{
const char *token = locale_string(lang, name, false);
if (token) {
void **tokens = get_translations(lang, UT_SPECDIR);
variant var;
char *str = _strdup(name);
var.v = str;
addtoken(tokens, token, var);
if (lang == locales) {
dir_lookup *dl = malloc(sizeof(dir_lookup));
dl->name = str;
dl->oldname = token;
dl->next = dir_name_lookup;
dir_name_lookup = dl;
}
}
else {
log_debug("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)
{
spec_direction *d = (spec_direction *)(a->data.v);
free(d->desc);
free(d->keyword);
free(d);
}
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);
char lbuf[32];
(void)owner;
READ_INT(store, &d->x);
READ_INT(store, &d->y);
READ_INT(store, &d->duration);
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);
(void)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)
{
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 && strcmp(token, 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;
}