make attrib use a variant, not a custom union.

change attrib_type methods to take a variant, not the entire attrib.
This commit is contained in:
Enno Rehling 2018-02-09 21:20:43 +01:00
parent cfc3171021
commit 1035a98fd3
36 changed files with 282 additions and 323 deletions

View File

@ -284,13 +284,9 @@ typedef struct potiondelay {
int amount;
} potiondelay;
static void init_potiondelay(attrib * a)
static void init_potiondelay(variant *var)
{
a->data.v = malloc(sizeof(potiondelay));
}
static void free_potiondelay(attrib * a) {
free(a->data.v);
var->v = malloc(sizeof(potiondelay));
}
static int age_potiondelay(attrib * a, void *owner)
@ -304,7 +300,7 @@ static int age_potiondelay(attrib * a, void *owner)
attrib_type at_potiondelay = {
"potiondelay",
init_potiondelay,
free_potiondelay,
a_free_voidptr,
age_potiondelay, 0, 0
};
@ -337,31 +333,26 @@ struct order *ord)
/* at_effect */
/*****************/
static void a_initeffect(attrib * a)
static void a_initeffect(variant *var)
{
a->data.v = calloc(sizeof(effect_data), 1);
}
static void a_finalizeeffect(attrib * a) /*-V524 */
{
free(a->data.v);
var->v = calloc(sizeof(effect_data), 1);
}
static void
a_writeeffect(const attrib * a, const void *owner, struct storage *store)
a_writeeffect(const variant *var, const void *owner, struct storage *store)
{
effect_data *edata = (effect_data *)a->data.v;
effect_data *edata = (effect_data *)var->v;
UNUSED_ARG(owner);
WRITE_TOK(store, resourcename(edata->type->rtype, 0));
WRITE_INT(store, edata->value);
}
static int a_readeffect(attrib * a, void *owner, struct gamedata *data)
static int a_readeffect(variant *var, void *owner, struct gamedata *data)
{
struct storage *store = data->store;
int power;
const resource_type *rtype;
effect_data *edata = (effect_data *)a->data.v;
effect_data *edata = (effect_data *)var->v;
char zText[32];
UNUSED_ARG(owner);
@ -386,7 +377,7 @@ static int a_readeffect(attrib * a, void *owner, struct gamedata *data)
attrib_type at_effect = {
"effect",
a_initeffect,
a_finalizeeffect,
a_free_voidptr,
DEFAULT_AGE,
a_writeeffect,
a_readeffect,

View File

@ -68,42 +68,45 @@ typedef struct obs_data {
int timer;
} obs_data;
static void obs_init(struct attrib *a)
static void obs_init(variant *var)
{
a->data.v = malloc(sizeof(obs_data));
}
static void obs_done(struct attrib *a)
{
free(a->data.v);
var->v = malloc(sizeof(obs_data));
}
static int obs_age(struct attrib *a, void *owner)
{
obs_data *od = (obs_data *)a->data.v;
UNUSED_ARG(owner);
update_interval(od->f, (region *)owner);
return --od->timer;
}
static void obs_write(const struct attrib *a, const void *owner, struct storage *store)
static void obs_write(const variant *var, const void *owner,
struct storage *store)
{
obs_data *od = (obs_data *)a->data.v;
obs_data *od = (obs_data *)var->v;
UNUSED_ARG(owner);
write_faction_reference(od->f, store);
WRITE_INT(store, od->skill);
WRITE_INT(store, od->timer);
}
static int obs_read(struct attrib *a, void *owner, struct gamedata *data)
static int obs_read(variant *var, void *owner, struct gamedata *data)
{
obs_data *od = (obs_data *)a->data.v;
obs_data *od = (obs_data *)var->v;
UNUSED_ARG(owner);
read_faction_reference(data, &od->f, NULL);
READ_INT(data->store, &od->skill);
READ_INT(data->store, &od->timer);
return AT_READ_OK;
}
attrib_type at_observer = { "observer", obs_init, obs_done, obs_age, obs_write, obs_read };
attrib_type at_observer = {
"observer", obs_init, a_free_voidptr, obs_age, obs_write, obs_read
};
static attrib *make_observer(faction *f, int perception)
{
@ -154,10 +157,11 @@ attrib_type at_unitdissolve = {
"unitdissolve", NULL, NULL, NULL, a_writechars, a_readchars
};
static int read_ext(attrib * a, void *owner, gamedata *data)
static int read_ext(variant *var, void *owner, gamedata *data)
{
int len;
UNUSED_ARG(var);
READ_INT(data->store, &len);
data->store->api->r_bin(data->store->handle, NULL, (size_t)len);
return AT_READ_OK;

View File

@ -62,11 +62,11 @@ typedef struct dict_data {
} data;
} dict_data;
static int dict_read(attrib * a, void *owner, gamedata *data)
static int dict_read(variant * var, void *owner, gamedata *data)
{
storage *store = data->store;
char name[NAMESIZE];
dict_data *dd = (dict_data *)a->data.v;
dict_data *dd = (dict_data *)var->v;
int n;
READ_STR(store, name, sizeof(name));
@ -88,19 +88,19 @@ static int dict_read(attrib * a, void *owner, gamedata *data)
return AT_READ_DEPR;
}
static void dict_init(attrib * a)
static void dict_init(variant *var)
{
dict_data *dd;
a->data.v = malloc(sizeof(dict_data));
dd = (dict_data *)a->data.v;
var->v = malloc(sizeof(dict_data));
dd = (dict_data *)var->v;
dd->type = TNONE;
}
static void dict_done(attrib * a)
static void dict_done(variant *var)
{
dict_data *dd = (dict_data *)a->data.v;
dict_data *dd = (dict_data *)var->v;
free(dd->name);
free(a->data.v);
free(var->v);
}
static void upgrade_keyval(const dict_data *dd, int keyval[], int v) {

View File

@ -28,7 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <storage.h>
static int read_follow(attrib * a, void *owner, gamedata *data)
static int read_follow(variant * var, void *owner, gamedata *data)
{
READ_INT(data->store, NULL); /* skip it */
return AT_READ_FAIL;

View File

@ -39,14 +39,14 @@ static int verify_hate(attrib * a, void *owner)
}
static void
write_hate(const attrib * a, const void *owner, struct storage *store)
write_hate(const variant *var, const void *owner, struct storage *store)
{
write_unit_reference((unit *)a->data.v, store);
write_unit_reference((unit *)var->v, store);
}
static int read_hate(attrib * a, void *owner, gamedata *data)
static int read_hate(variant *var, void *owner, gamedata *data)
{
if (read_unit_reference(data, (unit **)&a->data.v, NULL) <= 0) {
if (read_unit_reference(data, (unit **)&var->v, NULL) <= 0) {
return AT_READ_FAIL;
}
return AT_READ_OK;

View File

@ -29,8 +29,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h>
#include <assert.h>
static void a_writekeys(const attrib *a, const void *o, storage *store) {
int i, *keys = (int *)a->data.v;
static void a_writekeys(const variant *var, const void *o, storage *store) {
int i, *keys = (int *)var->v;
int n = 0;
if (keys) {
assert(keys[0] < 4096 && keys[0]>0);
@ -76,7 +76,7 @@ static int keys_size(int n) {
return 4096;
}
static int a_readkeys(attrib * a, void *owner, gamedata *data) {
static int a_readkeys(variant *var, void *owner, gamedata *data) {
int i, n, *keys;
READ_INT(data->store, &n);
@ -135,26 +135,22 @@ static int a_readkeys(attrib * a, void *owner, gamedata *data) {
}
}
}
a->data.v = keys;
var->v = keys;
return AT_READ_OK;
}
static int a_readkey(attrib *a, void *owner, struct gamedata *data) {
int res = a_readint(a, owner, data);
static int a_readkey(variant *var, void *owner, struct gamedata *data) {
int res = a_readint(var, owner, data);
if (data->version >= KEYVAL_VERSION) {
return AT_READ_FAIL;
}
return (res != AT_READ_FAIL) ? AT_READ_DEPR : res;
}
static void a_freekeys(attrib *a) {
free(a->data.v);
}
attrib_type at_keys = {
"keys",
NULL,
a_freekeys,
a_free_voidptr,
NULL,
a_writekeys,
a_readkeys,

View File

@ -34,15 +34,15 @@ static int age_moved(attrib * a, void *owner)
}
static void
write_moved(const attrib * a, const void *owner, struct storage *store)
write_moved(const variant *var, const void *owner, struct storage *store)
{
WRITE_INT(store, a->data.i);
WRITE_INT(store, var->i);
}
static int read_moved(attrib * a, void *owner, gamedata *data)
static int read_moved(variant *var, void *owner, gamedata *data)
{
READ_INT(data->store, &a->data.i);
if (a->data.i != 0)
READ_INT(data->store, &var->i);
if (var->i != 0)
return AT_READ_OK;
else
return AT_READ_FAIL;

View File

@ -29,23 +29,17 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <limits.h>
#include <assert.h>
static void
write_movement(const attrib * a, const void *owner, struct storage *store)
static int read_movement(variant *var, void *owner, gamedata *data)
{
WRITE_INT(store, a->data.i);
}
static int read_movement(attrib * a, void *owner, gamedata *data)
{
READ_INT(data->store, &a->data.i);
if (a->data.i != 0)
READ_INT(data->store, &var->i);
if (var->i != 0)
return AT_READ_OK;
else
return AT_READ_FAIL;
}
attrib_type at_movement = {
"movement", NULL, NULL, NULL, write_movement, read_movement
"movement", NULL, NULL, NULL, a_writeint, read_movement
};
bool get_movement(attrib * const *alist, int type)

View File

@ -33,20 +33,20 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* simple attributes that do not yet have their own file
*/
void write_of(const struct attrib *a, const void *owner, struct storage *store)
void write_of(const variant *var, const void *owner, struct storage *store)
{
const faction *f = (faction *)a->data.v;
const faction *f = (faction *)var->v;
WRITE_INT(store, f->no);
}
int read_of(struct attrib *a, void *owner, gamedata *data)
int read_of(variant *var, void *owner, gamedata *data)
{ /* return 1 on success, 0 if attrib needs removal */
int of;
READ_INT(data->store, &of);
if (rule_stealth_other()) {
a->data.v = findfaction(of);
if (a->data.v) {
var->v = findfaction(of);
if (var->v) {
return AT_READ_OK;
}
}

View File

@ -43,7 +43,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* Spruch zu seiner List-of-known-spells hinzugefügt werden.
*/
static int read_seenspell(attrib * a, void *owner, struct gamedata *data)
static int read_seenspell(variant *var, void *owner, struct gamedata *data)
{
storage *store = data->store;
spell *sp = 0;
@ -59,14 +59,14 @@ static int read_seenspell(attrib * a, void *owner, struct gamedata *data)
log_info("read_seenspell: could not find spell '%s'\n", token);
return AT_READ_FAIL;
}
a->data.v = sp;
var->v = sp;
return AT_READ_OK;
}
static void
write_seenspell(const attrib * a, const void *owner, struct storage *store)
write_seenspell(const variant *var, const void *owner, struct storage *store)
{
const spell *sp = (const spell *)a->data.v;
const spell *sp = (const spell *)var->v;
UNUSED_ARG(owner);
WRITE_TOK(store, sp->sname);
}

View File

@ -29,14 +29,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <storage.h>
static void
write_targetregion(const attrib * a, const void *owner, struct storage *store)
write_targetregion(const variant *var, const void *owner, struct storage *store)
{
write_region_reference((region *)a->data.v, store);
write_region_reference((region *)var->v, store);
}
static int read_targetregion(attrib * a, void *owner, gamedata *data)
static int read_targetregion(variant *var, void *owner, gamedata *data)
{
if (read_region_reference(data, (region **)&a->data.v, NULL) <= 0) {
if (read_region_reference(data, (region **)&var->v, NULL) <= 0) {
return AT_READ_FAIL;
}
return AT_READ_OK;

View File

@ -1432,10 +1432,10 @@ int make_cmd(unit * u, struct order *ord)
/* ------------------------------------------------------------- */
static void free_luxuries(struct attrib *a)
static void free_luxuries(variant *var)
{
item *itm = (item *)a->data.v;
a->data.v = NULL;
item *itm = (item *)var->v;
var->v = NULL;
i_freeall(&itm);
}

View File

@ -306,12 +306,12 @@ struct trigger_type tt_caldera = {
};
static int building_action_read(struct attrib *a, void *owner, gamedata *data)
static int building_action_read(variant *var, void *owner, gamedata *data)
{
struct storage *store = data->store;
UNUSED_ARG(owner);
UNUSED_ARG(a);
UNUSED_ARG(var);
if (data->version < ATTRIBOWNER_VERSION) {
READ_INT(data->store, NULL);

View File

@ -136,9 +136,9 @@ static int ally_mode(const ally * sf, int mode)
return sf->status & mode;
}
static void init_npcfaction(struct attrib *a)
static void init_npcfaction(variant *var)
{
a->data.i = 1;
var->i = 1;
}
attrib_type at_npcfaction = {

View File

@ -102,9 +102,9 @@ static void cunhash(curse * c)
/* ------------------------------------------------------------- */
/* at_curse */
void curse_init(attrib * a)
void curse_init(variant *var)
{
a->data.v = calloc(1, sizeof(curse));
var->v = calloc(1, sizeof(curse));
}
int curse_age(attrib * a, void *owner)
@ -133,9 +133,9 @@ void destroy_curse(curse * c)
free(c);
}
void curse_done(attrib * a)
void curse_done(variant * var)
{
destroy_curse((curse *)a->data.v);
destroy_curse((curse *)var->v);
}
/** reads curses that have been removed from the code */
@ -177,10 +177,10 @@ static int read_ccompat(const char *cursename, struct storage *store)
return -1;
}
int curse_read(attrib * a, void *owner, gamedata *data)
int curse_read(variant *var, void *owner, gamedata *data)
{
storage *store = data->store;
curse *c = (curse *)a->data.v;
curse *c = (curse *)var->v;
int ur;
char cursename[64];
int n;
@ -238,9 +238,9 @@ int curse_read(attrib * a, void *owner, gamedata *data)
return AT_READ_OK;
}
void curse_write(const attrib * a, const void *owner, struct storage *store)
void curse_write(const variant * var, const void *owner, struct storage *store)
{
curse *c = (curse *)a->data.v;
curse *c = (curse *)var->v;
const curse_type *ct = c->type;
unit *mage = (c->magician && c->magician->number) ? c->magician : NULL;

View File

@ -221,9 +221,9 @@ extern "C" {
void curses_done(void); /* de-register all curse-types */
void curse_write(const struct attrib *a, const void *owner,
void curse_write(const union variant *v, const void *owner,
struct storage *store);
int curse_read(struct attrib *a, void *owner, struct gamedata *store);
int curse_read(union variant *v, void *owner, struct gamedata *store);
/* ------------------------------------------------------------- */
/* Kommentare:
@ -291,8 +291,8 @@ extern "C" {
curse *findcurse(int curseid);
void curse_init(struct attrib *a);
void curse_done(struct attrib *a);
void curse_init(union variant *a);
void curse_done(union variant *a);
int curse_age(struct attrib *a, void *owner);
double destr_curse(struct curse *c, int cast_level, double force);

View File

@ -96,14 +96,14 @@ static group *find_group(int gid)
return g;
}
static int read_group(attrib * a, void *owner, gamedata *data)
static int read_group(variant *var, void *owner, gamedata *data)
{
struct storage *store = data->store;
group *g;
int gid;
READ_INT(store, &gid);
a->data.v = g = find_group(gid);
var->v = g = find_group(gid);
if (g != 0) {
g->members++;
return AT_READ_OK;
@ -112,9 +112,9 @@ static int read_group(attrib * a, void *owner, gamedata *data)
}
static void
write_group(const attrib * a, const void *owner, struct storage *store)
write_group(const variant *var, const void *owner, struct storage *store)
{
group *g = (group *)a->data.v;
group *g = (group *)var->v;
WRITE_INT(store, g->gid);
}

View File

@ -181,14 +181,14 @@ void deathcounts(region * r, int fallen)
/********************/
/* at_moveblock */
/********************/
void a_initmoveblock(attrib * a)
void a_initmoveblock(variant *var)
{
a->data.v = calloc(1, sizeof(moveblock));
var->v = calloc(1, sizeof(moveblock));
}
int a_readmoveblock(attrib * a, void *owner, gamedata *data)
int a_readmoveblock(variant *var, void *owner, gamedata *data)
{
moveblock *m = (moveblock *)(a->data.v);
moveblock *m = (moveblock *)var->v;
int i;
READ_INT(data->store, &i);
@ -197,9 +197,9 @@ int a_readmoveblock(attrib * a, void *owner, gamedata *data)
}
void
a_writemoveblock(const attrib * a, const void *owner, struct storage *store)
a_writemoveblock(const variant *var, const void *owner, struct storage *store)
{
moveblock *m = (moveblock *)(a->data.v);
moveblock *m = (moveblock *)var->v;
WRITE_INT(store, (int)m->dir);
}

View File

@ -40,21 +40,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h>
/** skillmod attribut **/
static void init_skillmod(attrib * a)
static void init_skillmod(variant *var)
{
a->data.v = calloc(sizeof(skillmod_data), 1);
}
static void finalize_skillmod(attrib * a)
{
free(a->data.v);
var->v = calloc(sizeof(skillmod_data), 1);
}
/** temporary skill modification (NOT SAVED!). */
attrib_type at_skillmod = {
"skillmod",
init_skillmod,
finalize_skillmod,
a_free_voidptr,
NULL,
NULL, /* can't write function pointers */
NULL, /* can't read function pointers */

View File

@ -506,13 +506,13 @@ int ualias(const unit * u)
return a->data.i;
}
int a_readprivate(attrib * a, void *owner, gamedata *data)
int a_readprivate(variant *var, void *owner, gamedata *data)
{
struct storage *store = data->store;
char lbuf[DISPLAYSIZE];
READ_STR(store, lbuf, sizeof(lbuf));
a->data.v = str_strdup(lbuf);
return (a->data.v) ? AT_READ_OK : AT_READ_FAIL;
var->v = str_strdup(lbuf);
return (var->v) ? AT_READ_OK : AT_READ_FAIL;
}
/*********************/
@ -644,15 +644,15 @@ void usettarget(unit * u, const unit * t)
/* at_siege */
/*********************/
void a_writesiege(const attrib * a, const void *owner, struct storage *store)
void a_writesiege(const variant *var, const void *owner, struct storage *store)
{
struct building *b = (struct building *)a->data.v;
struct building *b = (struct building *)var->v;
write_building_reference(b, store);
}
int a_readsiege(attrib * a, void *owner, gamedata *data)
int a_readsiege(variant *var, void *owner, gamedata *data)
{
if (read_building_reference(data, (building **)&a->data.v, NULL) <= 0) {
if (read_building_reference(data, (building **)&var->v, NULL) <= 0) {
return AT_READ_FAIL;
}
return AT_READ_OK;

View File

@ -126,10 +126,10 @@ typedef struct icastle_data {
int time;
} icastle_data;
static int a_readicastle(attrib * a, void *owner, struct gamedata *data)
static int a_readicastle(variant *var, void *owner, struct gamedata *data)
{
storage *store = data->store;
icastle_data *idata = (icastle_data *)a->data.v;
icastle_data *idata = (icastle_data *)var->v;
char token[32];
UNUSED_ARG(owner);
@ -143,9 +143,9 @@ static int a_readicastle(attrib * a, void *owner, struct gamedata *data)
}
static void
a_writeicastle(const attrib * a, const void *owner, struct storage *store)
a_writeicastle(const variant *var, const void *owner, struct storage *store)
{
icastle_data *data = (icastle_data *)a->data.v;
icastle_data *data = (icastle_data *)var->v;
UNUSED_ARG(owner);
WRITE_TOK(store, data->type->_name);
WRITE_INT(store, data->time);
@ -168,20 +168,15 @@ static int a_ageicastle(struct attrib *a, void *owner)
return AT_AGE_KEEP;
}
static void a_initicastle(struct attrib *a)
static void a_initicastle(variant *var)
{
a->data.v = calloc(sizeof(icastle_data), 1);
}
static void a_finalizeicastle(struct attrib *a) /*-V524 */
{
free(a->data.v);
var->v = calloc(sizeof(icastle_data), 1);
}
attrib_type at_icastle = {
"zauber_icastle",
a_initicastle,
a_finalizeicastle,
a_free_voidptr,
a_ageicastle,
a_writeicastle,
a_readicastle
@ -207,14 +202,14 @@ extern int dice(int count, int value);
* Umwandlung von alt nach neu gebraucht werden */
/* ------------------------------------------------------------- */
static void init_mage(attrib * a)
static void init_mage(variant *var)
{
a->data.v = calloc(sizeof(sc_mage), 1);
var->v = calloc(sizeof(sc_mage), 1);
}
static void free_mage(attrib * a)
static void free_mage(variant *var)
{
sc_mage *mage = (sc_mage *)a->data.v;
sc_mage *mage = (sc_mage *)var->v;
if (mage->spellbook) {
spellbook_clear(mage->spellbook);
free(mage->spellbook);
@ -239,11 +234,11 @@ int get_spell_level_mage(const spell * sp, void * cbdata)
return sbe ? sbe->level : 0;
}
static int read_mage(attrib * a, void *owner, struct gamedata *data)
static int read_mage(variant *var, void *owner, struct gamedata *data)
{
storage *store = data->store;
int i, mtype;
sc_mage *mage = (sc_mage *)a->data.v;
sc_mage *mage = (sc_mage *)var->v;
char spname[64];
UNUSED_ARG(owner);
@ -287,10 +282,10 @@ static int read_mage(attrib * a, void *owner, struct gamedata *data)
}
static void
write_mage(const attrib * a, const void *owner, struct storage *store)
write_mage(const variant *var, const void *owner, struct storage *store)
{
int i;
sc_mage *mage = (sc_mage *)a->data.v;
sc_mage *mage = (sc_mage *)var->v;
UNUSED_ARG(owner);
WRITE_INT(store, mage->magietyp);
@ -2090,9 +2085,9 @@ bool is_familiar(const unit * u)
}
static void
a_write_unit(const attrib * a, const void *owner, struct storage *store)
a_write_unit(const variant *var, const void *owner, struct storage *store)
{
unit *u = (unit *)a->data.v;
unit *u = (unit *)var->v;
UNUSED_ARG(owner);
write_unit_reference(u, store);
}
@ -2208,10 +2203,10 @@ static void * resolve_familiar(int id, void *data) {
return data;
}
static int read_familiar(attrib * a, void *owner, struct gamedata *data)
static int read_familiar(variant *var, void *owner, struct gamedata *data)
{
UNUSED_ARG(owner);
if (read_unit_reference(data, (unit **)&a->data.v, resolve_familiar) <= 0) {
if (read_unit_reference(data, (unit **)&var->v, resolve_familiar) <= 0) {
return AT_READ_FAIL;
}
return AT_READ_OK;
@ -2289,10 +2284,10 @@ static void * resolve_clone(int id, void *data) {
return data;
}
static int read_clone(attrib * a, void *owner, struct gamedata *data)
static int read_clone(variant *var, void *owner, struct gamedata *data)
{
UNUSED_ARG(owner);
if (read_unit_reference(data, (unit **)&a->data.v, resolve_clone) <= 0) {
if (read_unit_reference(data, (unit **)&var->v, resolve_clone) <= 0) {
return AT_READ_FAIL;
}
return AT_READ_OK;
@ -2312,10 +2307,10 @@ static void * resolve_mage(int id, void *data) {
return data;
}
static int read_magician(attrib * a, void *owner, struct gamedata *data)
static int read_magician(variant *var, void *owner, struct gamedata *data)
{
UNUSED_ARG(owner);
if (read_unit_reference(data, (unit **)&a->data.v, resolve_mage) <= 0) {
if (read_unit_reference(data, (unit **)&var->v, resolve_mage) <= 0) {
return AT_READ_FAIL;
}
return AT_READ_OK;

View File

@ -53,11 +53,11 @@ static unsigned int get_markets(region * r, unit ** results, size_t size)
return n;
}
static void free_market(attrib * a)
static void free_market(variant *var)
{
item *items = (item *)a->data.v;
item *items = (item *)var->v;
i_freeall(&items);
a->data.v = 0;
var->v = NULL;
}
attrib_type at_market = {

View File

@ -34,6 +34,7 @@
/* util includes */
#include <util/attrib.h>
#include <util/gamedata.h>
#include <util/macros.h>
#include <storage.h>
@ -43,17 +44,19 @@
#include <limits.h>
#include <assert.h>
static int read_permissions(attrib * a, void *owner, struct gamedata *data)
static int read_permissions(variant *var, void *owner, struct gamedata *data)
{
assert(!a);
attrib *a;
UNUSED_ARG(var);
read_attribs(data, &a, owner);
a_remove(&a, a);
return AT_READ_OK;
}
static int read_gmcreate(attrib * a, void *owner, struct gamedata *data)
static int read_gmcreate(variant *var, void *owner, struct gamedata *data)
{
char zText[32];
UNUSED_ARG(var);
READ_TOK(data->store, zText, sizeof(zText));
return AT_READ_OK;
}

View File

@ -59,29 +59,22 @@ attrib_type at_museumexit = {
"museumexit", NULL, NULL, NULL, a_writeshorts, a_readshorts
};
static void a_initmuseumgivebackcookie(attrib * a)
static void a_initmuseumgivebackcookie(variant *var)
{
a->data.v = calloc(1, sizeof(museumgivebackcookie));
var->v = calloc(1, sizeof(museumgivebackcookie));
}
static void a_finalizemuseumgivebackcookie(attrib * a)
static void a_writemuseumgivebackcookie(const variant *var,
const void *owner, struct storage *store)
{
free(a->data.v);
}
static void
a_writemuseumgivebackcookie(const attrib * a, const void *owner,
struct storage *store)
{
museumgivebackcookie *gbc = (museumgivebackcookie *)a->data.v;
museumgivebackcookie *gbc = (museumgivebackcookie *)var->v;
WRITE_INT(store, gbc->warden_no);
WRITE_INT(store, gbc->cookie);
}
static int
a_readmuseumgivebackcookie(attrib * a, void *owner, gamedata *data)
static int a_readmuseumgivebackcookie(variant *var, void *owner, gamedata *data)
{
museumgivebackcookie *gbc = (museumgivebackcookie *)a->data.v;
museumgivebackcookie *gbc = (museumgivebackcookie *)var->v;
READ_INT(data->store, &gbc->warden_no);
READ_INT(data->store, &gbc->cookie);
return AT_READ_OK;
@ -90,7 +83,7 @@ a_readmuseumgivebackcookie(attrib * a, void *owner, gamedata *data)
attrib_type at_museumgivebackcookie = {
"museumgivebackcookie",
a_initmuseumgivebackcookie,
a_finalizemuseumgivebackcookie,
a_free_voidptr,
NULL,
a_writemuseumgivebackcookie,
a_readmuseumgivebackcookie
@ -100,30 +93,30 @@ attrib_type at_warden = {
"itemwarden", NULL, NULL, NULL, a_writeint, a_readint
};
static void a_initmuseumgiveback(attrib * a)
static void a_initmuseumgiveback(variant *var)
{
a->data.v = calloc(1, sizeof(museumgiveback));
var->v = calloc(1, sizeof(museumgiveback));
}
static void a_finalizemuseumgiveback(attrib * a)
static void a_finalizemuseumgiveback(variant *var)
{
museumgiveback *gb = (museumgiveback *)a->data.v;
museumgiveback *gb = (museumgiveback *)var->v;
i_freeall(&gb->items);
free(a->data.v);
free(gb);
}
static void
a_writemuseumgiveback(const attrib * a, const void *owner,
a_writemuseumgiveback(const variant *var, const void *owner,
struct storage *store)
{
museumgiveback *gb = (museumgiveback *)a->data.v;
museumgiveback *gb = (museumgiveback *)var->v;
WRITE_INT(store, gb->cookie);
write_items(store, gb->items);
}
static int a_readmuseumgiveback(attrib * a, void *owner, struct gamedata *data)
static int a_readmuseumgiveback(variant *var, void *owner, struct gamedata *data)
{
museumgiveback *gb = (museumgiveback *)a->data.v;
museumgiveback *gb = (museumgiveback *)var->v;
READ_INT(data->store, &gb->cookie);
read_items(data->store, &gb->items);
return AT_READ_OK;

View File

@ -138,14 +138,9 @@ get_followers(unit * target, region * r, const region_list * route_end,
}
}
static void shiptrail_init(attrib * a)
static void shiptrail_init(variant *var)
{
a->data.v = calloc(1, sizeof(traveldir));
}
static void shiptrail_finalize(attrib * a)
{
free(a->data.v);
var->v = calloc(1, sizeof(traveldir));
}
static int shiptrail_age(attrib * a, void *owner)
@ -157,11 +152,11 @@ static int shiptrail_age(attrib * a, void *owner)
return (t->age > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE;
}
static int shiptrail_read(attrib * a, void *owner, struct gamedata *data)
static int shiptrail_read(variant *var, void *owner, struct gamedata *data)
{
storage *store = data->store;
int n;
traveldir *t = (traveldir *)(a->data.v);
traveldir *t = (traveldir *)var->v;
UNUSED_ARG(owner);
READ_INT(store, &t->no);
@ -172,9 +167,9 @@ static int shiptrail_read(attrib * a, void *owner, struct gamedata *data)
}
static void
shiptrail_write(const attrib * a, const void *owner, struct storage *store)
shiptrail_write(const variant *var, const void *owner, struct storage *store)
{
traveldir *t = (traveldir *)(a->data.v);
traveldir *t = (traveldir *)var->v;
UNUSED_ARG(owner);
WRITE_INT(store, t->no);
@ -185,7 +180,7 @@ shiptrail_write(const attrib * a, const void *owner, struct storage *store)
attrib_type at_shiptrail = {
"traveldir_new",
shiptrail_init,
shiptrail_finalize,
a_free_voidptr,
shiptrail_age,
shiptrail_write,
shiptrail_read

View File

@ -34,20 +34,15 @@ typedef struct piracy_data {
direction_t dir;
} piracy_data;
static void piracy_init(struct attrib *a)
static void piracy_init(variant *var)
{
a->data.v = calloc(1, sizeof(piracy_data));
}
static void piracy_done(struct attrib *a)
{
free(a->data.v);
var->v = calloc(1, sizeof(piracy_data));
}
static attrib_type at_piracy_direction = {
"piracy_direction",
piracy_init,
piracy_done,
a_free_voidptr,
DEFAULT_AGE,
NO_WRITE,
NO_READ

View File

@ -2857,12 +2857,12 @@ static curse *mk_deathcloud(unit * mage, region * r, double force, int duration)
return c;
}
static int dc_read_compat(struct attrib *a, void *target, gamedata *data)
static int dc_read_compat(variant *var, void *target, gamedata *data)
/* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */
{
struct storage *store = data->store;
UNUSED_ARG(a);
UNUSED_ARG(var);
UNUSED_ARG(target);
READ_INT(store, NULL);
READ_FLT(store, NULL);

View File

@ -31,13 +31,13 @@ typedef struct wallcurse {
connection *wall;
} wallcurse;
static int cw_read_depr(attrib * a, void *target, gamedata *data)
static int cw_read_depr(variant *var, void *target, gamedata *data)
{
storage *store = data->store;
curse_init(a);
curse_read(a, store, target);
curse_done(a);
curse_init(var);
curse_read(var, store, target);
curse_done(var);
READ_INT(store, NULL);
return AT_READ_DEPR;
}

View File

@ -173,16 +173,16 @@ int study_cost(struct unit *u, skill_t sk)
/* ------------------------------------------------------------- */
static void init_learning(struct attrib *a)
static void init_learning(variant *var)
{
a->data.v = calloc(sizeof(teaching_info), 1);
var->v = calloc(sizeof(teaching_info), 1);
}
static void done_learning(struct attrib *a)
static void done_learning(variant *var)
{
teaching_info *teach = (teaching_info *)a->data.v;
teaching_info *teach = (teaching_info *)var->v;
selist_free(teach->teachers);
free(a->data.v);
free(teach);
}
const attrib_type at_learning = {

View File

@ -37,9 +37,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <assert.h>
#include <string.h>
static void travel_done(attrib *a) {
selist *ql = (selist *)a->data.v;
selist_free(ql);
static void travel_done(variant *var) {
selist_free((selist *)var->v);
}
/*********************/

View File

@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "gamedata.h"
#include "log.h"
#include "variant.h"
#include "storage.h"
#include "strings.h"
@ -61,57 +62,57 @@ void write_attribs(storage *store, attrib *alist, const void *owner)
#endif
}
int a_readint(attrib * a, void *owner, struct gamedata *data)
int a_readint(variant * var, void *owner, struct gamedata *data)
{
int n;
READ_INT(data->store, &n);
if (a) a->data.i = n;
if (var) var->i = n;
return AT_READ_OK;
}
void a_writeint(const attrib * a, const void *owner, struct storage *store)
void a_writeint(const variant * var, const void *owner, struct storage *store)
{
WRITE_INT(store, a->data.i);
WRITE_INT(store, var->i);
}
int a_readshorts(attrib * a, void *owner, struct gamedata *data)
int a_readshorts(variant * var, void *owner, struct gamedata *data)
{
int n;
READ_INT(data->store, &n);
a->data.sa[0] = (short)n;
var->sa[0] = (short)n;
READ_INT(data->store, &n);
a->data.sa[1] = (short)n;
var->sa[1] = (short)n;
return AT_READ_OK;
}
void a_writeshorts(const attrib * a, const void *owner, struct storage *store)
void a_writeshorts(const variant * var, const void *owner, struct storage *store)
{
WRITE_INT(store, a->data.sa[0]);
WRITE_INT(store, a->data.sa[1]);
WRITE_INT(store, var->sa[0]);
WRITE_INT(store, var->sa[1]);
}
int a_readchars(attrib * a, void *owner, struct gamedata *data)
int a_readchars(variant * var, void *owner, struct gamedata *data)
{
int i;
for (i = 0; i != 4; ++i) {
int n;
READ_INT(data->store, &n);
a->data.ca[i] = (char)n;
var->ca[i] = (char)n;
}
return AT_READ_OK;
}
void a_writechars(const attrib * a, const void *owner, struct storage *store)
void a_writechars(const variant * var, const void *owner, struct storage *store)
{
int i;
for (i = 0; i != 4; ++i) {
WRITE_INT(store, a->data.ca[i]);
WRITE_INT(store, var->ca[i]);
}
}
#define DISPLAYSIZE 8192
int a_readstring(attrib * a, void *owner, struct gamedata *data)
int a_readstring(variant * var, void *owner, struct gamedata *data)
{
char buf[DISPLAYSIZE];
char * result = 0;
@ -133,19 +134,19 @@ int a_readstring(attrib * a, void *owner, struct gamedata *data)
result = str_strdup(buf);
}
} while (e == ENOMEM);
a->data.v = result;
var->v = result;
return AT_READ_OK;
}
void a_writestring(const attrib * a, const void *owner, struct storage *store)
void a_writestring(const variant * var, const void *owner, struct storage *store)
{
assert(a->data.v);
WRITE_STR(store, (const char *)a->data.v);
assert(var && var->v);
WRITE_STR(store, (const char *)var->v);
}
void a_finalizestring(attrib * a)
void a_finalizestring(variant * var)
{
free(a->data.v);
free(var->v);
}
#define MAXATHASH 61
@ -308,11 +309,16 @@ static int a_unlink(attrib ** pa, attrib * a)
return 0;
}
void a_free_voidptr(union variant *var)
{
free(var->v);
}
static void a_free(attrib * a)
{
const attrib_type *at = a->type;
if (at->finalize)
at->finalize(a);
at->finalize(&a->data);
free(a);
}
@ -376,7 +382,7 @@ attrib *a_new(const attrib_type * at)
assert(at != NULL);
a->type = at;
if (at->initialize)
at->initialize(a);
at->initialize(&a->data);
return a;
}
@ -404,10 +410,10 @@ static critbit_tree cb_deprecated = { 0 };
typedef struct deprecated_s {
unsigned int hash;
int(*reader)(attrib *, void *, struct gamedata *);
int(*reader)(variant *, void *, struct gamedata *);
} deprecated_t;
void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamedata *))
void at_deprecate(const char * name, int(*reader)(variant *, void *, struct gamedata *))
{
deprecated_t value;
@ -418,7 +424,7 @@ void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamed
static int a_read_i(gamedata *data, attrib ** attribs, void *owner, unsigned int key) {
int retval = AT_READ_OK;
int(*reader)(attrib *, void *, struct gamedata *) = 0;
int(*reader)(variant *, void *, struct gamedata *) = 0;
attrib_type *at = at_find_key(key);
attrib * na = 0;
@ -438,7 +444,7 @@ static int a_read_i(gamedata *data, attrib ** attribs, void *owner, unsigned int
}
}
if (reader) {
int ret = reader(na, owner, data);
int ret = reader(&na->data, owner, data);
if (na) {
switch (ret) {
case AT_READ_DEPR:
@ -508,7 +514,7 @@ void a_write(struct storage *store, const attrib * attribs, const void *owner) {
if (na->type->write) {
assert(na->type->hashkey || !"attribute not registered");
WRITE_INT(store, na->type->hashkey);
na->type->write(na, owner, store);
na->type->write(&na->data, owner, store);
na = na->next;
}
else {
@ -526,7 +532,7 @@ void a_write_orig(struct storage *store, const attrib * attribs, const void *own
if (na->type->write) {
assert(na->type->hashkey || !"attribute not registered");
WRITE_TOK(store, na->type->name);
na->type->write(na, owner, store);
na->type->write(&na->data, owner, store);
na = na->next;
}
else {

View File

@ -20,27 +20,19 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define ATTRIB_H
#include <stdbool.h>
#include "variant.h"
#ifdef __cplusplus
extern "C" {
#endif
union variant;
struct gamedata;
struct storage;
typedef void(*afun) (void);
typedef struct attrib {
const struct attrib_type *type;
union {
afun f;
void *v;
int i;
float flt;
char c;
short s;
short sa[2];
char ca[4];
} data;
union variant data;
/* internal data, do not modify: */
struct attrib *next; /* next attribute in the list */
struct attrib *nexttype; /* skip to attribute of a different type */
@ -52,12 +44,12 @@ extern "C" {
typedef struct attrib_type {
const char *name;
void(*initialize) (struct attrib *);
void(*finalize) (struct attrib *);
void(*initialize) (union variant *);
void(*finalize) (union variant *);
int(*age) (struct attrib *, void *owner);
/* age returns 0 if the attribute needs to be removed, !=0 otherwise */
void(*write) (const struct attrib *, const void *owner, struct storage *);
int(*read) (struct attrib *, void *owner, struct gamedata *); /* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */
void(*write) (const union variant *, const void *owner, struct storage *);
int(*read) (union variant *, void *owner, struct gamedata *); /* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */
void(*upgrade) (struct attrib **alist, struct attrib *a);
unsigned int flags;
/* ---- internal data, do not modify: ---- */
@ -66,7 +58,7 @@ extern "C" {
} attrib_type;
void at_register(attrib_type * at);
void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamedata *));
void at_deprecate(const char * name, int (*reader)(variant *, void *, struct gamedata *));
struct attrib_type *at_find(const char *name);
void write_attribs(struct storage *store, struct attrib *alist, const void *owner);
@ -80,25 +72,26 @@ extern "C" {
attrib *a_new(const attrib_type * at);
int a_age(attrib ** attribs, void *owner);
void a_free_voidptr(union variant *v);
int a_read_orig(struct gamedata *data, attrib ** attribs, void *owner);
void a_write_orig(struct storage *store, const attrib * attribs, const void *owner);
int a_read(struct gamedata *data, attrib ** attribs, void *owner);
void a_write(struct storage *store, const attrib * attribs, const void *owner);
int a_readint(struct attrib *a, void *owner, struct gamedata *);
void a_writeint(const struct attrib *a, const void *owner,
int a_readint(union variant *v, void *owner, struct gamedata *);
void a_writeint(const union variant *v, const void *owner,
struct storage *store);
int a_readshorts(struct attrib *a, void *owner, struct gamedata *);
void a_writeshorts(const struct attrib *a, const void *owner,
int a_readshorts(union variant *v, void *owner, struct gamedata *);
void a_writeshorts(const union variant *v, const void *owner,
struct storage *store);
int a_readchars(struct attrib *a, void *owner, struct gamedata *);
void a_writechars(const struct attrib *a, const void *owner,
int a_readchars(union variant *v, void *owner, struct gamedata *);
void a_writechars(const union variant *v, const void *owner,
struct storage *store);
int a_readstring(struct attrib *a, void *owner, struct gamedata *);
void a_writestring(const struct attrib *a, const void *owner,
int a_readstring(union variant *v, void *owner, struct gamedata *);
void a_writestring(const union variant *v, const void *owner,
struct storage *);
void a_finalizestring(struct attrib *a);
void a_finalizestring(union variant *v);
void attrib_done(void);

View File

@ -117,18 +117,18 @@ static void test_attrib_nexttype(CuTest * tc)
static void test_attrib_rwstring(CuTest *tc) {
gamedata data;
storage store;
attrib a = { 0 };
variant var = { 0 };
test_setup();
a.data.v = str_strdup("Hello World");
var.v = str_strdup("Hello World");
mstream_init(&data.strm);
gamedata_init(&data, &store, RELEASE_VERSION);
a_writestring(&a, NULL, &store);
a_finalizestring(&a);
a_writestring(&var, NULL, &store);
a_finalizestring(&var);
data.strm.api->rewind(data.strm.handle);
a_readstring(&a, NULL, &data);
CuAssertStrEquals(tc, "Hello World", (const char *)a.data.v);
a_finalizestring(&a);
a_readstring(&var, NULL, &data);
CuAssertStrEquals(tc, "Hello World", (const char *)var.v);
a_finalizestring(&var);
mstream_done(&data.strm);
gamedata_done(&data);
test_teardown();
@ -137,17 +137,17 @@ static void test_attrib_rwstring(CuTest *tc) {
static void test_attrib_rwint(CuTest *tc) {
gamedata data;
storage store;
attrib a = { 0 };
variant var = { 0 };
test_setup();
a.data.i = 42;
var.i = 42;
mstream_init(&data.strm);
gamedata_init(&data, &store, RELEASE_VERSION);
a_writeint(&a, NULL, &store);
a.data.i = 0;
a_writeint(&var, NULL, &store);
var.i = 0;
data.strm.api->rewind(data.strm.handle);
a_readint(&a, NULL, &data);
CuAssertIntEquals(tc, 42, a.data.i);
a_readint(&var, NULL, &data);
CuAssertIntEquals(tc, 42, var.i);
mstream_done(&data.strm);
gamedata_done(&data);
test_teardown();
@ -156,19 +156,19 @@ static void test_attrib_rwint(CuTest *tc) {
static void test_attrib_rwchars(CuTest *tc) {
gamedata data;
storage store;
attrib a = { 0 };
variant var = { 0 };
test_setup();
a.data.ca[0] = 1;
a.data.ca[3] = 42;
var.ca[0] = 1;
var.ca[3] = 42;
mstream_init(&data.strm);
gamedata_init(&data, &store, RELEASE_VERSION);
a_writeint(&a, NULL, &store);
memset(a.data.ca, 0, 4);
a_writeint(&var, NULL, &store);
memset(var.ca, 0, 4);
data.strm.api->rewind(data.strm.handle);
a_readint(&a, NULL, &data);
CuAssertIntEquals(tc, 1, a.data.ca[0]);
CuAssertIntEquals(tc, 42, a.data.ca[3]);
a_readint(&var, NULL, &data);
CuAssertIntEquals(tc, 1, var.ca[0]);
CuAssertIntEquals(tc, 42, var.ca[3]);
mstream_done(&data.strm);
gamedata_done(&data);
test_teardown();
@ -177,19 +177,19 @@ static void test_attrib_rwchars(CuTest *tc) {
static void test_attrib_rwshorts(CuTest *tc) {
gamedata data;
storage store;
attrib a = { 0 };
a.data.sa[0] = -4;
a.data.sa[1] = 42;
variant var = { 0 };
var.sa[0] = -4;
var.sa[1] = 42;
test_setup();
mstream_init(&data.strm);
gamedata_init(&data, &store, RELEASE_VERSION);
a_writeint(&a, NULL, &store);
memset(a.data.ca, 0, 4);
a_writeint(&var, NULL, &store);
memset(var.ca, 0, 4);
data.strm.api->rewind(data.strm.handle);
a_readint(&a, NULL, &data);
CuAssertIntEquals(tc, -4, a.data.sa[0]);
CuAssertIntEquals(tc, 42, a.data.sa[1]);
a_readint(&var, NULL, &data);
CuAssertIntEquals(tc, -4, var.sa[0]);
CuAssertIntEquals(tc, 42, var.sa[1]);
mstream_done(&data.strm);
gamedata_done(&data);
test_teardown();

View File

@ -127,32 +127,32 @@ typedef struct handler_info {
trigger *triggers;
} handler_info;
static void init_handler(attrib * a)
static void init_handler(variant *var)
{
a->data.v = calloc(sizeof(handler_info), 1);
var->v = calloc(sizeof(handler_info), 1);
}
static void free_handler(attrib * a)
static void free_handler(variant *var)
{
handler_info *hi = (handler_info *)a->data.v;
handler_info *hi = (handler_info *)var->v;
free_triggers(hi->triggers);
free(hi->event);
free(hi);
}
static void
write_handler(const attrib * a, const void *owner, struct storage *store)
write_handler(const variant *var, const void *owner, struct storage *store)
{
handler_info *hi = (handler_info *)a->data.v;
handler_info *hi = (handler_info *)var->v;
WRITE_TOK(store, hi->event);
write_triggers(store, hi->triggers);
}
static int read_handler(attrib * a, void *owner, gamedata *data)
static int read_handler(variant *var, void *owner, gamedata *data)
{
struct storage *store = data->store;
char zText[128];
handler_info *hi = (handler_info *)a->data.v;
handler_info *hi = (handler_info *)var->v;
READ_TOK(store, zText, sizeof(zText));
hi->event = str_strdup(zText);

View File

@ -65,14 +65,14 @@ void register_special_direction(struct locale *lang, const char *name)
/********************/
/* at_direction */
/********************/
static void a_initdirection(attrib * a)
static void a_initdirection(variant * var)
{
a->data.v = calloc(1, sizeof(spec_direction));
var->v = calloc(1, sizeof(spec_direction));
}
static void a_freedirection(attrib * a)
static void a_freedirection(variant *var)
{
spec_direction *d = (spec_direction *)(a->data.v);
spec_direction *d = (spec_direction *)(var->v);
free(d->desc);
free(d->keyword);
free(d);
@ -86,10 +86,10 @@ static int a_agedirection(attrib * a, void *owner)
return (d->duration > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE;
}
static int a_readdirection(attrib * a, void *owner, struct gamedata *data)
static int a_readdirection(variant *var, void *owner, struct gamedata *data)
{
struct storage *store = data->store;
spec_direction *d = (spec_direction *)(a->data.v);
spec_direction *d = (spec_direction *)(var->v);
char lbuf[32];
(void)owner;
@ -105,9 +105,9 @@ static int a_readdirection(attrib * a, void *owner, struct gamedata *data)
}
static void
a_writedirection(const attrib * a, const void *owner, struct storage *store)
a_writedirection(const variant *var, const void *owner, struct storage *store)
{
spec_direction *d = (spec_direction *)(a->data.v);
spec_direction *d = (spec_direction *)(var->v);
(void)owner;
WRITE_INT(store, d->x);

View File

@ -91,20 +91,20 @@ static int wormhole_age(struct attrib *a, void *owner)
return AT_AGE_KEEP;
}
static void wormhole_write(const struct attrib *a, const void *owner, struct storage *store)
static void wormhole_write(const variant *var, const void *owner, struct storage *store)
{
region *exit = (region *)a->data.v;
region *exit = (region *)var->v;
write_region_reference(exit, store);
}
static int wormhole_read(struct attrib *a, void *owner, struct gamedata *data)
static int wormhole_read(variant *var, void *owner, struct gamedata *data)
{
int id;
if (data->version < ATTRIBOWNER_VERSION) {
READ_INT(data->store, NULL);
}
id = read_region_reference(data, (region **)&a->data.v, NULL);
id = read_region_reference(data, (region **)&var->v, NULL);
return (id <= 0) ? AT_READ_FAIL : AT_READ_OK;
}