forked from github/server
Merge branch 'resolve-hashing'
This commit is contained in:
commit
9f97ee2dd7
|
@ -96,7 +96,7 @@ static int obs_read(struct attrib *a, void *owner, struct gamedata *data)
|
||||||
{
|
{
|
||||||
obs_data *od = (obs_data *)a->data.v;
|
obs_data *od = (obs_data *)a->data.v;
|
||||||
|
|
||||||
read_reference(&od->f, data, read_faction_reference, resolve_faction);
|
read_faction_reference(data, &od->f, NULL);
|
||||||
READ_INT(data->store, &od->skill);
|
READ_INT(data->store, &od->skill);
|
||||||
READ_INT(data->store, &od->timer);
|
READ_INT(data->store, &od->timer);
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
|
|
@ -30,7 +30,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
static int read_follow(attrib * a, void *owner, gamedata *data)
|
static int read_follow(attrib * a, void *owner, gamedata *data)
|
||||||
{
|
{
|
||||||
read_unit_reference(data); /* skip it */
|
READ_INT(data->store, NULL); /* skip it */
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,7 @@ write_hate(const attrib * a, const void *owner, struct storage *store)
|
||||||
|
|
||||||
static int read_hate(attrib * a, void *owner, gamedata *data)
|
static int read_hate(attrib * a, void *owner, gamedata *data)
|
||||||
{
|
{
|
||||||
int result = read_reference(&a->data.v, data, read_unit_reference,
|
if (read_unit_reference(data, (unit **)&a->data.v, NULL) <= 0) {
|
||||||
resolve_unit);
|
|
||||||
if (result == 0 && !a->data.v) {
|
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
|
|
@ -36,10 +36,9 @@ write_targetregion(const attrib * a, const void *owner, struct storage *store)
|
||||||
|
|
||||||
static int read_targetregion(attrib * a, void *owner, gamedata *data)
|
static int read_targetregion(attrib * a, void *owner, gamedata *data)
|
||||||
{
|
{
|
||||||
int result = read_reference(&a->data.v, data, read_region_reference,
|
if (read_region_reference(data, (region **)&a->data.v, NULL) <= 0) {
|
||||||
RESOLVE_REGION(data->version));
|
|
||||||
if (result == 0 && !a->data.v)
|
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,8 +86,7 @@ static void lc_done(struct attrib *a)
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void lc_write(const struct attrib *a, const void *owner, struct storage *store)
|
||||||
lc_write(const struct attrib *a, const void *owner, struct storage *store)
|
|
||||||
{
|
{
|
||||||
building_action *data = (building_action *)a->data.v;
|
building_action *data = (building_action *)a->data.v;
|
||||||
const char *fname = data->fname;
|
const char *fname = data->fname;
|
||||||
|
|
|
@ -20,6 +20,7 @@ without prior permission by the authors of Eressea.
|
||||||
#include <util/bsdstring.h>
|
#include <util/bsdstring.h>
|
||||||
#include <util/event.h>
|
#include <util/event.h>
|
||||||
#include <util/functions.h>
|
#include <util/functions.h>
|
||||||
|
#include <util/gamedata.h>
|
||||||
#include <util/log.h>
|
#include <util/log.h>
|
||||||
#include <util/parser.h>
|
#include <util/parser.h>
|
||||||
#include <util/resolve.h>
|
#include <util/resolve.h>
|
||||||
|
@ -290,10 +291,10 @@ use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compat code for old data files */
|
/* compat code for old data files */
|
||||||
static int caldera_read(trigger *t, struct gamedata *data)
|
static int caldera_read(trigger *t, gamedata *data)
|
||||||
{
|
{
|
||||||
UNUSED_ARG(t);
|
UNUSED_ARG(t);
|
||||||
read_building_reference(data);
|
READ_INT(data->store, NULL);
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,40 @@
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "faction.h"
|
#include "faction.h"
|
||||||
|
#include "objtypes.h"
|
||||||
#include "plane.h"
|
#include "plane.h"
|
||||||
|
|
||||||
#include <util/attrib.h>
|
#include <util/attrib.h>
|
||||||
|
#include <util/gamedata.h>
|
||||||
|
|
||||||
|
#include <storage.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void read_allies(gamedata * data, faction *f)
|
||||||
|
{
|
||||||
|
ally **sfp = &f->allies;
|
||||||
|
for (;;) {
|
||||||
|
int aid;
|
||||||
|
READ_INT(data->store, &aid);
|
||||||
|
if (aid > 0) {
|
||||||
|
ally * al = ally_add(sfp, NULL);
|
||||||
|
int state;
|
||||||
|
if ((al->faction = findfaction(aid)) == NULL) {
|
||||||
|
ur_add(RESOLVE_FACTION | aid, (void **)&al->faction, NULL);
|
||||||
|
}
|
||||||
|
READ_INT(data->store, &state);
|
||||||
|
al->status = state & HELP_ALL;
|
||||||
|
sfp = &al->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ally * ally_find(ally *al, const struct faction *f) {
|
ally * ally_find(ally *al, const struct faction *f) {
|
||||||
for (; al; al = al->next) {
|
for (; al; al = al->next) {
|
||||||
if (al->faction == f) return al;
|
if (al->faction == f) return al;
|
||||||
|
|
|
@ -26,7 +26,9 @@ extern "C" {
|
||||||
struct attrib_type;
|
struct attrib_type;
|
||||||
struct plane;
|
struct plane;
|
||||||
struct faction;
|
struct faction;
|
||||||
|
struct gamedata;
|
||||||
struct unit;
|
struct unit;
|
||||||
|
|
||||||
extern struct attrib_type at_npcfaction;
|
extern struct attrib_type at_npcfaction;
|
||||||
|
|
||||||
typedef struct ally {
|
typedef struct ally {
|
||||||
|
@ -35,6 +37,7 @@ extern "C" {
|
||||||
int status;
|
int status;
|
||||||
} ally;
|
} ally;
|
||||||
|
|
||||||
|
void read_allies(struct gamedata * data, struct faction *f);
|
||||||
ally * ally_find(ally *al, const struct faction *f);
|
ally * ally_find(ally *al, const struct faction *f);
|
||||||
ally * ally_add(ally **al_p, struct faction *f);
|
ally * ally_add(ally **al_p, struct faction *f);
|
||||||
void ally_remove(ally **al_p, struct faction *f);
|
void ally_remove(ally **al_p, struct faction *f);
|
||||||
|
|
|
@ -322,25 +322,26 @@ void write_building_reference(const struct building *b, struct storage *store)
|
||||||
WRITE_INT(store, (b && b->region) ? b->no : 0);
|
WRITE_INT(store, (b && b->region) ? b->no : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve_building(int id, void *address)
|
void resolve_building(building *b)
|
||||||
{
|
{
|
||||||
int result = 0;
|
resolve(RESOLVE_BUILDING | b->no, b);
|
||||||
building *b = NULL;
|
|
||||||
if (id != 0) {
|
|
||||||
b = findbuilding(id);
|
|
||||||
if (b == NULL) {
|
|
||||||
result = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*(building **)address = b;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_building_reference(gamedata * data)
|
int read_building_reference(gamedata * data, building **bp, resolve_fun fun)
|
||||||
{
|
{
|
||||||
int result;
|
int id;
|
||||||
READ_INT(data->store, &result);
|
READ_INT(data->store, &id);
|
||||||
return result;
|
if (id > 0) {
|
||||||
|
*bp = findbuilding(id);
|
||||||
|
if (*bp == NULL) {
|
||||||
|
*bp = NULL;
|
||||||
|
ur_add(RESOLVE_BUILDING | id, (void**)bp, fun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*bp = NULL;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
building *new_building(const struct building_type * btype, region * r,
|
building *new_building(const struct building_type * btype, region * r,
|
||||||
|
|
|
@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#define H_KRNL_BUILDING
|
#define H_KRNL_BUILDING
|
||||||
|
|
||||||
#include <kernel/types.h>
|
#include <kernel/types.h>
|
||||||
#include <util/variant.h>
|
#include <util/resolve.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -152,10 +152,11 @@ extern "C" {
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#define NOBUILDING NULL
|
#define NOBUILDING NULL
|
||||||
|
|
||||||
int resolve_building(int id, void *address);
|
#define RESOLVE_BUILDING (TYP_BUILDING << 24)
|
||||||
|
void resolve_building(building *b);
|
||||||
void write_building_reference(const struct building *b,
|
void write_building_reference(const struct building *b,
|
||||||
struct storage *store);
|
struct storage *store);
|
||||||
int read_building_reference(struct gamedata *data);
|
int read_building_reference(struct gamedata * data, struct building **bp, resolve_fun fun);
|
||||||
|
|
||||||
struct building *findbuilding(int n);
|
struct building *findbuilding(int n);
|
||||||
|
|
||||||
|
|
|
@ -606,37 +606,26 @@ int read_borders(gamedata *data)
|
||||||
{
|
{
|
||||||
struct storage *store = data->store;
|
struct storage *store = data->store;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int bid = 0;
|
int fid, tid, bid;
|
||||||
char zText[32];
|
char zText[32];
|
||||||
region *from, *to;
|
region *from, *to;
|
||||||
border_type *type;
|
border_type *type;
|
||||||
|
|
||||||
READ_TOK(store, zText, sizeof(zText));
|
READ_TOK(store, zText, sizeof(zText));
|
||||||
if (!strcmp(zText, "end"))
|
if (!strcmp(zText, "end")) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
READ_INT(store, &bid);
|
||||||
type = find_bordertype(zText);
|
type = find_bordertype(zText);
|
||||||
if (type == NULL) {
|
if (type == NULL) {
|
||||||
log_error("[read_borders] connection %d type %s is not registered", bid, zText);
|
log_error("[read_borders] connection %d type %s is not registered", bid, zText);
|
||||||
assert(type || !"connection type not registered");
|
assert(type || !"connection type not registered");
|
||||||
}
|
}
|
||||||
|
|
||||||
READ_INT(store, &bid);
|
READ_INT(store, &fid);
|
||||||
if (data->version < UIDHASH_VERSION) {
|
READ_INT(store, &tid);
|
||||||
int fx, fy, tx, ty;
|
from = findregionbyid(fid);
|
||||||
READ_INT(store, &fx);
|
to = findregionbyid(tid);
|
||||||
READ_INT(store, &fy);
|
|
||||||
READ_INT(store, &tx);
|
|
||||||
READ_INT(store, &ty);
|
|
||||||
from = findregion(fx, fy);
|
|
||||||
to = findregion(tx, ty);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int fid, tid;
|
|
||||||
READ_INT(store, &fid);
|
|
||||||
READ_INT(store, &tid);
|
|
||||||
from = findregionbyid(fid);
|
|
||||||
to = findregionbyid(tid);
|
|
||||||
}
|
|
||||||
if (!to || !from) {
|
if (!to || !from) {
|
||||||
log_error("%s connection %d has missing regions", zText, bid);
|
log_error("%s connection %d has missing regions", zText, bid);
|
||||||
if (type->read) {
|
if (type->read) {
|
||||||
|
|
|
@ -191,7 +191,7 @@ int curse_read(attrib * a, void *owner, gamedata *data)
|
||||||
READ_INT(store, &c->duration);
|
READ_INT(store, &c->duration);
|
||||||
READ_FLT(store, &flt);
|
READ_FLT(store, &flt);
|
||||||
c->vigour = flt;
|
c->vigour = flt;
|
||||||
ur = read_reference(&c->magician, data, read_unit_reference, resolve_unit);
|
ur = read_unit_reference(data, &c->magician, NULL);
|
||||||
if (data->version < CURSEFLOAT_VERSION) {
|
if (data->version < CURSEFLOAT_VERSION) {
|
||||||
READ_INT(store, &n);
|
READ_INT(store, &n);
|
||||||
c->effect = (float)n;
|
c->effect = (float)n;
|
||||||
|
@ -226,9 +226,7 @@ int curse_read(attrib * a, void *owner, gamedata *data)
|
||||||
READ_INT(store, &c->data.i);
|
READ_INT(store, &c->data.i);
|
||||||
}
|
}
|
||||||
if (c->type->typ == CURSETYP_REGION) {
|
if (c->type->typ == CURSETYP_REGION) {
|
||||||
int rr =
|
int rr = read_region_reference(data, (region **)&c->data.v, NULL);
|
||||||
read_reference(&c->data.v, data, read_region_reference,
|
|
||||||
RESOLVE_REGION(data->version));
|
|
||||||
if (ur == 0 && rr == 0 && !c->data.v) {
|
if (ur == 0 && rr == 0 && !c->data.v) {
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,21 +203,6 @@ const char *factionname(const faction * f)
|
||||||
return ibuf;
|
return ibuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve_faction(int id, void *address)
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
faction *f = NULL;
|
|
||||||
if (id != 0) {
|
|
||||||
f = findfaction(id);
|
|
||||||
if (f == NULL) {
|
|
||||||
result = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(address);
|
|
||||||
*(faction **)address = f;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool faction_id_is_unused(int id)
|
bool faction_id_is_unused(int id)
|
||||||
{
|
{
|
||||||
return findfaction(id) == NULL;
|
return findfaction(id) == NULL;
|
||||||
|
@ -332,10 +317,25 @@ bool checkpasswd(const faction * f, const char *passwd)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_faction_reference(gamedata * data)
|
void resolve_faction(faction *f)
|
||||||
|
{
|
||||||
|
resolve(RESOLVE_FACTION | f->no, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_faction_reference(gamedata * data, faction **fp, resolve_fun fun)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
READ_INT(data->store, &id);
|
READ_INT(data->store, &id);
|
||||||
|
if (id > 0) {
|
||||||
|
*fp = findfaction(id);
|
||||||
|
if (*fp == NULL) {
|
||||||
|
*fp = NULL;
|
||||||
|
ur_add(RESOLVE_FACTION | id, (void **)fp, fun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*fp = NULL;
|
||||||
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
#include "skill.h"
|
#include "skill.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
#include <util/resolve.h>
|
||||||
#include <modules/score.h>
|
#include <modules/score.h>
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -126,8 +129,10 @@ extern "C" {
|
||||||
|
|
||||||
void write_faction_reference(const struct faction *f,
|
void write_faction_reference(const struct faction *f,
|
||||||
struct storage *store);
|
struct storage *store);
|
||||||
int read_faction_reference(struct gamedata *data);
|
int read_faction_reference(struct gamedata *data, struct faction **fp, resolve_fun fun);
|
||||||
int resolve_faction(int id, void *addr);
|
|
||||||
|
#define RESOLVE_FACTION (TYP_FACTION << 24)
|
||||||
|
void resolve_faction(struct faction *f);
|
||||||
|
|
||||||
void renumber_faction(faction * f, int no);
|
void renumber_faction(faction * f, int no);
|
||||||
void free_factions(void);
|
void free_factions(void);
|
||||||
|
|
|
@ -24,6 +24,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "ally.h"
|
#include "ally.h"
|
||||||
#include "faction.h"
|
#include "faction.h"
|
||||||
#include "unit.h"
|
#include "unit.h"
|
||||||
|
#include "objtypes.h"
|
||||||
|
|
||||||
/* attrib includes */
|
/* attrib includes */
|
||||||
#include <attributes/raceprefix.h>
|
#include <attributes/raceprefix.h>
|
||||||
|
@ -238,16 +239,16 @@ void read_groups(gamedata *data, faction * f)
|
||||||
g = new_group(f, buf, gid);
|
g = new_group(f, buf, gid);
|
||||||
pa = &g->allies;
|
pa = &g->allies;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ally *a;
|
ally *al;
|
||||||
int fid;
|
int id;
|
||||||
|
READ_INT(store, &id);
|
||||||
fid = read_faction_reference(data);
|
if (id == 0) break;
|
||||||
if (fid <= 0)
|
al = ally_add(pa, NULL);
|
||||||
break;
|
al->faction = findfaction(id);
|
||||||
a = ally_add(pa, findfaction(fid));
|
if (!al->faction) {
|
||||||
READ_INT(store, &a->status);
|
ur_add(RESOLVE_FACTION | id, (void **)&al->faction, NULL);
|
||||||
if (!a->faction)
|
}
|
||||||
ur_add(fid, &a->faction, resolve_faction);
|
READ_INT(store, &al->status);
|
||||||
}
|
}
|
||||||
read_attribs(data, &g->attribs, g);
|
read_attribs(data, &g->attribs, g);
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,40 +258,6 @@ unsigned char index)
|
||||||
return (rel + ursprung_y(f, pl, NULL) + plane_center_y(pl));
|
return (rel + ursprung_y(f, pl, NULL) + plane_center_y(pl));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int resolve_plane(int id, void *addr)
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
plane *pl = NULL;
|
|
||||||
if (id != 0) {
|
|
||||||
pl = getplanebyid(id);
|
|
||||||
if (pl == NULL) {
|
|
||||||
result = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*(plane **)addr = pl;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void write_plane_reference(const plane * u, struct storage *store)
|
|
||||||
{
|
|
||||||
WRITE_INT(store, u ? (u->id) : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int read_plane_reference(plane ** pp, struct storage *store)
|
|
||||||
{
|
|
||||||
int id;
|
|
||||||
READ_INT(store, &id);
|
|
||||||
if (id == 0) {
|
|
||||||
*pp = NULL;
|
|
||||||
return AT_READ_FAIL;
|
|
||||||
}
|
|
||||||
*pp = getplanebyid(id);
|
|
||||||
if (*pp == NULL) {
|
|
||||||
ur_add(id, pp, resolve_plane);
|
|
||||||
}
|
|
||||||
return AT_READ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_plane(plane *pl) {
|
void free_plane(plane *pl) {
|
||||||
free(pl->name);
|
free(pl->name);
|
||||||
free(pl);
|
free(pl);
|
||||||
|
|
|
@ -69,8 +69,6 @@ extern "C" {
|
||||||
struct plane *get_homeplane(void);
|
struct plane *get_homeplane(void);
|
||||||
int rel_to_abs(const struct plane *pl, const struct faction *f,
|
int rel_to_abs(const struct plane *pl, const struct faction *f,
|
||||||
int rel, unsigned char index);
|
int rel, unsigned char index);
|
||||||
void write_plane_reference(const plane * p, struct storage *store);
|
|
||||||
int read_plane_reference(plane ** pp, struct storage *store);
|
|
||||||
int plane_width(const plane * pl);
|
int plane_width(const plane * pl);
|
||||||
int plane_height(const plane * pl);
|
int plane_height(const plane * pl);
|
||||||
void adjust_coordinates(const struct faction *f, int *x, int *y, const struct plane *pl);
|
void adjust_coordinates(const struct faction *f, int *x, int *y, const struct plane *pl);
|
||||||
|
|
|
@ -1255,50 +1255,22 @@ int production(const region * r)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve_region_coor(int id, void *address)
|
void resolve_region(region *r)
|
||||||
{
|
{
|
||||||
int x = (id >> 16);
|
resolve(RESOLVE_REGION | r->uid, r);
|
||||||
int y = id & 0xFFFF;
|
|
||||||
region *r = findregion(x, y);
|
|
||||||
if (r) {
|
|
||||||
*(region **)address = r;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*(region **)address = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve_region_id(int id, void *address)
|
int read_region_reference(gamedata * data, region **rp, resolve_fun fun)
|
||||||
{
|
|
||||||
region *r = NULL;
|
|
||||||
if (id != 0) {
|
|
||||||
r = findregionbyid(id);
|
|
||||||
if (r == NULL) {
|
|
||||||
*(region **)address = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*(region **)address = r;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int read_region_reference(gamedata *data)
|
|
||||||
{
|
{
|
||||||
struct storage * store = data->store;
|
struct storage * store = data->store;
|
||||||
int result;
|
int id = 0;
|
||||||
if (data->version < UIDHASH_VERSION) {
|
|
||||||
int n;
|
READ_INT(store, &id);
|
||||||
short x, y;
|
*rp = findregionbyid(id);
|
||||||
READ_INT(store, &n);
|
if (*rp == NULL) {
|
||||||
x = (short)n;
|
ur_add(RESOLVE_REGION | id, (void **)rp, fun);
|
||||||
READ_INT(store, &n);
|
|
||||||
y = (short)n;
|
|
||||||
result = x << 16 | (y & 0xFFFF);
|
|
||||||
}
|
}
|
||||||
else {
|
return id;
|
||||||
READ_INT(store, &result);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_region_reference(const region * r, struct storage *store)
|
void write_region_reference(const region * r, struct storage *store)
|
||||||
|
|
|
@ -19,11 +19,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#ifndef H_KRNL_REGION
|
#ifndef H_KRNL_REGION
|
||||||
#define H_KRNL_REGION
|
#define H_KRNL_REGION
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <util/resolve.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "direction.h"
|
#include "direction.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define MAXLUXURIES 16 /* there must be no more than MAXLUXURIES kinds of luxury goods in any game */
|
#define MAXLUXURIES 16 /* there must be no more than MAXLUXURIES kinds of luxury goods in any game */
|
||||||
#define MAXREGIONS 524287 /* must be prime for hashing. 262139 was a little small */
|
#define MAXREGIONS 524287 /* must be prime for hashing. 262139 was a little small */
|
||||||
#define MAXTREES 100 * 1000 * 1000 /* bug 2360: some players are crazy */
|
#define MAXTREES 100 * 1000 * 1000 /* bug 2360: some players are crazy */
|
||||||
|
@ -256,11 +259,10 @@ extern "C" {
|
||||||
int region_get_morale(const region * r);
|
int region_get_morale(const region * r);
|
||||||
void region_set_morale(region * r, int morale, int turn);
|
void region_set_morale(region * r, int morale, int turn);
|
||||||
|
|
||||||
|
#define RESOLVE_REGION (TYP_REGION << 24)
|
||||||
|
void resolve_region(region *r);
|
||||||
void write_region_reference(const struct region *r, struct storage *store);
|
void write_region_reference(const struct region *r, struct storage *store);
|
||||||
int read_region_reference(struct gamedata *data);
|
int read_region_reference(struct gamedata *data, region **rp, resolve_fun fun);
|
||||||
int resolve_region_coor(int id, void *address);
|
|
||||||
int resolve_region_id(int id, void *address);
|
|
||||||
#define RESOLVE_REGION(version) ((version<UIDHASH_VERSION)?resolve_region_coor:resolve_region_id)
|
|
||||||
|
|
||||||
const char *regionname(const struct region *r, const struct faction *f);
|
const char *regionname(const struct region *r, const struct faction *f);
|
||||||
|
|
||||||
|
|
|
@ -399,8 +399,7 @@ static void read_alliances(gamedata *data)
|
||||||
READ_INT(store, &al->flags);
|
READ_INT(store, &al->flags);
|
||||||
}
|
}
|
||||||
if (data->version >= ALLIANCELEADER_VERSION) {
|
if (data->version >= ALLIANCELEADER_VERSION) {
|
||||||
read_reference(&al->_leader, data, read_faction_reference,
|
read_faction_reference(data, &al->_leader, NULL);
|
||||||
resolve_faction);
|
|
||||||
READ_INT(store, &id);
|
READ_INT(store, &id);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -458,9 +457,10 @@ void read_planes(gamedata *data) {
|
||||||
else {
|
else {
|
||||||
/* WATCHERS - eliminated in February 2016, ca. turn 966 */
|
/* WATCHERS - eliminated in February 2016, ca. turn 966 */
|
||||||
if (data->version < NOWATCH_VERSION) {
|
if (data->version < NOWATCH_VERSION) {
|
||||||
int fno = read_faction_reference(data);
|
int fno;
|
||||||
|
READ_INT(data->store, &fno);
|
||||||
while (fno) {
|
while (fno) {
|
||||||
fno = read_faction_reference(data);
|
READ_INT(data->store, &fno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,21 +508,6 @@ void write_alliances(gamedata *data)
|
||||||
WRITE_SECTION(data->store);
|
WRITE_SECTION(data->store);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int resolve_owner(int id, void *address)
|
|
||||||
{
|
|
||||||
region_owner *owner = (region_owner *)address;
|
|
||||||
int result = 0;
|
|
||||||
faction *f = NULL;
|
|
||||||
if (id != 0) {
|
|
||||||
f = findfaction(id);
|
|
||||||
if (f == NULL) {
|
|
||||||
log_error("region has an invalid owner (%s)", itoa36(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
owner->owner = f;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void read_owner(gamedata *data, region_owner ** powner)
|
static void read_owner(gamedata *data, region_owner ** powner)
|
||||||
{
|
{
|
||||||
int since_turn;
|
int since_turn;
|
||||||
|
@ -539,9 +524,7 @@ static void read_owner(gamedata *data, region_owner ** powner)
|
||||||
owner->flags = 0;
|
owner->flags = 0;
|
||||||
}
|
}
|
||||||
if (data->version >= OWNER_3_VERSION) {
|
if (data->version >= OWNER_3_VERSION) {
|
||||||
int id;
|
read_faction_reference(data, &owner->last_owner, NULL);
|
||||||
READ_INT(data->store, &id);
|
|
||||||
owner->last_owner = id ? findfaction(id) : NULL;
|
|
||||||
}
|
}
|
||||||
else if (data->version >= OWNER_2_VERSION) {
|
else if (data->version >= OWNER_2_VERSION) {
|
||||||
int id;
|
int id;
|
||||||
|
@ -554,7 +537,7 @@ static void read_owner(gamedata *data, region_owner ** powner)
|
||||||
else {
|
else {
|
||||||
owner->last_owner = NULL;
|
owner->last_owner = NULL;
|
||||||
}
|
}
|
||||||
read_reference(owner, data, &read_faction_reference, &resolve_owner);
|
read_faction_reference(data, &owner->owner, NULL);
|
||||||
*powner = owner;
|
*powner = owner;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -817,6 +800,7 @@ unit *read_unit(gamedata *data)
|
||||||
u->hp = u->number;
|
u->hp = u->number;
|
||||||
}
|
}
|
||||||
read_attribs(data, &u->attribs, u);
|
read_attribs(data, &u->attribs, u);
|
||||||
|
resolve_unit(u);
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,6 +1065,7 @@ region *read_region(gamedata *data)
|
||||||
READ_INT(store, &x);
|
READ_INT(store, &x);
|
||||||
READ_INT(store, &y);
|
READ_INT(store, &y);
|
||||||
r = readregion(data, x, y);
|
r = readregion(data, x, y);
|
||||||
|
resolve_region(r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1152,31 +1137,6 @@ void write_region(gamedata *data, const region *r)
|
||||||
writeregion(data, r);
|
writeregion(data, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ally **addally(const faction * f, ally ** sfp, int aid, int state)
|
|
||||||
{
|
|
||||||
struct faction *af = findfaction(aid);
|
|
||||||
ally *sf;
|
|
||||||
|
|
||||||
state &= ~HELP_OBSERVE;
|
|
||||||
state &= ~HELP_TRAVEL;
|
|
||||||
state &= HelpMask();
|
|
||||||
|
|
||||||
if (state == 0)
|
|
||||||
return sfp;
|
|
||||||
|
|
||||||
while (*sfp) {
|
|
||||||
sfp = &(*sfp)->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
sf = ally_add(sfp, af);
|
|
||||||
if (!sf->faction) {
|
|
||||||
ur_add(aid, &sf->faction, resolve_faction);
|
|
||||||
}
|
|
||||||
sf->status = state & HELP_ALL;
|
|
||||||
|
|
||||||
return &sf->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_spell_level_faction(const spell * sp, void * cbdata)
|
int get_spell_level_faction(const spell * sp, void * cbdata)
|
||||||
{
|
{
|
||||||
static spellbook * common = 0;
|
static spellbook * common = 0;
|
||||||
|
@ -1255,7 +1215,6 @@ void _test_write_password(gamedata *data, const faction *f) {
|
||||||
|
|
||||||
faction *read_faction(gamedata * data)
|
faction *read_faction(gamedata * data)
|
||||||
{
|
{
|
||||||
ally **sfp;
|
|
||||||
int planes, n;
|
int planes, n;
|
||||||
faction *f;
|
faction *f;
|
||||||
char name[DISPLAYSIZE];
|
char name[DISPLAYSIZE];
|
||||||
|
@ -1384,24 +1343,13 @@ faction *read_faction(gamedata * data)
|
||||||
/* mistakes were made in the past*/
|
/* mistakes were made in the past*/
|
||||||
f->options &= ~want(O_JSON);
|
f->options &= ~want(O_JSON);
|
||||||
}
|
}
|
||||||
sfp = &f->allies;
|
read_allies(data, f);
|
||||||
for (;;) {
|
|
||||||
int aid = 0;
|
|
||||||
READ_INT(data->store, &aid);
|
|
||||||
if (aid > 0) {
|
|
||||||
int state;
|
|
||||||
READ_INT(data->store, &state);
|
|
||||||
sfp = addally(f, sfp, aid, state);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
read_groups(data, f);
|
read_groups(data, f);
|
||||||
f->spellbook = 0;
|
f->spellbook = 0;
|
||||||
if (data->version >= REGIONOWNER_VERSION) {
|
if (data->version >= REGIONOWNER_VERSION) {
|
||||||
read_spellbook(FactionSpells() ? &f->spellbook : 0, data, get_spell_level_faction, (void *)f);
|
read_spellbook(FactionSpells() ? &f->spellbook : 0, data, get_spell_level_faction, (void *)f);
|
||||||
}
|
}
|
||||||
|
resolve_faction(f);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1573,7 +1521,8 @@ struct building *read_building(gamedata *data) {
|
||||||
log_error("building too big: %s (%s size %d of %d), fixing.", buildingname(b), b->type->_name, b->size, b->type->maxsize);
|
log_error("building too big: %s (%s size %d of %d), fixing.", buildingname(b), b->type->_name, b->size, b->type->maxsize);
|
||||||
b->size = b->type->maxsize;
|
b->size = b->type->maxsize;
|
||||||
}
|
}
|
||||||
return b;
|
resolve_building(b);
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_ship(gamedata *data, const ship *sh)
|
void write_ship(gamedata *data, const ship *sh)
|
||||||
|
@ -1816,10 +1765,6 @@ int read_game(gamedata *data)
|
||||||
}
|
}
|
||||||
read_borders(data);
|
read_borders(data);
|
||||||
|
|
||||||
/* Unaufgeloeste Zeiger initialisieren */
|
|
||||||
log_debug("fixing unresolved references.");
|
|
||||||
resolve();
|
|
||||||
|
|
||||||
log_debug("updating area information for lighthouses.");
|
log_debug("updating area information for lighthouses.");
|
||||||
for (r = regions; r; r = r->next) {
|
for (r = regions; r; r = r->next) {
|
||||||
if (r->flags & RF_LIGHTHOUSE) {
|
if (r->flags & RF_LIGHTHOUSE) {
|
||||||
|
|
|
@ -648,9 +648,7 @@ void a_writesiege(const attrib * a, const void *owner, struct storage *store)
|
||||||
|
|
||||||
int a_readsiege(attrib * a, void *owner, gamedata *data)
|
int a_readsiege(attrib * a, void *owner, gamedata *data)
|
||||||
{
|
{
|
||||||
int result = read_reference(&a->data.v, data, read_building_reference,
|
if (read_building_reference(data, (building **)&a->data.v, NULL) <= 0) {
|
||||||
resolve_building);
|
|
||||||
if (result == 0 && !a->data.v) {
|
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
@ -751,24 +749,25 @@ void write_unit_reference(const unit * u, struct storage *store)
|
||||||
WRITE_INT(store, (u && u->region) ? u->no : 0);
|
WRITE_INT(store, (u && u->region) ? u->no : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve_unit(int id, void *address)
|
void resolve_unit(unit *u)
|
||||||
{
|
{
|
||||||
unit *u = NULL;
|
resolve(RESOLVE_UNIT | u->no, u);
|
||||||
if (id != 0) {
|
|
||||||
u = findunit(id);
|
|
||||||
if (u == NULL) {
|
|
||||||
*(unit **)address = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*(unit **)address = u;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_unit_reference(gamedata *data)
|
int read_unit_reference(gamedata * data, unit **up, resolve_fun fun)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
READ_INT(data->store, &id);
|
READ_INT(data->store, &id);
|
||||||
|
if (id > 0) {
|
||||||
|
*up = findunit(id);
|
||||||
|
if (*up == NULL) {
|
||||||
|
*up = NULL;
|
||||||
|
ur_add(RESOLVE_UNIT | id, (void **)up, fun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*up = NULL;
|
||||||
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#ifndef H_KRNL_UNIT_H
|
#ifndef H_KRNL_UNIT_H
|
||||||
#define H_KRNL_UNIT_H
|
#define H_KRNL_UNIT_H
|
||||||
|
|
||||||
#include <util/variant.h>
|
#include <util/resolve.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "skills.h"
|
#include "skills.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@ -182,12 +182,13 @@ extern "C" {
|
||||||
#define GIFT_FRIENDS 1<<1
|
#define GIFT_FRIENDS 1<<1
|
||||||
#define GIFT_PEASANTS 1<<2
|
#define GIFT_PEASANTS 1<<2
|
||||||
int gift_items(struct unit *u, int flags);
|
int gift_items(struct unit *u, int flags);
|
||||||
void make_zombie(unit * u);
|
void make_zombie(struct unit * u);
|
||||||
|
|
||||||
/* see resolve.h */
|
/* see resolve.h */
|
||||||
int resolve_unit(int id, void *address);
|
#define RESOLVE_UNIT (TYP_UNIT << 24)
|
||||||
|
void resolve_unit(struct unit *u);
|
||||||
void write_unit_reference(const struct unit *u, struct storage *store);
|
void write_unit_reference(const struct unit *u, struct storage *store);
|
||||||
int read_unit_reference(struct gamedata *data);
|
int read_unit_reference(struct gamedata * data, struct unit **up, resolve_fun fun);
|
||||||
|
|
||||||
bool leave(struct unit *u, bool force);
|
bool leave(struct unit *u, bool force);
|
||||||
bool can_leave(struct unit *u);
|
bool can_leave(struct unit *u);
|
||||||
|
|
45
src/magic.c
45
src/magic.c
|
@ -2262,26 +2262,21 @@ bool create_newfamiliar(unit * mage, unit * familiar)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int resolve_familiar(int id, void *addr)
|
static void * resolve_familiar(int id, void *data) {
|
||||||
{
|
if (data) {
|
||||||
unit *familiar;
|
unit *familiar = (unit *)data;
|
||||||
int result = resolve_unit(id, &familiar);
|
|
||||||
if (result == 0 && familiar) {
|
|
||||||
attrib *a = a_find(familiar->attribs, &at_familiarmage);
|
attrib *a = a_find(familiar->attribs, &at_familiarmage);
|
||||||
if (a != NULL && a->data.v) {
|
if (a != NULL && a->data.v) {
|
||||||
unit *mage = (unit *)a->data.v;
|
unit *mage = (unit *)a->data.v;
|
||||||
set_familiar(mage, familiar);
|
set_familiar(mage, familiar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*(unit **)addr = familiar;
|
return data;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_familiar(attrib * a, void *owner, struct gamedata *data)
|
static int read_familiar(attrib * a, void *owner, struct gamedata *data)
|
||||||
{
|
{
|
||||||
int result =
|
if (read_unit_reference(data, (unit **)&a->data.v, resolve_familiar) <= 0) {
|
||||||
read_reference(&a->data.v, data, read_unit_reference, resolve_familiar);
|
|
||||||
if (result == 0 && a->data.v == NULL) {
|
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
@ -2346,52 +2341,42 @@ unit *has_clone(unit * mage)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int resolve_clone(int id, void *addr)
|
static void * resolve_clone(int id, void *data) {
|
||||||
{
|
if (data) {
|
||||||
unit *clone;
|
unit *clone = (unit *)data;
|
||||||
int result = resolve_unit(id, &clone);
|
|
||||||
if (result == 0 && clone) {
|
|
||||||
attrib *a = a_find(clone->attribs, &at_clonemage);
|
attrib *a = a_find(clone->attribs, &at_clonemage);
|
||||||
if (a != NULL && a->data.v) {
|
if (a != NULL && a->data.v) {
|
||||||
unit *mage = (unit *)a->data.v;
|
unit *mage = (unit *)a->data.v;
|
||||||
set_clone(mage, clone);
|
set_clone(mage, clone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*(unit **)addr = clone;
|
return data;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_clone(attrib * a, void *owner, struct gamedata *data)
|
static int read_clone(attrib * a, void *owner, struct gamedata *data)
|
||||||
{
|
{
|
||||||
int result =
|
if (read_unit_reference(data, (unit **)&a->data.v, resolve_clone) <= 0) {
|
||||||
read_reference(&a->data.v, data, read_unit_reference, resolve_clone);
|
|
||||||
if (result == 0 && a->data.v == NULL) {
|
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mages */
|
/* mages */
|
||||||
static int resolve_mage(int id, void *addr)
|
static void * resolve_mage(int id, void *data) {
|
||||||
{
|
if (data) {
|
||||||
unit *mage;
|
unit *mage = (unit *)data;
|
||||||
int result = resolve_unit(id, &mage);
|
|
||||||
if (result == 0 && mage) {
|
|
||||||
attrib *a = a_find(mage->attribs, &at_familiar);
|
attrib *a = a_find(mage->attribs, &at_familiar);
|
||||||
if (a != NULL && a->data.v) {
|
if (a != NULL && a->data.v) {
|
||||||
unit *familiar = (unit *)a->data.v;
|
unit *familiar = (unit *)a->data.v;
|
||||||
set_familiar(mage, familiar);
|
set_familiar(mage, familiar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*(unit **)addr = mage;
|
return data;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_magician(attrib * a, void *owner, struct gamedata *data)
|
static int read_magician(attrib * a, void *owner, struct gamedata *data)
|
||||||
{
|
{
|
||||||
int result =
|
if (read_unit_reference(data, (unit **)&a->data.v, resolve_mage) <= 0) {
|
||||||
read_reference(&a->data.v, data, read_unit_reference, resolve_mage);
|
|
||||||
if (result == 0 && a->data.v == NULL) {
|
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
#include "xmas.h"
|
#include "xmas.h"
|
||||||
|
|
||||||
/* kernel includes */
|
/* kernel includes */
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
#include <kernel/item.h>
|
#include <kernel/item.h>
|
||||||
|
@ -50,10 +50,7 @@ static void xmasgate_write(const trigger * t, struct storage *store)
|
||||||
|
|
||||||
static int xmasgate_read(trigger * t, struct gamedata *data)
|
static int xmasgate_read(trigger * t, struct gamedata *data)
|
||||||
{
|
{
|
||||||
int bc =
|
if (read_building_reference(data, (building **)&t->data.v, NULL) <= 0) {
|
||||||
read_reference(&t->data.v, data, read_building_reference,
|
|
||||||
resolve_building);
|
|
||||||
if (bc == 0 && !t->data.v) {
|
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
|
41
src/spells.c
41
src/spells.c
|
@ -2892,47 +2892,20 @@ static curse *mk_deathcloud(unit * mage, region * r, double force, int duration)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COMPAT_DEATHCLOUD
|
|
||||||
#ifdef COMPAT_DEATHCLOUD
|
|
||||||
static int dc_read_compat(struct attrib *a, void *target, gamedata *data)
|
static int dc_read_compat(struct attrib *a, void *target, gamedata *data)
|
||||||
/* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */
|
/* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */
|
||||||
{
|
{
|
||||||
struct storage *store = data->store;
|
struct storage *store = data->store;
|
||||||
region *r = NULL;
|
|
||||||
unit *u;
|
|
||||||
int id;
|
|
||||||
int duration;
|
|
||||||
float strength;
|
|
||||||
int rx, ry;
|
|
||||||
|
|
||||||
UNUSED_ARG(a);
|
UNUSED_ARG(a);
|
||||||
UNUSED_ARG(target);
|
UNUSED_ARG(target);
|
||||||
READ_INT(store, &duration);
|
READ_INT(store, NULL);
|
||||||
READ_FLT(store, &strength);
|
READ_FLT(store, NULL);
|
||||||
READ_INT(store, &id);
|
READ_INT(store, NULL);
|
||||||
u = findunit(id);
|
READ_INT(store, NULL);
|
||||||
|
READ_INT(store, NULL);
|
||||||
/* this only affects really old data. no need to change: */
|
return AT_READ_DEPR; /* we don't care for the attribute. */
|
||||||
READ_INT(store, &rx);
|
|
||||||
READ_INT(store, &ry);
|
|
||||||
r = findregion(rx, ry);
|
|
||||||
|
|
||||||
if (r != NULL) {
|
|
||||||
double effect;
|
|
||||||
curse *c;
|
|
||||||
|
|
||||||
effect = strength;
|
|
||||||
c =
|
|
||||||
create_curse(u, &r->attribs, &ct_deathcloud, strength * 2, duration,
|
|
||||||
effect, 0);
|
|
||||||
c->data.v = r;
|
|
||||||
if (u == NULL) {
|
|
||||||
ur_add(id, &c->magician, resolve_unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return AT_READ_FAIL; /* we don't care for the attribute. */
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Name: Todeswolke
|
/* Name: Todeswolke
|
||||||
|
@ -6705,9 +6678,7 @@ void register_spells(void)
|
||||||
{
|
{
|
||||||
register_borders();
|
register_borders();
|
||||||
|
|
||||||
#ifdef COMPAT_DEATHCLOUD
|
|
||||||
at_deprecate("zauber_todeswolke", dc_read_compat);
|
at_deprecate("zauber_todeswolke", dc_read_compat);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* init_firewall(); */
|
/* init_firewall(); */
|
||||||
ct_register(&ct_firewall);
|
ct_register(&ct_firewall);
|
||||||
|
|
|
@ -92,7 +92,7 @@ static void wall_read(connection * b, gamedata * data)
|
||||||
static wall_data dummy;
|
static wall_data dummy;
|
||||||
wall_data *fd = b->data.v ? (wall_data *)b->data.v : &dummy;
|
wall_data *fd = b->data.v ? (wall_data *)b->data.v : &dummy;
|
||||||
|
|
||||||
read_reference(&fd->mage, data, read_unit_reference, resolve_unit);
|
read_unit_reference(data, &fd->mage, NULL);
|
||||||
READ_INT(data->store, &fd->force);
|
READ_INT(data->store, &fd->force);
|
||||||
READ_INT(data->store, &fd->countdown);
|
READ_INT(data->store, &fd->countdown);
|
||||||
fd->active = true;
|
fd->active = true;
|
||||||
|
|
|
@ -83,16 +83,10 @@ static void changefaction_write(const trigger * t, struct storage *store)
|
||||||
|
|
||||||
static int changefaction_read(trigger * t, gamedata *data)
|
static int changefaction_read(trigger * t, gamedata *data)
|
||||||
{
|
{
|
||||||
int id;
|
|
||||||
changefaction_data *td = (changefaction_data *)t->data.v;
|
changefaction_data *td = (changefaction_data *)t->data.v;
|
||||||
|
|
||||||
read_reference(&td->unit, data, read_unit_reference, resolve_unit);
|
read_unit_reference(data, &td->unit, NULL);
|
||||||
id = read_faction_reference(data);
|
return read_faction_reference(data, &td->faction, NULL) > 0 ? AT_READ_OK : AT_READ_FAIL;
|
||||||
if (id == 0) {
|
|
||||||
return AT_READ_FAIL;
|
|
||||||
}
|
|
||||||
ur_add(id, &td->faction, resolve_faction);
|
|
||||||
return AT_READ_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger_type tt_changefaction = {
|
trigger_type tt_changefaction = {
|
||||||
|
|
|
@ -89,7 +89,7 @@ static void changerace_write(const trigger * t, struct storage *store)
|
||||||
static int changerace_read(trigger * t, gamedata *data)
|
static int changerace_read(trigger * t, gamedata *data)
|
||||||
{
|
{
|
||||||
changerace_data *td = (changerace_data *)t->data.v;
|
changerace_data *td = (changerace_data *)t->data.v;
|
||||||
read_reference(&td->u, data, read_unit_reference, resolve_unit);
|
read_unit_reference(data, &td->u, NULL);
|
||||||
td->race = read_race_reference(data->store);
|
td->race = read_race_reference(data->store);
|
||||||
td->irace = read_race_reference(data->store);
|
td->irace = read_race_reference(data->store);
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
|
|
@ -70,9 +70,7 @@ static void clonedied_write(const trigger * t, struct storage *store)
|
||||||
|
|
||||||
static int clonedied_read(trigger * t, gamedata *data)
|
static int clonedied_read(trigger * t, gamedata *data)
|
||||||
{
|
{
|
||||||
int result =
|
if (read_unit_reference(data, (unit **)&t->data.v, NULL) <= 0) {
|
||||||
read_reference(&t->data.v, data, read_unit_reference, resolve_unit);
|
|
||||||
if (result == 0 && t->data.v == NULL) {
|
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
|
|
@ -98,8 +98,8 @@ static int createcurse_read(trigger * t, gamedata *data)
|
||||||
char zText[128];
|
char zText[128];
|
||||||
float flt;
|
float flt;
|
||||||
|
|
||||||
read_reference(&td->mage, data, read_unit_reference, resolve_unit);
|
read_unit_reference(data, &td->mage, NULL);
|
||||||
read_reference(&td->target, data, read_unit_reference, resolve_unit);
|
read_unit_reference(data, &td->target, NULL);
|
||||||
|
|
||||||
READ_TOK(data->store, zText, sizeof(zText));
|
READ_TOK(data->store, zText, sizeof(zText));
|
||||||
td->type = ct_find(zText);
|
td->type = ct_find(zText);
|
||||||
|
|
|
@ -92,19 +92,13 @@ static int createunit_read(trigger * t, gamedata *data)
|
||||||
createunit_data *td = (createunit_data *)t->data.v;
|
createunit_data *td = (createunit_data *)t->data.v;
|
||||||
int id;
|
int id;
|
||||||
int result = AT_READ_OK;
|
int result = AT_READ_OK;
|
||||||
id = read_faction_reference(data);
|
|
||||||
if (id > 0) {
|
id = read_faction_reference(data, &td->f, NULL);
|
||||||
td->f = findfaction(id);
|
if (id <= 0) {
|
||||||
if (!td->f) {
|
|
||||||
ur_add(id, &td->f, resolve_faction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = AT_READ_FAIL;
|
result = AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_reference(&td->r, data, read_region_reference,
|
read_region_reference(data, &td->r, NULL);
|
||||||
RESOLVE_REGION(data->version));
|
|
||||||
td->race = read_race_reference(data->store);
|
td->race = read_race_reference(data->store);
|
||||||
if (!td->race) {
|
if (!td->race) {
|
||||||
result = AT_READ_FAIL;
|
result = AT_READ_FAIL;
|
||||||
|
|
|
@ -74,16 +74,11 @@ static void gate_write(const trigger * t, struct storage *store)
|
||||||
static int gate_read(trigger * t, gamedata *data)
|
static int gate_read(trigger * t, gamedata *data)
|
||||||
{
|
{
|
||||||
gate_data *gd = (gate_data *)t->data.v;
|
gate_data *gd = (gate_data *)t->data.v;
|
||||||
|
int bc = read_building_reference(data, &gd->gate, NULL);
|
||||||
|
int rc = read_region_reference(data, &gd->target, NULL);
|
||||||
|
|
||||||
int bc =
|
if (bc <= 0 && rc <= 0) {
|
||||||
read_reference(&gd->gate, data, read_building_reference, resolve_building);
|
return AT_READ_FAIL;
|
||||||
int rc =
|
|
||||||
read_reference(&gd->target, data, read_region_reference,
|
|
||||||
RESOLVE_REGION(data->version));
|
|
||||||
|
|
||||||
if (bc == 0 && rc == 0) {
|
|
||||||
if (!gd->gate || !gd->target)
|
|
||||||
return AT_READ_FAIL;
|
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,15 +86,16 @@ static int giveitem_read(trigger * t, gamedata *data)
|
||||||
{
|
{
|
||||||
giveitem_data *td = (giveitem_data *)t->data.v;
|
giveitem_data *td = (giveitem_data *)t->data.v;
|
||||||
char zText[128];
|
char zText[128];
|
||||||
|
int result;
|
||||||
|
|
||||||
int result = read_reference(&td->u, data, read_unit_reference, resolve_unit);
|
result = read_unit_reference(data, &td->u, NULL);
|
||||||
|
|
||||||
READ_INT(data->store, &td->number);
|
READ_INT(data->store, &td->number);
|
||||||
READ_TOK(data->store, zText, sizeof(zText));
|
READ_TOK(data->store, zText, sizeof(zText));
|
||||||
td->itype = it_find(zText);
|
td->itype = it_find(zText);
|
||||||
assert(td->itype);
|
assert(td->itype);
|
||||||
|
|
||||||
if (result == 0 && td->u == NULL) {
|
if (result == 0) {
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
|
|
@ -60,9 +60,7 @@ static void killunit_write(const trigger * t, struct storage *store)
|
||||||
|
|
||||||
static int killunit_read(trigger * t, gamedata *data)
|
static int killunit_read(trigger * t, gamedata *data)
|
||||||
{
|
{
|
||||||
int result = read_reference(&t->data.v, data, read_unit_reference,
|
if (read_unit_reference(data, (unit **)&t->data.v, NULL) == 0) {
|
||||||
resolve_unit);
|
|
||||||
if (result == 0 && t->data.v == NULL) {
|
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
|
|
@ -125,11 +125,8 @@ static void shock_write(const trigger * t, struct storage *store)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int shock_read(trigger * t, gamedata *data)
|
static int shock_read(trigger * t, gamedata *data) {
|
||||||
{
|
if (read_unit_reference(data, (unit **)&t->data.v, NULL) <= 0) {
|
||||||
int result =
|
|
||||||
read_reference(&t->data.v, data, read_unit_reference, resolve_unit);
|
|
||||||
if (result == 0 && t->data.v == NULL) {
|
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
return AT_READ_OK;
|
return AT_READ_OK;
|
||||||
|
|
|
@ -17,73 +17,85 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
|
|
||||||
|
#include <selist.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "resolve.h"
|
#include "resolve.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
#include "variant.h"
|
#include "variant.h"
|
||||||
|
|
||||||
typedef struct unresolved {
|
typedef struct unresolved {
|
||||||
void *ptrptr;
|
int id;
|
||||||
/* address to pass to the resolve-function */
|
|
||||||
variant data;
|
|
||||||
/* information on how to resolve the missing object */
|
/* information on how to resolve the missing object */
|
||||||
resolve_fun resolve;
|
resolve_fun resolve;
|
||||||
/* function to resolve the unknown object */
|
/* function to resolve the unknown object */
|
||||||
|
selist *addrs;
|
||||||
|
/* address to pass to the resolve-function */
|
||||||
} unresolved;
|
} unresolved;
|
||||||
|
|
||||||
#define BLOCKSIZE 1024
|
#define HASHSIZE 1024 /* must be a power of 2 */
|
||||||
static unresolved *ur_list;
|
static unresolved ur_hash[HASHSIZE];
|
||||||
static unresolved *ur_begin;
|
|
||||||
static unresolved *ur_current;
|
|
||||||
|
|
||||||
int
|
int ur_key(int id) {
|
||||||
read_reference(void *address, struct gamedata * data, read_fun reader,
|
int h = id ^ (id >> 16);
|
||||||
resolve_fun resolver)
|
return h & (HASHSIZE - 1);
|
||||||
{
|
|
||||||
int id = reader(data);
|
|
||||||
int result = resolver(id, address);
|
|
||||||
if (result != 0) {
|
|
||||||
ur_add(id, address, resolver);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ur_add(int id, void *ptrptr, resolve_fun fun)
|
void ur_add(int id, void **addr, resolve_fun fun)
|
||||||
{
|
{
|
||||||
assert(ptrptr);
|
int h, i;
|
||||||
if (ur_list == NULL) {
|
|
||||||
ur_list = malloc(BLOCKSIZE * sizeof(unresolved));
|
|
||||||
ur_begin = ur_current = ur_list;
|
|
||||||
}
|
|
||||||
else if (ur_current - ur_begin == BLOCKSIZE - 1) {
|
|
||||||
ur_begin = malloc(BLOCKSIZE * sizeof(unresolved));
|
|
||||||
ur_current->data.v = ur_begin;
|
|
||||||
ur_current = ur_begin;
|
|
||||||
}
|
|
||||||
ur_current->data.i = id;
|
|
||||||
ur_current->resolve = fun;
|
|
||||||
ur_current->ptrptr = ptrptr;
|
|
||||||
|
|
||||||
++ur_current;
|
assert(id > 0);
|
||||||
ur_current->resolve = NULL;
|
assert(addr);
|
||||||
ur_current->data.v = NULL;
|
assert(!*addr);
|
||||||
}
|
|
||||||
|
|
||||||
void resolve(void)
|
h = ur_key(id);
|
||||||
{
|
for (i = 0; i != HASHSIZE; ++i) {
|
||||||
unresolved *ur = ur_list;
|
int k = h + i;
|
||||||
while (ur) {
|
if (k >= HASHSIZE) k -= HASHSIZE;
|
||||||
if (ur->resolve == NULL) {
|
if (ur_hash[k].id <= 0) {
|
||||||
ur = ur->data.v;
|
ur_hash[k].id = id;
|
||||||
free(ur_list);
|
ur_hash[k].resolve = fun;
|
||||||
ur_list = ur;
|
selist_push(&ur_hash[k].addrs, addr);
|
||||||
continue;
|
return;
|
||||||
|
}
|
||||||
|
if (ur_hash[k].id == id && ur_hash[k].resolve == fun) {
|
||||||
|
ur_hash[k].resolve = fun;
|
||||||
|
selist_push(&ur_hash[k].addrs, addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(!"hash table is full");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool addr_cb(void *data, void *more) {
|
||||||
|
void **addr = (void **)data;
|
||||||
|
*addr = more;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resolve(int id, void *data)
|
||||||
|
{
|
||||||
|
int h, i;
|
||||||
|
h = ur_key(id);
|
||||||
|
|
||||||
|
for (i = 0; i != HASHSIZE; ++i) {
|
||||||
|
int k = h + i;
|
||||||
|
|
||||||
|
if (k >= HASHSIZE) k -= HASHSIZE;
|
||||||
|
if (ur_hash[k].id == 0) break;
|
||||||
|
else if (ur_hash[k].id == id) {
|
||||||
|
if (ur_hash[k].resolve) {
|
||||||
|
data = ur_hash[k].resolve(id, data);
|
||||||
|
}
|
||||||
|
selist_foreach_ex(ur_hash[k].addrs, addr_cb, data);
|
||||||
|
selist_free(ur_hash[k].addrs);
|
||||||
|
ur_hash[k].addrs = NULL;
|
||||||
|
ur_hash[k].id = -1;
|
||||||
}
|
}
|
||||||
assert(ur->ptrptr);
|
|
||||||
ur->resolve(ur->data.i, ur->ptrptr);
|
|
||||||
++ur;
|
|
||||||
}
|
}
|
||||||
free(ur_list);
|
|
||||||
ur_list = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,11 @@ struct gamedata;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef int(*resolve_fun) (int id, void *address);
|
typedef void *(*resolve_fun) (int id, void *data);
|
||||||
typedef int(*read_fun) (struct gamedata * data);
|
typedef int(*read_fun) (struct gamedata * data);
|
||||||
int read_reference(void *address, struct gamedata *data,
|
|
||||||
read_fun reader, resolve_fun resolver);
|
|
||||||
|
|
||||||
void ur_add(int id, void *address, resolve_fun fun);
|
void ur_add(int id, void **addr, resolve_fun fun);
|
||||||
void resolve(void);
|
void resolve(int id, void *data);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,36 +96,15 @@ static void wormhole_write(const struct attrib *a, const void *owner, struct sto
|
||||||
write_region_reference(exit, store);
|
write_region_reference(exit, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** conversion code, turn 573, 2008-05-23 */
|
|
||||||
static int resolve_exit(int id, void *address)
|
|
||||||
{
|
|
||||||
building *b = findbuilding(id);
|
|
||||||
region **rp = address;
|
|
||||||
if (b) {
|
|
||||||
*rp = b->region;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*rp = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int wormhole_read(struct attrib *a, void *owner, struct gamedata *data)
|
static int wormhole_read(struct attrib *a, void *owner, struct gamedata *data)
|
||||||
{
|
{
|
||||||
storage *store = data->store;
|
int id;
|
||||||
resolve_fun resolver = (data->version < UIDHASH_VERSION)
|
|
||||||
? resolve_exit : resolve_region_id;
|
|
||||||
read_fun reader = (data->version < UIDHASH_VERSION)
|
|
||||||
? read_building_reference : read_region_reference;
|
|
||||||
|
|
||||||
if (data->version < ATTRIBOWNER_VERSION) {
|
if (data->version < ATTRIBOWNER_VERSION) {
|
||||||
READ_INT(store, NULL);
|
READ_INT(data->store, NULL);
|
||||||
}
|
}
|
||||||
if (read_reference(&a->data.v, data, reader, resolver) == 0) {
|
id = read_region_reference(data, (region **)&a->data.v, NULL);
|
||||||
if (!a->data.v) {
|
return (id <= 0) ? AT_READ_FAIL : AT_READ_OK;
|
||||||
return AT_READ_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return AT_READ_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static attrib_type at_wormhole = {
|
static attrib_type at_wormhole = {
|
||||||
|
|
Loading…
Reference in New Issue