- new planes/torus code is (close to) finished and has bugs fixed.

- new CR version
-  fixed E3 test for spells.
This commit is contained in:
Enno Rehling 2009-06-29 10:50:52 +00:00
parent 5b6b638a37
commit 7d79d0bc00
36 changed files with 839 additions and 406 deletions

View file

@ -81,7 +81,7 @@ extern int verbosity;
boolean opt_cr_absolute_coords = false; boolean opt_cr_absolute_coords = false;
/* globals */ /* globals */
#define C_REPORT_VERSION 64 #define C_REPORT_VERSION 65
#define TAG_LOCALE "de" #define TAG_LOCALE "de"
#ifdef TAG_LOCALE #ifdef TAG_LOCALE
@ -309,8 +309,9 @@ cr_region(variant var, char * buffer, const void * userdata)
const faction * report = (const faction*)userdata; const faction * report = (const faction*)userdata;
region * r = (region *)var.v; region * r = (region *)var.v;
if (r) { if (r) {
plane * p = r->planep; plane * pl = rplane(r);
sprintf(buffer, "%d %d %d", region_x(r, report), region_y(r, report), p?p->id:0); int nx = region_x(r, report), ny = region_y(r, report);
sprintf(buffer, "%d %d %d", nx, ny, plane_id(pl));
return 0; return 0;
} }
return -1; return -1;
@ -419,14 +420,17 @@ cr_regions(variant var, char * buffer, const void * userdata)
if (rdata!=NULL && rdata->nregions>0) { if (rdata!=NULL && rdata->nregions>0) {
region * r = rdata->regions[0]; region * r = rdata->regions[0];
int i, z = r->planep?r->planep->id:0; plane * pl = rplane(r);
int i, z = plane_id(pl);
char * wp = buffer; char * wp = buffer;
int nx = region_x(r, f), ny = region_y(r, f);
wp += sprintf(wp, "\"%d %d %d", region_x(r, f), region_y(r, f), z); wp += sprintf(wp, "\"%d %d %d", nx, ny, z);
for (i=1;i!=rdata->nregions;++i) { for (i=1;i!=rdata->nregions;++i) {
r = rdata->regions[i]; r = rdata->regions[i];
z = r->planep?r->planep->id:0; pl = rplane(r);
wp += sprintf(wp, ", %d %d %d", region_x(r, f), region_y(r, f), z); z = plane_id(pl);
wp += sprintf(wp, ", %d %d %d", nx, ny, z);
} }
strcat(wp, "\""); strcat(wp, "\"");
} else { } else {
@ -1093,17 +1097,25 @@ cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
{ {
faction * f = ctx->f; faction * f = ctx->f;
region * r = sr->r; region * r = sr->r;
plane * pl = rplane(r);
int plid = plane_id(pl), nx, ny;
const char * tname; const char * tname;
if (!r->planep) {
if (opt_cr_absolute_coords) { if (opt_cr_absolute_coords) {
fprintf(F, "REGION %d %d\n", r->x, r->x); nx = r->x;
} else { ny = r->y;
fprintf(F, "REGION %d %d\n", region_x(r, f), region_y(r, f));
}
} else { } else {
fprintf(F, "REGION %d %d %d\n", region_x(r, f), region_y(r, f), r->planep->id); nx = region_x(r, f);
ny = region_y(r, f);
}
if (plid==0) {
fprintf(F, "REGION %d %d\n", nx, ny);
} else {
fprintf(F, "REGION %d %d %d\n", nx, ny, plid);
} }
fprintf(F, "%d;id\n", r->uid); fprintf(F, "%d;id\n", r->uid);
if (r->land) { if (r->land) {
const char * str = rname(r, f->locale); const char * str = rname(r, f->locale);
if (str && str[0]) { if (str && str[0]) {
@ -1200,7 +1212,9 @@ cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
region_list *rl2 = rl; region_list *rl2 = rl;
while(rl2) { while(rl2) {
region * r = rl2->data; region * r = rl2->data;
fprintf(F, "SCHEMEN %d %d\n", region_x(r, f), region_y(r, f)); plane * pl = rplane(r);
int nx = region_x(r, f), ny = region_y(r, f);
fprintf(F, "SCHEMEN %d %d\n", nx, ny);
fprintf(F, "\"%s\";Name\n", rname(r, f->locale)); fprintf(F, "\"%s\";Name\n", rname(r, f->locale));
rl2 = rl2->next; rl2 = rl2->next;
} }
@ -1275,6 +1289,7 @@ cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
static int static int
report_computer(const char * filename, report_context * ctx, const char * charset) report_computer(const char * filename, report_context * ctx, const char * charset)
{ {
static int era = -1;
int i; int i;
faction * f = ctx->f; faction * f = ctx->f;
const char * prefix; const char * prefix;
@ -1288,6 +1303,9 @@ report_computer(const char * filename, report_context * ctx, const char * charse
int enc = xmlParseCharEncoding(charset); int enc = xmlParseCharEncoding(charset);
FILE * F = fopen(filename, "wt"); FILE * F = fopen(filename, "wt");
if (era<0) {
era = get_param_int(global.parameters, "world.era", 2);
}
if (F==NULL) { if (F==NULL) {
perror(filename); perror(filename);
return -1; return -1;
@ -1310,7 +1328,7 @@ report_computer(const char * filename, report_context * ctx, const char * charse
fprintf(F, "\"%s\";Koordinaten\n", "Hex"); fprintf(F, "\"%s\";Koordinaten\n", "Hex");
fprintf(F, "%d;Basis\n", 36); fprintf(F, "%d;Basis\n", 36);
fprintf(F, "%d;Runde\n", turn); fprintf(F, "%d;Runde\n", turn);
fputs("2;Zeitalter\n", F); fprintf(F, "%d;Zeitalter\n", era);
if (mailto!=NULL) { if (mailto!=NULL) {
fprintf(F, "\"%s\";mailto\n", mailto); fprintf(F, "\"%s\";mailto\n", mailto);
fprintf(F, "\"%s\";mailcmd\n", locale_string(f->locale, "mailcmd")); fprintf(F, "\"%s\";mailcmd\n", locale_string(f->locale, "mailcmd"));
@ -1389,9 +1407,12 @@ report_computer(const char * filename, report_context * ctx, const char * charse
{ {
struct bmsg * bm; struct bmsg * bm;
for (bm=f->battles;bm;bm=bm->next) { for (bm=f->battles;bm;bm=bm->next) {
if (!bm->r->planep) fprintf(F, "BATTLE %d %d\n", region_x(bm->r, f), region_y(bm->r, f)); plane * pl = rplane(bm->r);
int plid = plane_id(pl);
int nx = region_x(bm->r, f), ny = region_y(bm->r, f);
if (!plid) fprintf(F, "BATTLE %d %d\n", nx, ny);
else { else {
fprintf(F, "BATTLE %d %d %d\n", region_x(bm->r, f), region_y(bm->r, f), bm->r->planep->id); fprintf(F, "BATTLE %d %d %d\n", nx, ny, plid);
} }
cr_output_messages(F, bm->msgs, f); cr_output_messages(F, bm->msgs, f);
} }
@ -1452,9 +1473,18 @@ crwritemap(const char * filename)
{ {
FILE * F = fopen(filename, "w+"); FILE * F = fopen(filename, "w+");
region * r; region * r;
fprintf(F, "VERSION %d\n", C_REPORT_VERSION);
fputs("\"UTF-8\";charset\n", F);
for (r=regions;r;r=r->next) { for (r=regions;r;r=r->next) {
plane * p = r->planep; plane * pl = rplane(r);
fprintf(F, "REGION %d %d %d\n", r->x, r->y, p?p->id:0); int plid = plane_id(pl);
if (plid) {
fprintf(F, "REGION %d %d %d\n", r->x, r->y, plid);
} else {
fprintf(F, "REGION %d %d\n", r->x, r->y);
}
fprintf(F, "\"%s\";Name\n\"%s\";Terrain\n", rname(r, default_locale), LOC(default_locale, terrain_name(r))); fprintf(F, "\"%s\";Name\n\"%s\";Terrain\n", rname(r, default_locale), LOC(default_locale, terrain_name(r)));
} }
fclose(F); fclose(F);

View file

@ -622,6 +622,7 @@ give_cmd(unit * u, order * ord)
int i, n, rule = rule_give(); int i, n, rule = rule_give();
const item_type * itype; const item_type * itype;
param_t p; param_t p;
plane * pl;
init_tokens(ord); init_tokens(ord);
skip_token(); skip_token();
@ -652,7 +653,8 @@ give_cmd(unit * u, order * ord)
/* UFL_TAKEALL ist ein grober Hack. Generalisierung tut not, ist aber nicht /* UFL_TAKEALL ist ein grober Hack. Generalisierung tut not, ist aber nicht
* wirklich einfach. */ * wirklich einfach. */
if (r->planep && fval(r->planep, PFL_NOGIVE) && (!u2 || !fval(u2, UFL_TAKEALL))) { pl = rplane(r);
if (pl && fval(pl, PFL_NOGIVE) && (!u2 || !fval(u2, UFL_TAKEALL))) {
cmistake(u, ord, 268, MSG_COMMERCE); cmistake(u, ord, 268, MSG_COMMERCE);
return; return;
} }
@ -1811,15 +1813,12 @@ make_cmd(unit * u, struct order * ord)
* aufruf von make geeicht */ * aufruf von make geeicht */
if (p == P_ROAD) { if (p == P_ROAD) {
if(r->planep && fval(r->planep, PFL_NOBUILD)) { plane * pl = rplane(r);
if (pl && fval(pl, PFL_NOBUILD)) {
cmistake(u, ord, 275, MSG_PRODUCE); cmistake(u, ord, 275, MSG_PRODUCE);
} else { } else {
direction_t d = finddirection(getstrtoken(), u->faction->locale); direction_t d = finddirection(getstrtoken(), u->faction->locale);
if (d!=NODIRECTION) { if (d!=NODIRECTION) {
if(r->planep && fval(r->planep, PFL_NOBUILD)) {
cmistake(u, ord, 94, MSG_PRODUCE);
return 0;
}
build_road(r, u, m, d); build_road(r, u, m, d);
} else { } else {
/* Die Richtung wurde nicht erkannt */ /* Die Richtung wurde nicht erkannt */
@ -1828,7 +1827,8 @@ make_cmd(unit * u, struct order * ord)
} }
return 0; return 0;
} else if (p == P_SHIP) { } else if (p == P_SHIP) {
if(r->planep && fval(r->planep, PFL_NOBUILD)) { plane * pl = rplane(r);
if (pl && fval(pl, PFL_NOBUILD)) {
cmistake(u, ord, 276, MSG_PRODUCE); cmistake(u, ord, 276, MSG_PRODUCE);
} else { } else {
continue_ship(r, u, m); continue_ship(r, u, m);
@ -1872,13 +1872,15 @@ make_cmd(unit * u, struct order * ord)
} }
if (stype != NOSHIP) { if (stype != NOSHIP) {
if(r->planep && fval(r->planep, PFL_NOBUILD)) { plane * pl = rplane(r);
if (pl && fval(pl, PFL_NOBUILD)) {
cmistake(u, ord, 276, MSG_PRODUCE); cmistake(u, ord, 276, MSG_PRODUCE);
} else { } else {
create_ship(r, u, stype, m, ord); create_ship(r, u, stype, m, ord);
} }
} else if (btype != NOBUILDING) { } else if (btype != NOBUILDING) {
if(r->planep && fval(r->planep, PFL_NOBUILD)) { plane * pl = rplane(r);
if (pl && fval(pl, PFL_NOBUILD)) {
cmistake(u, ord, 94, MSG_PRODUCE); cmistake(u, ord, 94, MSG_PRODUCE);
} else { } else {
build_building(u, btype, m, ord); build_building(u, btype, m, ord);
@ -2836,6 +2838,7 @@ steal_cmd(unit * u, struct order * ord, request ** stealorders)
unit * u2 = NULL; unit * u2 = NULL;
region * r = u->region; region * r = u->region;
faction * f = NULL; faction * f = NULL;
plane * pl;
assert(skill_enabled[SK_PERCEPTION] && skill_enabled[SK_STEALTH]); assert(skill_enabled[SK_PERCEPTION] && skill_enabled[SK_STEALTH]);
@ -2849,7 +2852,8 @@ steal_cmd(unit * u, struct order * ord, request ** stealorders)
return; return;
} }
if (r->planep && fval(r->planep, PFL_NOATTACK)) { pl = rplane(r);
if (pl && fval(pl, PFL_NOATTACK)) {
cmistake(u, ord, 270, MSG_INCOME); cmistake(u, ord, 270, MSG_INCOME);
return; return;
} }

View file

@ -189,6 +189,7 @@ help_money(const unit * u)
static void static void
get_food(region *r) get_food(region *r)
{ {
plane * pl = rplane(r);
unit *u; unit *u;
int peasantfood = rpeasants(r)*10; int peasantfood = rpeasants(r)*10;
faction * owner = region_get_owner(r); faction * owner = region_get_owner(r);
@ -307,7 +308,7 @@ get_food(region *r)
} }
} }
} }
if (r->planep == NULL || !fval(r->planep, PFL_NOFEED)) { if (pl == NULL || !fval(pl, PFL_NOFEED)) {
if (peasantfood>=hungry) { if (peasantfood>=hungry) {
peasantfood -= hungry; peasantfood -= hungry;
hungry = 0; hungry = 0;

View file

@ -426,10 +426,13 @@ set_new_dragon_target(unit * u, region * r, int range)
free_regionlist(rlist); free_regionlist(rlist);
#else #else
int x, y; int tx, ty;
for (x = r->x - range; x < r->x + range; x++) { for (tx = r->x - range; tx < r->x + range; tx++) {
for (y = r->y - range; y < r->y + range; y++) { for (ty = r->y - range; ty < r->y + range; ty++) {
region * r2 = findregion(x, y); region * r2;
int x = tx, y = ty;
pnormalize(&x, &y, r->planep);
r2 = findregion(x, y);
if (r2!=NULL) { if (r2!=NULL) {
int affinity = dragon_affinity_value(r2, u); int affinity = dragon_affinity_value(r2, u);
if (affinity > max_affinity) { if (affinity > max_affinity) {

View file

@ -1332,7 +1332,6 @@ report_template(const char * filename, report_context * ctx, const char * charse
{ {
faction * f = ctx->f; faction * f = ctx->f;
region *r; region *r;
plane *pl;
FILE * F = fopen(filename, "wt"); FILE * F = fopen(filename, "wt");
seen_region * sr = NULL; seen_region * sr = NULL;
char buf[8192], * bufp; char buf[8192], * bufp;
@ -1384,15 +1383,16 @@ report_template(const char * filename, report_context * ctx, const char * charse
if (u->faction == f && !fval(u->race, RCF_INVISIBLE)) { if (u->faction == f && !fval(u->race, RCF_INVISIBLE)) {
order * ord; order * ord;
if (!dh) { if (!dh) {
plane * pl = getplane(r);
int nx = region_x(r, f), ny = region_y(r, f);
rps_nowrap(F, ""); rps_nowrap(F, "");
rnl(F); rnl(F);
pl = getplane(r);
if (pl && pl->id != 0) { if (pl && pl->id != 0) {
sprintf(buf, "%s %d,%d,%d ; %s", LOC(f->locale, parameters[P_REGION]), region_x(r,f), sprintf(buf, "%s %d,%d,%d ; %s", LOC(f->locale, parameters[P_REGION]),
region_y(r,f), pl->id, rname(r, f->locale)); nx, ny, pl->id, rname(r, f->locale));
} else { } else {
sprintf(buf, "%s %d,%d ; %s", LOC(f->locale, parameters[P_REGION]), region_x(r,f), sprintf(buf, "%s %d,%d ; %s", LOC(f->locale, parameters[P_REGION]),
region_y(r,f), rname(r, f->locale)); nx, ny, rname(r, f->locale));
} }
rps_nowrap(F, buf); rps_nowrap(F, buf);
rnl(F); rnl(F);

View file

@ -265,7 +265,7 @@ int
teach_cmd(unit * u, struct order * ord) teach_cmd(unit * u, struct order * ord)
{ {
static const curse_type * gbdream_ct = NULL; static const curse_type * gbdream_ct = NULL;
plane * pl;
region * r = u->region; region * r = u->region;
int teaching, i, j, count, academy=0; int teaching, i, j, count, academy=0;
unit *u2; unit *u2;
@ -285,7 +285,8 @@ teach_cmd(unit * u, struct order * ord)
return 0; return 0;
} }
if (r->planep && fval(r->planep, PFL_NOTEACH)) { pl = rplane(r);
if (pl && fval(pl, PFL_NOTEACH)) {
cmistake(u, ord, 273, MSG_EVENT); cmistake(u, ord, 273, MSG_EVENT);
return 0; return 0;
} }

View file

@ -592,15 +592,18 @@ xml_region(report_context * ctx, seen_region * sr)
unit * u; unit * u;
ship * sh = r->ships; ship * sh = r->ships;
building * b = r->buildings; building * b = r->buildings;
plane * pl = rplane(r);
int nx = region_x(r, ctx->f), ny = region_y(r, ctx->f);
pnormalize(&nx, &ny, pl);
/* TODO: entertain-quota, recruits, salary, prices, curses, borders, apparitions (Schemen), spells, travelthru, messages */ /* TODO: entertain-quota, recruits, salary, prices, curses, borders, apparitions (Schemen), spells, travelthru, messages */
xmlNewNsProp(node, xct->ns_xml, XML_XML_ID, xml_ref_region(r)); xmlNewNsProp(node, xct->ns_xml, XML_XML_ID, xml_ref_region(r));
child = xmlAddChild(node, xmlNewNode(xct->ns_atl, BAD_CAST "coordinate")); child = xmlAddChild(node, xmlNewNode(xct->ns_atl, BAD_CAST "coordinate"));
xmlNewNsProp(child, xct->ns_atl, BAD_CAST "x", xml_i(region_x(r, ctx->f))); xmlNewNsProp(child, xct->ns_atl, BAD_CAST "x", xml_i(nx));
xmlNewNsProp(child, xct->ns_atl, BAD_CAST "y", xml_i(region_y(r, ctx->f))); xmlNewNsProp(child, xct->ns_atl, BAD_CAST "y", xml_i(ny));
if (r->planep) { if (pl && pl->name) {
xmlNewNsProp(child, xct->ns_atl, BAD_CAST "plane", (xmlChar *)r->planep->name); xmlNewNsProp(child, xct->ns_atl, BAD_CAST "plane", (xmlChar *)pl->name);
} }
child = xmlAddChild(node, xmlNewNode(xct->ns_atl, BAD_CAST "terrain")); child = xmlAddChild(node, xmlNewNode(xct->ns_atl, BAD_CAST "terrain"));

View file

@ -46,6 +46,18 @@ without prior permission by the authors of Eressea.
alliance * alliances = NULL; alliance * alliances = NULL;
void
free_alliance(alliance * al)
{
free(al->name);
while (al->members) {
faction_list * m = al->members;
al->members = m->next;
free(m);
}
free(al);
}
alliance * alliance *
makealliance(int id, const char * name) makealliance(int id, const char * name)
{ {

View file

@ -48,6 +48,7 @@ extern alliance * findalliance(int id);
extern alliance * makealliance(int id, const char * name); extern alliance * makealliance(int id, const char * name);
extern const char * alliancename(const struct alliance * al); extern const char * alliancename(const struct alliance * al);
extern void setalliance(struct faction * f, alliance * al); extern void setalliance(struct faction * f, alliance * al);
void free_alliance(struct alliance * al);
extern void alliance_cmd(void); extern void alliance_cmd(void);

View file

@ -3865,10 +3865,11 @@ join_allies(battle * b)
} }
for (sa=s+1;sa!=b->sides+b->nsides;++sa) { for (sa=s+1;sa!=b->sides+b->nsides;++sa) {
plane * pl = rplane(r);
if (enemy(s, sa)) continue; if (enemy(s, sa)) continue;
if (friendly(s, sa)) continue; if (friendly(s, sa)) continue;
if (!alliedgroup(r->planep, f, sa->faction, f->allies, HELP_FIGHT)) continue; if (!alliedgroup(pl, f, sa->faction, f->allies, HELP_FIGHT)) continue;
if (!alliedgroup(r->planep, sa->faction, f, sa->faction->allies, HELP_FIGHT)) continue; if (!alliedgroup(pl, sa->faction, f, sa->faction->allies, HELP_FIGHT)) continue;
set_friendly(s, sa); set_friendly(s, sa);
} }
@ -3961,8 +3962,9 @@ init_battle(region * r, battle **bp)
unit *u2; unit *u2;
fighter *c1, *c2; fighter *c1, *c2;
ship * lsh = NULL; ship * lsh = NULL;
plane * pl = rplane(r);
if (r->planep && fval(r->planep, PFL_NOATTACK)) { if (pl && fval(pl, PFL_NOATTACK)) {
cmistake(u, ord, 271, MSG_BATTLE); cmistake(u, ord, 271, MSG_BATTLE);
continue; continue;
} }

View file

@ -91,9 +91,6 @@
#include <util/patricia.h> #include <util/patricia.h>
#endif #endif
int world_width = -1;
int world_height = -1;
/* exported variables */ /* exported variables */
region *regions; region *regions;
faction *factions; faction *factions;
@ -948,7 +945,7 @@ alliedunit(const unit * u, const faction * f2, int mode)
assert(u->region); /* the unit should be in a region, but it's possible that u->number==0 (TEMP units) */ assert(u->region); /* the unit should be in a region, but it's possible that u->number==0 (TEMP units) */
if (u->faction == f2) return mode; if (u->faction == f2) return mode;
if (u->faction != NULL && f2!=NULL) { if (u->faction != NULL && f2!=NULL) {
plane * pl = u->region->planep; plane * pl = rplane(u->region);
automode = mode & autoalliance(pl, u->faction, f2); automode = mode & autoalliance(pl, u->faction, f2);
if (pl!=NULL && (pl->flags & PFL_NOALLIANCES)) if (pl!=NULL && (pl->flags & PFL_NOALLIANCES))
@ -1163,7 +1160,10 @@ update_lighthouse(building * lh)
int y; int y;
for (y=-d;y<=d;++y) { for (y=-d;y<=d;++y) {
attrib * a; attrib * a;
region * r2 = findregion(x+r->x, y+r->y); region * r2;
int px = r->x+x, py = r->y+y;
pnormalize(&px, &py, rplane(r));
r2 = findregion(px, py);
if (r2==NULL) continue; if (r2==NULL) continue;
if (!fval(r2->terrain, SEA_REGION)) continue; if (!fval(r2->terrain, SEA_REGION)) continue;
if (distance(r, r2) > d) continue; if (distance(r, r2) > d) continue;
@ -2475,6 +2475,7 @@ int
lifestyle(const unit * u) lifestyle(const unit * u)
{ {
int need; int need;
plane * pl;
static int gamecookie = -1; static int gamecookie = -1;
if (gamecookie!=global.cookie) { if (gamecookie!=global.cookie) {
gamecookie = global.cookie; gamecookie = global.cookie;
@ -2484,7 +2485,8 @@ lifestyle(const unit * u)
need = maintenance_cost(u); need = maintenance_cost(u);
if(u->region->planep && fval(u->region->planep, PFL_NOFEED)) pl = rplane(u->region);
if (pl && fval(pl, PFL_NOFEED))
return 0; return 0;
#if KARMA_MODULE #if KARMA_MODULE
@ -2935,8 +2937,6 @@ has_limited_skills (const struct unit * u)
void void
attrib_init(void) attrib_init(void)
{ {
world_width = get_param_int(global.parameters, "world.width", 0);
world_height = get_param_int(global.parameters, "world.height", 0);
/* Alle speicherbaren Attribute müssen hier registriert werden */ /* Alle speicherbaren Attribute müssen hier registriert werden */
at_register(&at_shiptrail); at_register(&at_shiptrail);
at_register(&at_familiar); at_register(&at_familiar);
@ -3064,6 +3064,11 @@ free_gamedata(void)
free_regions(); free_regions();
free_borders(); free_borders();
while (alliances) {
alliance * al = alliances;
alliances = al->next;
free_alliance(al);
}
while (factions) { while (factions) {
faction * f = factions; faction * f = factions;
factions = f->next; factions = f->next;

View file

@ -115,9 +115,6 @@ extern const char *parameters[MAXPARAMS];
#define want(option) (1<<option) #define want(option) (1<<option)
extern const char *options[MAXOPTIONS]; extern const char *options[MAXOPTIONS];
extern int world_width;
extern int world_height;
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
extern int shipspeed(const struct ship * sh, const struct unit * u); extern int shipspeed(const struct ship * sh, const struct unit * u);

View file

@ -1915,7 +1915,10 @@ addparam_region(const char * const param[], spllprm ** spobjp, const unit * u, o
int tx = atoi((const char*)param[0]), ty = atoi((const char*)param[1]); int tx = atoi((const char*)param[0]), ty = atoi((const char*)param[1]);
int x = rel_to_abs(0, u->faction, tx, 0); int x = rel_to_abs(0, u->faction, tx, 0);
int y = rel_to_abs(0, u->faction, ty, 1); int y = rel_to_abs(0, u->faction, ty, 1);
region *rt = findregion(x,y); region *rt;
pnormalize(&x, &y, rplane(u->region));
rt = findregion(x,y);
if (rt!=NULL) { if (rt!=NULL) {
spllprm * spobj = *spobjp = malloc(sizeof(spllprm)); spllprm * spobj = *spobjp = malloc(sizeof(spllprm));
@ -2528,13 +2531,15 @@ cast_cmd(unit * u, order * ord)
unit *familiar = NULL, *mage = u; unit *familiar = NULL, *mage = u;
const char * s; const char * s;
spell * sp; spell * sp;
plane * pl;
spellparameter *args = NULL; spellparameter *args = NULL;
if (LongHunger(u)) { if (LongHunger(u)) {
cmistake(u, ord, 224, MSG_MAGIC); cmistake(u, ord, 224, MSG_MAGIC);
return 0; return 0;
} }
if (r->planep && fval(r->planep, PFL_NOMAGIC)) { pl = rplane(r);
if (pl && fval(pl, PFL_NOMAGIC)) {
cmistake(u, ord, 269, MSG_MAGIC); cmistake(u, ord, 269, MSG_MAGIC);
return 0; return 0;
} }
@ -2555,10 +2560,12 @@ cast_cmd(unit * u, order * ord)
s = getstrtoken(); s = getstrtoken();
} }
if (findparam(s, u->faction->locale) == P_REGION) { if (findparam(s, u->faction->locale) == P_REGION) {
short t_x = (short)getint(); int t_x = getint();
short t_y = (short)getint(); int t_y = getint();
t_x = rel_to_abs(getplane(u->region),u->faction,t_x,0); plane * pl = getplane(u->region);
t_y = rel_to_abs(getplane(u->region),u->faction,t_y,1); t_x = rel_to_abs(pl, u->faction, t_x,0);
t_y = rel_to_abs(pl, u->faction, t_y,1);
pnormalize(&t_x, &t_y, pl);
target_r = findregion(t_x, t_y); target_r = findregion(t_x, t_y);
if (!target_r) { if (!target_r) {
/* Fehler "Die Region konnte nicht verzaubert werden" */ /* Fehler "Die Region konnte nicht verzaubert werden" */

View file

@ -200,7 +200,7 @@ entrance_allowed(const struct unit * u, const struct region * r)
#ifdef REGIONOWNERS #ifdef REGIONOWNERS
faction * owner = region_get_owner(r); faction * owner = region_get_owner(r);
if (owner == NULL || u->faction == owner) return true; if (owner == NULL || u->faction == owner) return true;
if (alliedfaction(r->planep, owner, u->faction, HELP_TRAVEL)) return true; if (alliedfaction(rplane(r), owner, u->faction, HELP_TRAVEL)) return true;
return false; return false;
#else #else
return true; return true;

View file

@ -1,7 +1,7 @@
/* vi: set ts=2: /* vi: set ts=2:
* *
* *
* Eressea PB(E)M host Copyright (C) 1998-2003 * Eressea PB(E)M host Copyright (C) 1998-2003
* Christian Schlittchen (corwin@amber.kn-bremen.de) * Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de)
* Henning Peters (faroul@beyond.kn-bremen.de) * Henning Peters (faroul@beyond.kn-bremen.de)
@ -40,195 +40,239 @@
struct plane *planes; struct plane *planes;
int plane_width(const plane * pl)
{
if (pl) {
return pl->maxx-pl->minx+1;
}
return 0;
}
int plane_height(const plane * pl)
{
if (pl) {
return pl->maxy-pl->miny+1;
}
return 0;
}
static plane * home_plane = NULL;
plane *
get_homeplane(void)
{
return home_plane;
}
plane * plane *
getplane(const region *r) getplane(const region *r)
{ {
if(r) if (r) {
return r->planep; return r->_plane;
}
return NULL; return get_homeplane();
} }
plane * plane *
getplanebyid(int id) getplanebyid(int id)
{ {
plane *p; plane *p;
for (p=planes; p; p=p->next) for (p=planes; p; p=p->next) {
if (p->id == id) if (p->id == id) {
return p; return p;
return NULL; }
}
return NULL;
} }
plane * plane *
getplanebyname(const char * name) getplanebyname(const char * name)
{ {
plane *p; plane *p;
for (p=planes; p; p=p->next) for (p=planes; p; p=p->next)
if (!strcmp(p->name, name)) if (!strcmp(p->name, name))
return p; return p;
return NULL; return NULL;
} }
plane * plane *
findplane(int x, int y) findplane(int x, int y)
{ {
plane *pl; plane *pl;
for(pl=planes;pl;pl=pl->next) { for(pl=planes;pl;pl=pl->next) {
if(x >= pl->minx && x <= pl->maxx if(x >= pl->minx && x <= pl->maxx
&& y >= pl->miny && y <= pl->maxy) { && y >= pl->miny && y <= pl->maxy) {
return pl; return pl;
} }
} }
return NULL; return NULL;
} }
int int
getplaneid(const region *r) getplaneid(const region *r)
{ {
if(r) { if(r) {
plane * pl = getplane(r); plane * pl = getplane(r);
if (pl) return pl->id; if (pl) return pl->id;
for(pl=planes;pl;pl=pl->next) { for(pl=planes;pl;pl=pl->next) {
if(r->x >= pl->minx && r->x <= pl->maxx if(r->x >= pl->minx && r->x <= pl->maxx
&& r->y >= pl->miny && r->y <= pl->maxy) { && r->y >= pl->miny && r->y <= pl->maxy) {
return pl->id; return pl->id;
} }
} }
} }
return 0; return 0;
} }
static int static int
ursprung_x(const faction *f, const plane *pl, const region * rdefault) ursprung_x(const faction *f, const plane *pl, const region * rdefault)
{ {
ursprung *ur; ursprung *ur;
int id = 0; int id = 0;
if(!f) if(!f)
return 0; return 0;
if(pl) if(pl)
id = pl->id; id = pl->id;
for(ur = f->ursprung; ur; ur = ur->next) { for(ur = f->ursprung; ur; ur = ur->next) {
if(ur->id == id) if(ur->id == id)
return ur->x; return ur->x;
} }
if (!rdefault) return 0; if (!rdefault) return 0;
set_ursprung((faction*)f, id, rdefault->x - plane_center_x(pl), rdefault->y - plane_center_y(pl)); set_ursprung((faction*)f, id, rdefault->x - plane_center_x(pl), rdefault->y - plane_center_y(pl));
return rdefault->x - plane_center_x(pl); return rdefault->x - plane_center_x(pl);
} }
static int static int
ursprung_y(const faction *f, const plane *pl, const region * rdefault) ursprung_y(const faction *f, const plane *pl, const region * rdefault)
{ {
ursprung *ur; ursprung *ur;
int id = 0; int id = 0;
if(!f) if(!f)
return 0; return 0;
if(pl) if(pl)
id = pl->id; id = pl->id;
for(ur = f->ursprung; ur; ur = ur->next) { for(ur = f->ursprung; ur; ur = ur->next) {
if(ur->id == id) if(ur->id == id)
return ur->y; return ur->y;
} }
if (!rdefault) return 0; if (!rdefault) return 0;
set_ursprung((faction*)f, id, rdefault->x - plane_center_x(pl), rdefault->y - plane_center_y(pl)); set_ursprung((faction*)f, id, rdefault->x - plane_center_x(pl), rdefault->y - plane_center_y(pl));
return rdefault->y - plane_center_y(pl); return rdefault->y - plane_center_y(pl);
} }
int int
plane_center_x(const plane *pl) plane_center_x(const plane *pl)
{ {
if(pl == NULL) if(pl == NULL)
return 0; return 0;
return(pl->minx + pl->maxx)/2; return(pl->minx + pl->maxx)/2;
} }
int int
plane_center_y(const plane *pl) plane_center_y(const plane *pl)
{ {
if(pl == NULL) if(pl == NULL)
return 0; return 0;
return(pl->miny + pl->maxy)/2; return(pl->miny + pl->maxy)/2;
} }
int int
region_x(const region *r, const faction *f) region_x(const region *r, const faction *f)
{ {
plane *pl = r->planep; plane *pl = rplane(r);
return r->x - ursprung_x(f, pl, r) - plane_center_x(pl); int x = r->x - plane_center_x(pl);
if (f) {
int width = plane_width(pl);
int width_2 = width/2;
x -= ursprung_x(f, pl, r);
if (x>width_2) x -= width;
}
return x;
} }
int int
region_y(const region *r, const faction *f) region_y(const region *r, const faction *f)
{ {
plane *pl = r->planep; plane *pl = rplane(r);
return r->y - plane_center_y(pl) - ursprung_y(f, pl, r); int y = r->y - plane_center_y(pl);
if (f) {
int height = plane_height(pl);
int height_2 = height/2;
y -= ursprung_y(f, pl, r);
if (y>height_2) y -= height;
}
return y;
} }
void void
set_ursprung(faction *f, int id, int x, int y) set_ursprung(faction *f, int id, int x, int y)
{ {
ursprung *ur; ursprung *ur;
assert(f!=NULL); assert(f!=NULL);
for(ur=f->ursprung;ur;ur=ur->next) { for(ur=f->ursprung;ur;ur=ur->next) {
if (ur->id == id) { if (ur->id == id) {
ur->x = ur->x + x; ur->x = ur->x + x;
ur->y = ur->y + y; ur->y = ur->y + y;
return; return;
} }
} }
ur = calloc(1, sizeof(ursprung)); ur = calloc(1, sizeof(ursprung));
ur->id = id; ur->id = id;
ur->x = x; ur->x = x;
ur->y = y; ur->y = y;
addlist(&f->ursprung, ur); addlist(&f->ursprung, ur);
} }
plane * plane *
create_new_plane(int id, const char *name, int minx, int maxx, int miny, int maxy, int flags) create_new_plane(int id, const char *name, int minx, int maxx, int miny, int maxy, int flags)
{ {
plane *pl = getplanebyid(id); plane *pl = getplanebyid(id);
if (pl) return pl; if (pl) return pl;
pl = calloc(1, sizeof(plane)); pl = calloc(1, sizeof(plane));
pl->next = NULL; pl->next = NULL;
pl->id = id; pl->id = id;
pl->name = strdup(name); if (name) pl->name = strdup(name);
pl->minx = minx; pl->minx = minx;
pl->maxx = maxx; pl->maxx = maxx;
pl->miny = miny; pl->miny = miny;
pl->maxy = maxy; pl->maxy = maxy;
pl->flags = flags; pl->flags = flags;
addlist(&planes, pl); addlist(&planes, pl);
return pl; if (id==0) {
home_plane = pl;
}
return pl;
} }
/* Umrechnung Relative-Absolute-Koordinaten */ /* Umrechnung Relative-Absolute-Koordinaten */
int int
rel_to_abs(const struct plane *pl, const struct faction * f, int rel, unsigned char index) rel_to_abs(const struct plane *pl, const struct faction * f, int rel, unsigned char index)
{ {
assert(index == 0 || index == 1); assert(index == 0 || index == 1);
if(index == 0) if(index == 0)
return (rel + ursprung_x(f, pl, NULL) + plane_center_x(pl)); return (rel + ursprung_x(f, pl, NULL) + plane_center_x(pl));
return (rel + ursprung_y(f, pl, NULL) + plane_center_y(pl)); return (rel + ursprung_y(f, pl, NULL) + plane_center_y(pl));
} }
@ -269,9 +313,9 @@ read_plane_reference(plane ** pp, struct storage * store)
boolean boolean
is_watcher(const struct plane * p, const struct faction * f) is_watcher(const struct plane * p, const struct faction * f)
{ {
struct watcher * w; struct watcher * w;
if (!p) return false; if (!p) return false;
w = p->watchers; w = p->watchers;
while (w && w->faction!=f) w=w->next; while (w && w->faction!=f) w=w->next;
return (w!=NULL); return (w!=NULL);
} }

View file

@ -1,6 +1,6 @@
/* vi: set ts=2: /* vi: set ts=2:
* *
* Eressea PB(E)M host Copyright (C) 1998-2003 * Eressea PB(E)M host Copyright (C) 1998-2003
* Christian Schlittchen (corwin@amber.kn-bremen.de) * Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de)
* Henning Peters (faroul@beyond.kn-bremen.de) * Henning Peters (faroul@beyond.kn-bremen.de)
@ -42,21 +42,23 @@ extern "C" {
#define PFL_SEESPECIAL 32768 /* far seeing */ #define PFL_SEESPECIAL 32768 /* far seeing */
typedef struct watcher { typedef struct watcher {
struct watcher * next; struct watcher * next;
struct faction * faction; struct faction * faction;
unsigned char mode; unsigned char mode;
} watcher; } watcher;
typedef struct plane { typedef struct plane {
struct plane *next; struct plane *next;
struct watcher * watchers; struct watcher * watchers;
int id; int id;
char *name; char *name;
int minx, maxx, miny, maxy; int minx, maxx, miny, maxy;
unsigned int flags; unsigned int flags;
struct attrib *attribs; struct attrib *attribs;
} plane; } plane;
#define plane_id(pl) ( (pl) ? (pl)->id : 0 )
extern struct plane *planes; extern struct plane *planes;
struct plane *getplane(const struct region *r); struct plane *getplane(const struct region *r);
@ -69,14 +71,16 @@ int region_y(const struct region *r, const struct faction *f);
int plane_center_x(const struct plane *pl); int plane_center_x(const struct plane *pl);
int plane_center_y(const struct plane *pl); int plane_center_y(const struct plane *pl);
void set_ursprung(struct faction *f, int id, int x, int y); void set_ursprung(struct faction *f, int id, int x, int y);
plane * create_new_plane(int id, const char *name, int minx, int maxx, int miny, int maxy, int flags); struct plane * create_new_plane(int id, const char *name, int minx, int maxx, int miny, int maxy, int flags);
plane * getplanebyname(const char *); struct plane * getplanebyname(const char *);
struct plane * get_homeplane(void);
extern int rel_to_abs(const struct plane *pl, const struct faction * f, int rel, unsigned char index); extern int rel_to_abs(const struct plane *pl, const struct faction * f, int rel, unsigned char index);
extern boolean is_watcher(const struct plane * p, const struct faction * f); extern boolean is_watcher(const struct plane * p, const struct faction * f);
extern int resolve_plane(variant data, void * addr); extern int resolve_plane(variant data, void * addr);
extern void write_plane_reference(const plane * p, struct storage * store); extern void write_plane_reference(const plane * p, struct storage * store);
extern int read_plane_reference(plane ** pp, struct storage * store); extern int read_plane_reference(plane ** pp, struct storage * store);
extern int plane_width(const plane * pl);
extern int plane_height(const plane * pl);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -116,8 +116,9 @@ write_regionname(const region * r, const faction * f, char * buffer, size_t size
if (r==NULL) { if (r==NULL) {
strcpy(buf, "(null)"); strcpy(buf, "(null)");
} else { } else {
snprintf(buf, size, "%s (%d,%d)", rname(r, lang), plane * pl = rplane(r);
region_x(r, f), region_y(r, f)); int nx = region_x(r, f), ny = region_y(r, f);
snprintf(buf, size, "%s (%d,%d)", rname(r, lang), nx, ny);
} }
buf[size-1] = 0; buf[size-1] = 0;
return buffer; return buffer;
@ -357,7 +358,7 @@ int
a_readmoveblock(attrib *a, storage * store) a_readmoveblock(attrib *a, storage * store)
{ {
moveblock *m = (moveblock *)(a->data.v); moveblock *m = (moveblock *)(a->data.v);
int i; int i;
i = store->r_int(store); i = store->r_int(store);
m->dir = (direction_t)i; m->dir = (direction_t)i;
@ -375,7 +376,6 @@ attrib_type at_moveblock = {
"moveblock", a_initmoveblock, NULL, NULL, a_writemoveblock, a_readmoveblock "moveblock", a_initmoveblock, NULL, NULL, a_writemoveblock, a_readmoveblock
}; };
#define coor_hashkey(x, y) (unsigned int)((x<<16) + y) #define coor_hashkey(x, y) (unsigned int)((x<<16) + y)
#define RMAXHASH MAXREGIONS #define RMAXHASH MAXREGIONS
static region * regionhash[RMAXHASH]; static region * regionhash[RMAXHASH];
@ -433,26 +433,31 @@ static int hash_requests;
static int hash_misses; static int hash_misses;
#endif #endif
void cnormalize(int * x, int * y) boolean pnormalize(int * x, int * y, const plane * pl)
{ {
if (world_width && x) { if (pl) {
if (*x<0) { if (x) {
*x = world_width - abs(*x) % world_width; int width = pl->maxx - pl->minx + 1;
int nx = *x - pl->minx;
nx = (nx>0)?nx:(width-(-nx)%width);
*x = nx % width+ pl->minx;
} }
*x = *x % world_width; if (y) {
} int height = pl->maxy - pl->miny + 1;
if (world_height && y) { int ny = *y - pl->miny;
if (*y<0) { ny = (ny>0)?ny:(height-(-ny)%height);
*y = world_height - abs(*y) % world_height; *y = ny % height + pl->miny;
} }
*y = *y % world_height;
} }
return false; /* TBD */
} }
static region * static region *
rfindhash(int x, int y) rfindhash(int x, int y)
{ {
unsigned int rid = coor_hashkey(x, y); unsigned int rid;
rid = coor_hashkey(x, y);
#if HASH_STATISTICS #if HASH_STATISTICS
++hash_requests; ++hash_requests;
#endif #endif
@ -509,13 +514,17 @@ region *
r_connect(const region * r, direction_t dir) r_connect(const region * r, direction_t dir)
{ {
region * result; region * result;
int x, y;
#ifdef FAST_CONNECT #ifdef FAST_CONNECT
region * rmodify = (region*)r; region * rmodify = (region*)r;
assert (dir>=0 && dir<MAXDIRECTIONS); assert (dir>=0 && dir<MAXDIRECTIONS);
if (r->connect[dir]) return r->connect[dir]; if (r->connect[dir]) return r->connect[dir];
#endif #endif
assert(dir<MAXDIRECTIONS); assert(dir<MAXDIRECTIONS);
result = rfindhash(r->x + delta_x[dir], r->y + delta_y[dir]); x = r->x + delta_x[dir];
y = r->y + delta_y[dir];
pnormalize(&x, &y, rplane(r));
result = rfindhash(x, y);
#ifdef FAST_CONNECT #ifdef FAST_CONNECT
if (result) { if (result) {
rmodify->connect[dir] = result; rmodify->connect[dir] = result;
@ -531,20 +540,19 @@ findregion(int x, int y)
return rfindhash(x, y); return rfindhash(x, y);
} }
int /* Contributed by Hubert Mackenberg. Thanks.
koor_distance(int x1, int y1, int x2, int y2) * x und y Abstand zwischen x1 und x2 berechnen
*/
static int
koor_distance_orig(int x1, int y1, int x2, int y2)
{ {
/* Contributed by Hubert Mackenberg. Thanks.
* x und y Abstand zwischen x1 und x2 berechnen
*/
int dx = x1 - x2; int dx = x1 - x2;
int dy = y1 - y2; int dy = y1 - y2;
/* Bei negativem dy am Ursprung spiegeln, das veraendert /* Bei negativem dy am Ursprung spiegeln, das veraendert
* den Abstand nicht * den Abstand nicht
*/ */
if ( dy < 0 ) if ( dy < 0 ) {
{
dy = -dy; dy = -dy;
dx = -dx; dx = -dx;
} }
@ -552,9 +560,71 @@ koor_distance(int x1, int y1, int x2, int y2)
/* /*
* dy ist jetzt >=0, fuer dx sind 3 Faelle zu untescheiden * dy ist jetzt >=0, fuer dx sind 3 Faelle zu untescheiden
*/ */
if ( dx >= 0 ) return dx + dy; if ( dx >= 0 ) {
else if (-dx >= dy) return -dx; int result = dx + dy;
else return dy; return result;
}
else if (-dx >= dy) {
int result = -dx;
return result;
}
else {
return dy;
}
}
static int
koor_distance_wrap_xy(int x1, int y1, int x2, int y2, int width, int height)
{
int dx = x1 - x2;
int dy = y1 - y2;
int result, dist;
int mindist = MIN(width, height) >> 1;
/* Bei negativem dy am Ursprung spiegeln, das veraendert
* den Abstand nicht
*/
if ( dy < 0 ) {
dy = -dy;
dx = -dx;
}
if (dx<0) {
dx = width + dx;
}
/* dx,dy is now pointing northeast */
result = dx + dy;
if (result<=mindist) return result;
dist = (width-dx) + (height-dy); /* southwest */
if (dist>=0 && dist<result) {
result = dist;
if (result<=mindist) return result;
}
dist = MAX(dx, height-dy);
if (dist>=0 && dist<result) {
result = dist;
if (result<=mindist) return result;
}
dist = MAX(width-dx, dy);
if (dist>=0 && dist<result) result = dist;
return result;
}
int
koor_distance(int x1, int y1, int x2, int y2)
{
const plane * p1 = findplane(x1, y1);
const plane * p2 = findplane(x2, y2);
if (p1!=p2) return INT_MAX;
else {
int width = plane_width(p1);
int height = plane_height(p1);
if (width && height) {
return koor_distance_wrap_xy(x1, y1, x2, y2, width, height);
} else {
return koor_distance_orig(x1, y1, x2, y2);
}
}
} }
int int
@ -564,11 +634,14 @@ distance(const region * r1, const region * r2)
} }
static direction_t static direction_t
koor_reldirection(int ax, int ay, int bx, int by) koor_reldirection(int ax, int ay, int bx, int by, const struct plane * pl)
{ {
direction_t dir; direction_t dir;
for (dir=0;dir!=MAXDIRECTIONS;++dir) { for (dir=0;dir!=MAXDIRECTIONS;++dir) {
if (bx-ax == delta_x[dir] && by-ay == delta_y[dir]) return dir; int x = ax + delta_x[dir];
int y = ay + delta_y[dir];
pnormalize(&x, &y, pl);
if (bx == x && by == y) return dir;
} }
return NODIRECTION; return NODIRECTION;
} }
@ -589,13 +662,17 @@ special_direction(const region * from, const region * to)
direction_t direction_t
reldirection(const region * from, const region * to) reldirection(const region * from, const region * to)
{ {
direction_t dir = koor_reldirection(from->x, from->y, to->x, to->y); plane * pl = rplane(from);
if (pl == rplane(to)) {
direction_t dir = koor_reldirection(from->x, from->y, to->x, to->y, pl);
if (dir==NODIRECTION) { if (dir==NODIRECTION) {
spec_direction *sd = special_direction(from, to); spec_direction *sd = special_direction(from, to);
if (sd!=NULL && sd->active) return D_SPECIAL; if (sd!=NULL && sd->active) return D_SPECIAL;
}
return dir;
} }
return dir; return NODIRECTION;
} }
void void
@ -856,9 +933,12 @@ static region *last;
static unsigned int max_index = 0; static unsigned int max_index = 0;
region * region *
new_region(int x, int y, unsigned int uid) new_region(int x, int y, struct plane * pl, unsigned int uid)
{ {
region *r = rfindhash(x, y); region *r;
pnormalize(&x, &y, pl);
r = rfindhash(x, y);
if (r) { if (r) {
log_error(("duplicate region discovered: %s(%d,%d)\n", regionname(r, NULL), x, y)); log_error(("duplicate region discovered: %s(%d,%d)\n", regionname(r, NULL), x, y));
@ -871,7 +951,7 @@ new_region(int x, int y, unsigned int uid)
r->y = y; r->y = y;
r->uid = uid; r->uid = uid;
r->age = 1; r->age = 1;
r->planep = findplane(x, y); r->_plane = pl;
rhash(r); rhash(r);
hash_uid(r); hash_uid(r);
if (last) if (last)

View file

@ -113,7 +113,7 @@ typedef struct region {
and lastregion */ and lastregion */
unsigned int uid; /* a unique id */ unsigned int uid; /* a unique id */
int x, y; int x, y;
struct plane *planep; struct plane * _plane; /* to access, use rplane(r) */
char *display; char *display;
unsigned int flags; unsigned int flags;
unsigned short age; unsigned short age;
@ -229,9 +229,10 @@ int r_demand(const struct region * r, const struct luxury_type * ltype);
const char * write_regionname(const struct region * r, const struct faction * f, char * buffer, size_t size); const char * write_regionname(const struct region * r, const struct faction * f, char * buffer, size_t size);
struct region * new_region(int x, int y, unsigned int uid); struct region * new_region(int x, int y, struct plane * pl, unsigned int uid);
void remove_region(region ** rlist, region * r); void remove_region(region ** rlist, region * r);
void terraform_region(struct region * r, const struct terrain_type * terrain); void terraform_region(struct region * r, const struct terrain_type * terrain);
boolean pnormalize(int * x, int * y, const struct plane * pl);
extern const int delta_x[MAXDIRECTIONS]; extern const int delta_x[MAXDIRECTIONS];
extern const int delta_y[MAXDIRECTIONS]; extern const int delta_y[MAXDIRECTIONS];

View file

@ -747,7 +747,7 @@ bufunit(const faction * f, const unit * u, int indent, int mode, char * buf, siz
dh=0; dh=0;
if (!getarnt && f) { if (!getarnt && f) {
if (alliedfaction(u->region->planep, f, fv, HELP_ALL)) { if (alliedfaction(rplane(u->region), f, fv, HELP_ALL)) {
dh = 1; dh = 1;
} }
} }
@ -1275,7 +1275,7 @@ prepare_reports(void)
for (r = regions; r ; r = r->next) { for (r = regions; r ; r = r->next) {
attrib *ru; attrib *ru;
unit * u; unit * u;
plane * p = r->planep; plane * p = rplane(r);
reorder_units(r); reorder_units(r);
@ -1351,7 +1351,7 @@ prepare_report(faction * f)
for (;sr!=NULL;sr=sr->next) { for (;sr!=NULL;sr=sr->next) {
if (sr->mode>see_neighbour) { if (sr->mode>see_neighbour) {
region * r = sr->r; region * r = sr->r;
plane * p = r->planep; plane * p = rplane(r);
void (*view)(struct seen_region **, region *, faction *) = view_default; void (*view)(struct seen_region **, region *, faction *) = view_default;
if (p && fval(p, PFL_SEESPECIAL)) { if (p && fval(p, PFL_SEESPECIAL)) {
@ -1624,14 +1624,15 @@ trailinto(const region * r, const struct locale * lang)
size_t size_t
f_regionid(const region * r, const faction * f, char * buffer, size_t size) f_regionid(const region * r, const faction * f, char * buffer, size_t size)
{ {
if (!r) { if (!r) {
strncpy(buffer, "(Chaos)", size); strncpy(buffer, "(Chaos)", size);
} else { } else {
plane * pl = r->planep; plane * pl = rplane(r);
const char * name = pl?pl->name:0;
int nx = region_x(r, f), ny = region_y(r, f);
strncpy(buffer, rname(r, f->locale), size); strncpy(buffer, rname(r, f->locale), size);
buffer[size-1]=0; buffer[size-1]=0;
sprintf(buffer+strlen(buffer), " (%d,%d%s%s)", region_x(r,f), region_y(r,f), pl?",":"", pl?pl->name:""); sprintf(buffer+strlen(buffer), " (%d,%d%s%s)", nx, ny, name?",":"", (name)?name:"");
} }
return strlen(buffer); return strlen(buffer);
} }

View file

@ -895,7 +895,8 @@ readregion(struct storage * store, int x, int y)
} }
if (r==NULL) { if (r==NULL) {
r = new_region(x, y, uid); plane * pl = findplane(x, y);
r = new_region(x, y, pl, uid);
} else { } else {
assert(uid==0 || r->uid==uid); assert(uid==0 || r->uid==uid);
current_region = r; current_region = r;

View file

@ -80,9 +80,11 @@ astralregions(const region * r, boolean (*valid)(const region *))
for (y=-TP_RADIUS;y<=+TP_RADIUS;++y) { for (y=-TP_RADIUS;y<=+TP_RADIUS;++y) {
region * rn; region * rn;
int dist = koor_distance(0, 0, x, y); int dist = koor_distance(0, 0, x, y);
int nx = r->x+x, ny = r->y+y;
if (dist > TP_RADIUS) continue; if (dist > TP_RADIUS) continue;
rn = findregion(r->x+x, r->y+y); pnormalize(&nx, &ny, rplane(r));
rn = findregion(nx, ny);
if (rn!=NULL && (valid==NULL || valid(rn))) add_regionlist(&rlist, rn); if (rn!=NULL && (valid==NULL || valid(rn))) add_regionlist(&rlist, rn);
} }
} }
@ -105,8 +107,8 @@ r_astral_to_standard(const region *r)
assert(is_astral(r)); assert(is_astral(r));
x = (r->x-TE_CENTER_X)*TP_DISTANCE; x = (r->x-TE_CENTER_X)*TP_DISTANCE;
y = (r->y-TE_CENTER_Y)*TP_DISTANCE; y = (r->y-TE_CENTER_Y)*TP_DISTANCE;
pnormalize(&x, &y, rplane(r));
r2 = findregion(x,y); r2 = findregion(x, y);
if (r2==NULL || rplane(r2)!=get_normalplane()) return NULL; if (r2==NULL || rplane(r2)!=get_normalplane()) return NULL;
return r2; return r2;
@ -117,13 +119,17 @@ all_in_range(const region *r, int n, boolean (*valid)(const region *))
{ {
int x, y; int x, y;
region_list *rlist = NULL; region_list *rlist = NULL;
plane * pl = rplane(r);
if (r == NULL) return NULL; if (r == NULL) return NULL;
for (x = r->x-n; x <= r->x+n; x++) { for (x = r->x-n; x <= r->x+n; x++) {
for (y = r->y-n; y <= r->y+n; y++) { for (y = r->y-n; y <= r->y+n; y++) {
if (koor_distance(r->x, r->y, x, y) <= n) { if (koor_distance(r->x, r->y, x, y) <= n) {
region * r2 = findregion(x, y); region * r2;
int nx = x, ny = y;
pnormalize(&nx, &ny, pl);
r2 = findregion(nx, ny);
if (r2!=NULL && (valid==NULL || valid(r2))) add_regionlist(&rlist, r2); if (r2!=NULL && (valid==NULL || valid(r2))) add_regionlist(&rlist, r2);
} }
} }
@ -196,24 +202,23 @@ void
create_teleport_plane(void) create_teleport_plane(void)
{ {
region *r; region *r;
plane * hplane = get_homeplane();
plane * aplane = get_astralplane(); plane * aplane = get_astralplane();
const terrain_type * fog = get_terrain("fog"); const terrain_type * fog = get_terrain("fog");
for (r=regions;r;r=r->next) { for (r=regions;r;r=r->next) {
if (r->planep == NULL) { plane * pl = rplane(r);
if (pl == hplane) {
region *ra = tpregion(r); region *ra = tpregion(r);
if (ra==NULL) { if (ra==NULL) {
int x = TE_CENTER_X+real2tp(r->x); int x = TE_CENTER_X+real2tp(r->x);
int y = TE_CENTER_Y+real2tp(r->y); int y = TE_CENTER_Y+real2tp(r->y);
plane * pl = findplane(x, y); pnormalize(&x, &y, aplane);
if (aplane && pl==aplane) { ra = new_region(x, y, aplane, 0);
ra = new_region(x, y, 0); terraform_region(ra, fog);
terraform_region(ra, fog);
ra->planep = aplane;
}
} }
} }
} }

View file

@ -1243,9 +1243,12 @@ get_modifier(const unit *u, skill_t sk, int level, const region *r, boolean noit
int bskill = level; int bskill = level;
int skill = bskill; int skill = bskill;
if (r->planep && sk == SK_STEALTH && fval(r->planep, PFL_NOSTEALTH)) return 0;
assert(r); assert(r);
if (sk == SK_STEALTH) {
plane * pl = rplane(r);
if (pl &&fval(pl, PFL_NOSTEALTH)) return 0;
}
skill += rc_skillmod(u->race, r, sk); skill += rc_skillmod(u->race, r, sk);
skill += att_modification(u, sk); skill += att_modification(u, sk);

View file

@ -423,17 +423,22 @@ free_newfaction(newfaction * nf)
static void static void
frame_regions(int age, const terrain_type * terrain) frame_regions(int age, const terrain_type * terrain)
{ {
plane * hplane = get_homeplane();
region * r = regions; region * r = regions;
for (r=regions;r;r=r->next) { for (r=regions;r;r=r->next) {
plane * pl = rplane(r);
direction_t d; direction_t d;
if (r->age<age) continue; if (r->age<age) continue;
if (r->planep) continue; if (pl!=hplane) continue; /* only do this on the main world */
if (r->terrain == terrain) continue; if (r->terrain == terrain) continue;
for (d=0;d!=MAXDIRECTIONS;++d) { for (d=0;d!=MAXDIRECTIONS;++d) {
region * rn = rconnect(r, d); region * rn = rconnect(r, d);
if (rn==NULL) { if (rn==NULL) {
rn = new_region(r->x+delta_x[d], r->y+delta_y[d], 0); int x = r->x + delta_x[d];
int y = r->y + delta_y[d];
pnormalize(&x, &y, pl);
rn = new_region(x, y, pl, 0);
terraform_region(rn, terrain); terraform_region(rn, terrain);
rn->age=r->age; rn->age=r->age;
} }
@ -513,12 +518,13 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
if (max_agediff>0) { if (max_agediff>0) {
region * rmin = NULL; region * rmin = NULL;
plane * hplane = get_homeplane();
/* find a spot that's adjacent to the previous island, but virgin. /* find a spot that's adjacent to the previous island, but virgin.
* like the last land virgin ocean region adjacent to land. * like the last land virgin ocean region adjacent to land.
*/ */
for (r=regions;r;r=r->next) { for (r=regions;r;r=r->next) {
struct plane * p = r->planep; struct plane * pl = rplane(r);
if (r->age<=max_agediff && r->terrain == newterrain(T_OCEAN) && p==NULL && virgin_region(r)) { if (r->age<=max_agediff && r->terrain == newterrain(T_OCEAN) && pl==hplane && virgin_region(r)) {
direction_t d; direction_t d;
for (d=0;d!=MAXDIRECTIONS;++d) { for (d=0;d!=MAXDIRECTIONS;++d) {
region * rn = rconnect(r, d); region * rn = rconnect(r, d);
@ -559,13 +565,14 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
if (r==NULL) { if (r==NULL) {
region * rmin = NULL; region * rmin = NULL;
direction_t dmin = MAXDIRECTIONS; direction_t dmin = MAXDIRECTIONS;
plane * hplane = get_homeplane();
/* find an empty spot. /* find an empty spot.
* rmin = the youngest ocean region that has a missing neighbour * rmin = the youngest ocean region that has a missing neighbour
* dmin = direction in which it's empty * dmin = direction in which it's empty
*/ */
for (r=regions;r;r=r->next) { for (r=regions;r;r=r->next) {
struct plane * p = r->planep; struct plane * pl = rplane(r);
if (r->terrain == newterrain(T_OCEAN) && p==0 && (rmin==NULL || r->age<=max_agediff)) { if (r->terrain == newterrain(T_OCEAN) && pl==hplane && (rmin==NULL || r->age<=max_agediff)) {
direction_t d; direction_t d;
for (d=0;d!=MAXDIRECTIONS;++d) { for (d=0;d!=MAXDIRECTIONS;++d) {
region * rn = rconnect(r, d); region * rn = rconnect(r, d);
@ -582,10 +589,12 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
* in our island. island regions are kept in rlist, so only new regions can * in our island. island regions are kept in rlist, so only new regions can
* get populated, and old regions are not overwritten */ * get populated, and old regions are not overwritten */
if (rmin!=NULL) { if (rmin!=NULL) {
plane * pl = rplane(rmin);
int x = rmin->x + delta_x[dmin];
int y = rmin->y + delta_y[dmin];
pnormalize(&x, &y, pl);
assert(virgin_region(rconnect(rmin, dmin))); assert(virgin_region(rconnect(rmin, dmin)));
x = rmin->x + delta_x[dmin]; r = new_region(x, y, pl, 0);
y = rmin->y + delta_y[dmin];
r = new_region(x, y, 0);
terraform_region(r, newterrain(T_OCEAN)); terraform_region(r, newterrain(T_OCEAN));
} }
} }
@ -611,7 +620,11 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
region * rn = rconnect(r, d); region * rn = rconnect(r, d);
if (rn && fval(rn, RF_MARK)) continue; if (rn && fval(rn, RF_MARK)) continue;
if (rn==NULL) { if (rn==NULL) {
rn = new_region(r->x + delta_x[d], r->y + delta_y[d], 0); plane * pl = rplane(r);
int x = r->x + delta_x[d];
int y = r->y + delta_y[d];
pnormalize(&x, &y, pl);
rn = new_region(x, y, pl, 0);
terraform_region(rn, newterrain(T_OCEAN)); terraform_region(rn, newterrain(T_OCEAN));
} }
if (virgin_region(rn)) { if (virgin_region(rn)) {
@ -691,7 +704,11 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
region * rn = rconnect(r, d); region * rn = rconnect(r, d);
if (rn==NULL) { if (rn==NULL) {
const struct terrain_type * terrain = newterrain(T_OCEAN); const struct terrain_type * terrain = newterrain(T_OCEAN);
rn = new_region(r->x + delta_x[d], r->y + delta_y[d], 0); plane * pl = rplane(r);
int x = r->x + delta_x[d];
int y = r->y + delta_y[d];
pnormalize(&x, &y, pl);
rn = new_region(x, y, pl, 0);
if (rng_int() % SPECIALCHANCE < special) { if (rng_int() % SPECIALCHANCE < special) {
terrain = random_terrain(terrainarr, distribution, nterrains); terrain = random_terrain(terrainarr, distribution, nterrains);
special = SPECIALCHANCE / 3; /* 33% chance auf noch eines */ special = SPECIALCHANCE / 3; /* 33% chance auf noch eines */
@ -709,18 +726,26 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
} }
while (*rbegin) { while (*rbegin) {
region * r = (*rbegin)->data; region * r = (*rbegin)->data;
plane * pl = rplane(r);
direction_t d; direction_t d;
rbegin=&(*rbegin)->next; rbegin=&(*rbegin)->next;
for (d=0;d!=MAXDIRECTIONS;++d) if (rconnect(r, d)==NULL) { for (d=0;d!=MAXDIRECTIONS;++d) if (rconnect(r, d)==NULL) {
int i; int i;
for (i=1;i!=MAXFILLDIST;++i) { for (i=1;i!=MAXFILLDIST;++i) {
if (findregion(r->x + i*delta_x[d], r->y + i*delta_y[d])) int x = r->x + delta_x[d]*i;
int y = r->y + delta_y[d]*i;
pnormalize(&x, &y, pl);
if (findregion(x, y)) {
break; break;
}
} }
if (i!=MAXFILLDIST) { if (i!=MAXFILLDIST) {
while (--i) { while (--i) {
region * rn = new_region(r->x + i*delta_x[d], r->y + i*delta_y[d], 0); region * rn;
int x = r->x + delta_x[d]*i;
int y = r->y + delta_y[d]*i;
pnormalize(&x, &y, pl);
rn = new_region(x, y, pl, 0);
terraform_region(rn, newterrain(T_OCEAN)); terraform_region(rn, newterrain(T_OCEAN));
} }
} }
@ -808,7 +833,11 @@ random_neighbours(region * r, region_list ** rlist, const terrain_type *(*terraf
region * rn = rconnect(r, dir); region * rn = rconnect(r, dir);
if (rn==NULL) { if (rn==NULL) {
const terrain_type * terrain = terraformer(dir); const terrain_type * terrain = terraformer(dir);
rn = new_region(r->x+delta_x[dir], r->y+delta_y[dir], 0); plane * pl = rplane(r);
int x = r->x + delta_x[dir];
int y = r->y + delta_y[dir];
pnormalize(&x, &y, pl);
rn = new_region(x, y, pl, 0);
terraform_region(rn, terrain); terraform_region(rn, terrain);
regionqueue_push(rlist, rn); regionqueue_push(rlist, rn);
if (rn->land) { if (rn->land) {
@ -847,7 +876,11 @@ oceans_around(region * r, region * rn[])
for (n=0;n!=MAXDIRECTIONS;++n) { for (n=0;n!=MAXDIRECTIONS;++n) {
region * rx = rn[n]; region * rx = rn[n];
if (rx==NULL) { if (rx==NULL) {
rx = new_region(r->x+delta_x[n], r->y+delta_y[n], 0); plane * pl = rplane(r);
int x = r->x + delta_x[n];
int y = r->y + delta_y[n];
pnormalize(&x, &y, pl);
rx = new_region(x, y, pl, 0);
terraform_region(rx, newterrain(T_OCEAN)); terraform_region(rx, newterrain(T_OCEAN));
rn[n] = rx; rn[n] = rx;
} }
@ -874,6 +907,7 @@ smooth_island(region_list * island)
if (nland==1) { if (nland==1) {
get_neighbours(r, rn); get_neighbours(r, rn);
oceans_around(r, rn);
for (n=0;n!=MAXDIRECTIONS;++n) { for (n=0;n!=MAXDIRECTIONS;++n) {
int n1 = (n+1)%MAXDIRECTIONS; int n1 = (n+1)%MAXDIRECTIONS;
int n2 = (n+1+MAXDIRECTIONS)%MAXDIRECTIONS; int n2 = (n+1+MAXDIRECTIONS)%MAXDIRECTIONS;
@ -920,7 +954,8 @@ build_island_e3(int x, int y, int numfactions, int minsize)
int nfactions = 0; int nfactions = 0;
region_list * rlist = NULL; region_list * rlist = NULL;
region_list * island = NULL; region_list * island = NULL;
region * r = new_region(x, y, 0); plane * pl = findplane(x, y);
region * r = new_region(x, y, pl, 0);
int nsize = 1; int nsize = 1;
int q, maxq = INT_MIN, minq = INT_MAX; int q, maxq = INT_MIN, minq = INT_MAX;
@ -943,33 +978,35 @@ build_island_e3(int x, int y, int numfactions, int minsize)
smooth_island(island); smooth_island(island);
for (rlist=island;rlist;rlist=rlist->next) { if (nsize>minsize/2) {
r = rlist->data; for (rlist=island;rlist;rlist=rlist->next) {
if (r->land && fval(r, RF_MARK)) { r = rlist->data;
region *rn[MAXDIRECTIONS]; if (r->land && fval(r, RF_MARK)) {
region *rn[MAXDIRECTIONS];
get_neighbours(r, rn); get_neighbours(r, rn);
q = region_quality(r,rn); q = region_quality(r,rn);
if (q>=MIN_QUALITY && nfactions<numfactions) { if (q>=MIN_QUALITY && nfactions<numfactions) {
starting_region(r, rn); starting_region(r, rn);
minq = MIN(minq, q); minq = MIN(minq, q);
maxq = MAX(maxq, q); maxq = MAX(maxq, q);
++nfactions; ++nfactions;
}
} }
} }
}
for (rlist=island;rlist && nfactions<numfactions;rlist=rlist->next) { for (rlist=island;rlist && nfactions<numfactions;rlist=rlist->next) {
r = rlist->data; r = rlist->data;
if (!r->land && fval(r, RF_MARK)) { if (!r->land && fval(r, RF_MARK)) {
region *rn[MAXDIRECTIONS]; region *rn[MAXDIRECTIONS];
get_neighbours(r, rn); get_neighbours(r, rn);
q = region_quality(r, rn); q = region_quality(r, rn);
if (q>=MIN_QUALITY*4/3 && nfactions<numfactions) { if (q>=MIN_QUALITY*4/3 && nfactions<numfactions) {
starting_region(r, rn); starting_region(r, rn);
minq = MIN(minq, q); minq = MIN(minq, q);
maxq = MAX(maxq, q); maxq = MAX(maxq, q);
++nfactions; ++nfactions;
}
} }
} }
} }

View file

@ -174,13 +174,16 @@ static void
gm_gate(const tnode * tnext, void * data, struct order * ord) gm_gate(const tnode * tnext, void * data, struct order * ord)
{ {
unit * u = (unit*)data; unit * u = (unit*)data;
const struct plane * p = rplane(u->region); const struct plane * pl = rplane(u->region);
int id = getid(); int id = getid();
int x = rel_to_abs(p, u->faction, getint(), 0); int x = rel_to_abs(pl, u->faction, getint(), 0);
int y = rel_to_abs(p, u->faction, getint(), 1); int y = rel_to_abs(pl, u->faction, getint(), 1);
region * r = findregion(x, y);
building * b = findbuilding(id); building * b = findbuilding(id);
if (b==NULL || r==NULL || p!=rplane(b->region) || p!=rplane(r)) { region * r;
pnormalize(&x, &y, pl);
r = findregion(x, y);
if (b==NULL || r==NULL || pl!=rplane(b->region) || pl!=rplane(r)) {
mistake(u, ord, "the unit cannot transform this building."); mistake(u, ord, "the unit cannot transform this building.");
return; return;
} else { } else {
@ -211,9 +214,11 @@ gm_terraform(const tnode * tnext, void * data, struct order * ord)
int x = rel_to_abs(p, u->faction, getint(), 0); int x = rel_to_abs(p, u->faction, getint(), 0);
int y = rel_to_abs(p, u->faction, getint(), 1); int y = rel_to_abs(p, u->faction, getint(), 1);
const char * c = getstrtoken(); const char * c = getstrtoken();
region * r = findregion(x, y);
variant token; variant token;
tnode * tokens = get_translations(u->faction->locale, UT_TERRAINS); tnode * tokens = get_translations(u->faction->locale, UT_TERRAINS);
region * r;
pnormalize(&x, &y, p);
r = findregion(x, y);
if (r==NULL || p!=rplane(r)) { if (r==NULL || p!=rplane(r)) {
mistake(u, ord, "region is in another plane."); mistake(u, ord, "region is in another plane.");
@ -613,7 +618,7 @@ gmcommands(void)
faction * faction *
gm_addquest(const char * email, const char * name, int radius, unsigned int flags) gm_addquest(const char * email, const char * name, int radius, unsigned int flags)
{ {
plane * p; plane * pl;
watcher * w = calloc(sizeof(watcher), 1); watcher * w = calloc(sizeof(watcher), 1);
region * center; region * center;
boolean invalid = false; boolean invalid = false;
@ -635,15 +640,16 @@ gm_addquest(const char * email, const char * name, int radius, unsigned int flag
} while (invalid); } while (invalid);
maxx = minx+2*radius; cx = minx+radius; maxx = minx+2*radius; cx = minx+radius;
maxy = miny+2*radius; cy = miny+radius; maxy = miny+2*radius; cy = miny+radius;
p = create_new_plane(rng_int(), name, minx, maxx, miny, maxy, flags); pl = create_new_plane(rng_int(), name, minx, maxx, miny, maxy, flags);
center = new_region(cx, cy, 0); center = new_region(cx, cy, pl, 0);
for (x=0;x<=2*radius;++x) { for (x=0;x<=2*radius;++x) {
int y; int y;
for (y=0;y<=2*radius;++y) { for (y=0;y<=2*radius;++y) {
region * r = findregion(minx+x, miny+y); region * r = findregion(minx+x, miny+y);
if (!r) r = new_region(minx+x, miny+y, 0); if (!r) {
r = new_region(minx+x, miny+y, pl, 0);
}
freset(r, RF_ENCOUNTER); freset(r, RF_ENCOUNTER);
r->planep = p;
if (distance(r, center)==radius) { if (distance(r, center)==radius) {
terraform_region(r, newterrain(T_FIREWALL)); terraform_region(r, newterrain(T_FIREWALL));
} else if (r==center) { } else if (r==center) {
@ -655,11 +661,11 @@ gm_addquest(const char * email, const char * name, int radius, unsigned int flag
} }
/* watcher: */ /* watcher: */
f = gm_addfaction(email, p, center); f = gm_addfaction(email, pl, center);
w->faction = f; w->faction = f;
w->mode = see_unit; w->mode = see_unit;
w->next = p->watchers; w->next = pl->watchers;
p->watchers = w; pl->watchers = w;
return f; return f;
} }
@ -726,7 +732,7 @@ plane *
gm_addplane(int radius, unsigned int flags, const char * name) gm_addplane(int radius, unsigned int flags, const char * name)
{ {
region * center; region * center;
plane * p; plane * pl;
boolean invalid = false; boolean invalid = false;
int minx, miny, maxx, maxy, cx, cy; int minx, miny, maxx, maxy, cx, cy;
int x; int x;
@ -745,15 +751,14 @@ gm_addplane(int radius, unsigned int flags, const char * name)
} while (invalid); } while (invalid);
maxx = minx+2*radius; cx = minx+radius; maxx = minx+2*radius; cx = minx+radius;
maxy = miny+2*radius; cy = miny+radius; maxy = miny+2*radius; cy = miny+radius;
p = create_new_plane(rng_int(), name, minx, maxx, miny, maxy, flags); pl = create_new_plane(rng_int(), name, minx, maxx, miny, maxy, flags);
center = new_region(cx, cy, 0); center = new_region(cx, cy, pl, 0);
for (x=0;x<=2*radius;++x) { for (x=0;x<=2*radius;++x) {
int y; int y;
for (y=0;y<=2*radius;++y) { for (y=0;y<=2*radius;++y) {
region * r = findregion(minx+x, miny+y); region * r = findregion(minx+x, miny+y);
if (!r) r = new_region(minx+x, miny+y, 0); if (!r) r = new_region(minx+x, miny+y, pl, 0);
freset(r, RF_ENCOUNTER); freset(r, RF_ENCOUNTER);
r->planep = p;
if (distance(r, center)==radius) { if (distance(r, center)==radius) {
terraform_region(r, newterrain(T_FIREWALL)); terraform_region(r, newterrain(T_FIREWALL));
} else if (r==center) { } else if (r==center) {
@ -763,5 +768,5 @@ gm_addplane(int radius, unsigned int flags, const char * name)
} }
} }
} }
return p; return pl;
} }

View file

@ -345,11 +345,12 @@ use_museumticket(unit *u, const struct item_type *itype, int amount, order * ord
{ {
attrib *a; attrib *a;
region *r = u->region; region *r = u->region;
plane * pl = rplane(r);
unused(amount); unused(amount);
/* Prüfen ob in normaler Plane und nur eine Person */ /* Prüfen ob in normaler Plane und nur eine Person */
if(r->planep != NULL) { if (pl != get_homeplane()) {
cmistake(u, ord, 265, MSG_MAGIC); cmistake(u, ord, 265, MSG_MAGIC);
return 0; return 0;
} }

View file

@ -39,14 +39,17 @@ make_block(int x, int y, int radius, const struct terrain_type * terrain)
{ {
int cx, cy; int cx, cy;
region *r; region *r;
plane * pl = findplane(x, y);
if (terrain==NULL) return; if (terrain==NULL) return;
for (cx = x - radius; cx != x+radius; ++cx) { for (cx = x - radius; cx != x+radius; ++cx) {
for (cy = y - radius; cy != y+radius; ++cy) { for (cy = y - radius; cy != y+radius; ++cy) {
if (koor_distance(cx, cy, x, y) < radius) { int nx = cx, ny = cy;
if (!findregion(cx, cy)) { pnormalize(&nx, &ny, pl);
r = new_region(cx, cy, 0); if (koor_distance(nx, ny, x, y) < radius) {
if (!findregion(nx, ny)) {
r = new_region(nx, ny, pl, 0);
terraform_region(r, terrain); terraform_region(r, terrain);
} }
} }

View file

@ -134,6 +134,13 @@ init_curses(void)
refresh(); refresh();
} }
void cnormalize(const coordinate * c, int * x, int * y)
{
*x = c->x;
*y = c->y;
pnormalize(x, y, c->pl);
}
map_region * map_region *
mr_get(const view * vi, int xofs, int yofs) mr_get(const view * vi, int xofs, int yofs)
{ {
@ -168,14 +175,14 @@ win_create(WINDOW * hwin)
} }
static void static void
untag_region(selection * s, const coordinate * c) untag_region(selection * s, int nx, int ny)
{ {
unsigned int key = ((c->x << 12) ^ c->y); unsigned int key = ((nx << 12) ^ ny);
tag ** tp = &s->tags[key & (MAXTHASH-1)]; tag ** tp = &s->tags[key & (MAXTHASH-1)];
tag * t = NULL; tag * t = NULL;
while (*tp) { while (*tp) {
t = *tp; t = *tp;
if (t->coord.p==c->p && t->coord.x==c->x && t->coord.y==c->y) break; if (t->coord.x==nx && t->coord.y==ny) break;
tp=&t->nexthash; tp=&t->nexthash;
} }
if (!*tp) return; if (!*tp) return;
@ -185,28 +192,30 @@ untag_region(selection * s, const coordinate * c)
} }
static void static void
tag_region(selection * s, const coordinate * c) tag_region(selection * s, int nx, int ny)
{ {
unsigned int key = ((c->x << 12) ^ c->y); unsigned int key = ((nx << 12) ^ ny);
tag ** tp = &s->tags[key & (MAXTHASH-1)]; tag ** tp = &s->tags[key & (MAXTHASH-1)];
while (*tp) { while (*tp) {
tag * t = *tp; tag * t = *tp;
if (t->coord.p==c->p && t->coord.x==c->x && t->coord.y==c->y) return; if (t->coord.x==nx && t->coord.y==ny) return;
tp=&t->nexthash; tp=&t->nexthash;
} }
*tp = calloc(1, sizeof(tag)); *tp = calloc(1, sizeof(tag));
(*tp)->coord = *c; (*tp)->coord.x = nx;
(*tp)->coord.y = ny;
(*tp)->coord.pl = findplane(nx, ny);
return; return;
} }
static int static int
tagged_region(selection * s, const coordinate * c) tagged_region(selection * s, int nx, int ny)
{ {
unsigned int key = ((c->x << 12) ^ c->y); unsigned int key = ((nx << 12) ^ ny);
tag ** tp = &s->tags[key & (MAXTHASH-1)]; tag ** tp = &s->tags[key & (MAXTHASH-1)];
while (*tp) { while (*tp) {
tag * t = *tp; tag * t = *tp;
if (t->coord.x==c->x && t->coord.p==c->p && t->coord.y==c->y) return 1; if (t->coord.x==nx && t->coord.y==ny) return 1;
tp=&t->nexthash; tp=&t->nexthash;
} }
return 0; return 0;
@ -254,22 +263,25 @@ paint_map(window * wnd, const state * st)
WINDOW * win = wnd->handle; WINDOW * win = wnd->handle;
int lines = getmaxy(win); int lines = getmaxy(win);
int cols = getmaxx(win); int cols = getmaxx(win);
int x, y; int vx, vy;
lines = lines/THEIGHT; lines = lines/THEIGHT;
cols = cols/TWIDTH; cols = cols/TWIDTH;
for (y = 0; y!=lines; ++y) { for (vy = 0; vy!=lines; ++vy) {
int yp = (lines - y - 1) * THEIGHT; int yp = (lines - vy - 1) * THEIGHT;
for (x = 0; x!=cols; ++x) { for (vx = 0; vx!=cols; ++vx) {
map_region * mr = mr_get(&st->display, vx, vy);
int attr = 0; int attr = 0;
int hl = 0; int hl = 0;
int xp = x * TWIDTH + (y & 1) * TWIDTH/2; int xp = vx * TWIDTH + (vy & 1) * TWIDTH/2;
map_region * mr = mr_get(&st->display, x, y); int nx, ny;
if (mr && st && tagged_region(st->selected, &mr->coord)) {
attr |= A_REVERSE;
}
if (mr) { if (mr) {
if (st) {
cnormalize(&mr->coord, &nx, &ny);
if (tagged_region(st->selected, nx, ny)) {
attr |= A_REVERSE;
}
}
if (mr->r && mr->r->flags & RF_MAPPER_HIGHLIGHT) hl = 1; if (mr->r && mr->r->flags & RF_MAPPER_HIGHLIGHT) hl = 1;
mvwaddch(win, yp, xp, mr_tile(mr, hl) | attr); mvwaddch(win, yp, xp, mr_tile(mr, hl) | attr);
} }
@ -297,7 +309,7 @@ static void
draw_cursor(WINDOW * win, selection * s, const view * v, const coordinate * c, int show) draw_cursor(WINDOW * win, selection * s, const view * v, const coordinate * c, int show)
{ {
int lines = getmaxy(win)/THEIGHT; int lines = getmaxy(win)/THEIGHT;
int xp, yp; int xp, yp, nx, ny;
int attr = 0; int attr = 0;
map_region * mr = cursor_region(v, c); map_region * mr = cursor_region(v, c);
coordinate relpos; coordinate relpos;
@ -312,7 +324,8 @@ draw_cursor(WINDOW * win, selection * s, const view * v, const coordinate * c, i
yp = (lines - cy - 1) * THEIGHT; yp = (lines - cy - 1) * THEIGHT;
xp = cx * TWIDTH + (cy & 1) * TWIDTH/2; xp = cx * TWIDTH + (cy & 1) * TWIDTH/2;
if (s && tagged_region(s, &mr->coord)) attr = A_REVERSE; cnormalize(&mr->coord, &nx, &ny);
if (s && tagged_region(s, nx, ny)) attr = A_REVERSE;
if (mr->r) { if (mr->r) {
int hl = 0; int hl = 0;
if (mr->r->flags & RF_MAPPER_HIGHLIGHT) hl = 1; if (mr->r->flags & RF_MAPPER_HIGHLIGHT) hl = 1;
@ -339,7 +352,7 @@ paint_status(window * wnd, const state * st)
{ {
WINDOW * win = wnd->handle; WINDOW * win = wnd->handle;
const char * name = ""; const char * name = "";
int uid = 0; int nx, ny, uid = 0;
const char * terrain = "----"; const char * terrain = "----";
map_region * mr = cursor_region(&st->display, &st->cursor); map_region * mr = cursor_region(&st->display, &st->cursor);
if (mr && mr->r) { if (mr && mr->r) {
@ -351,7 +364,8 @@ paint_status(window * wnd, const state * st)
} }
terrain = mr->r->terrain->_name; terrain = mr->r->terrain->_name;
} }
mvwprintw(win, 0, 0, "%4d %4d | %.4s | %.20s (%d)", st->cursor.x, st->cursor.y, terrain, name, uid); cnormalize(&st->cursor, &nx, &ny);
mvwprintw(win, 0, 0, "%4d %4d | %.4s | %.20s (%d)", nx, ny, terrain, name, uid);
wclrtoeol(win); wclrtoeol(win);
} }
@ -449,9 +463,13 @@ static void
terraform_at(coordinate * c, const terrain_type *terrain) terraform_at(coordinate * c, const terrain_type *terrain)
{ {
if (terrain!=NULL) { if (terrain!=NULL) {
int x = c->x, y = c->y; region * r;
region * r = findregion(x, y); int nx = c->x, ny = c->y;
if (r==NULL) r = new_region(x, y, 0); pnormalize(&nx, &ny, c->pl);
r = findregion(nx, ny);
if (r==NULL) {
r = new_region(nx, ny, c->pl, 0);
}
terraform_region(r, terrain); terraform_region(r, terrain);
} }
} }
@ -465,10 +483,16 @@ terraform_selection(selection * selected, const terrain_type *terrain)
for (i=0;i!=MAXTHASH;++i) { for (i=0;i!=MAXTHASH;++i) {
tag ** tp = &selected->tags[i]; tag ** tp = &selected->tags[i];
while (*tp) { while (*tp) {
region * r;
tag * t = *tp; tag * t = *tp;
int x = t->coord.x, y = t->coord.y; int nx = t->coord.x, ny = t->coord.y;
region * r = findregion(x, y); plane * pl = t->coord.pl;
if (r==NULL) r = new_region(x, y, 0);
pnormalize(&nx, &ny, pl);
r = findregion(nx, ny);
if (r==NULL) {
r = new_region(nx, ny, pl, 0);
}
terraform_region(r, terrain); terraform_region(r, terrain);
tp = &t->nexthash; tp = &t->nexthash;
} }
@ -530,7 +554,7 @@ region2coord(const region * r, coordinate * c)
{ {
c->x = r->x; c->x = r->x;
c->y = r->y; c->y = r->y;
c->p = r->planep?r->planep->id:0; c->pl = rplane(r);
return c; return c;
} }
@ -556,13 +580,10 @@ highlight_region(region *r, int toggle)
} }
void void
select_coordinate(struct selection * selected, int x, int y, int toggle) select_coordinate(struct selection * selected, int nx, int ny, int toggle)
{ {
coordinate coord = { 0 }; if (toggle) tag_region(selected, nx, ny);
coord.x = x; else untag_region(selected, nx, ny);
coord.y = y;
if (toggle) tag_region(selected, &coord);
else untag_region(selected, &coord);
} }
enum { MODE_MARK, MODE_SELECT, MODE_UNMARK, MODE_UNSELECT }; enum { MODE_MARK, MODE_SELECT, MODE_UNMARK, MODE_UNSELECT };
@ -729,7 +750,7 @@ handlekey(state * st, int c)
region *r; region *r;
char sbuffer[80]; char sbuffer[80];
static char kbuffer[80]; static char kbuffer[80];
int n; int n, nx, ny;
switch(c) { switch(c) {
case FAST_RIGHT: case FAST_RIGHT:
@ -791,15 +812,17 @@ handlekey(state * st, int c)
/* /*
make_block(st->cursor.x, st->cursor.y, 6, select_terrain(st, NULL)); make_block(st->cursor.x, st->cursor.y, 6, select_terrain(st, NULL));
*/ */
cnormalize(&st->cursor, &nx, &ny);
n = rng_int() % 8 + 8; n = rng_int() % 8 + 8;
build_island_e3(st->cursor.x, st->cursor.y, n, n*3); build_island_e3(nx, ny, n, n*3);
st->modified = 1; st->modified = 1;
st->wnd_info->update |= 1; st->wnd_info->update |= 1;
st->wnd_status->update |= 1; st->wnd_status->update |= 1;
st->wnd_map->update |= 1; st->wnd_map->update |= 1;
break; break;
case 0x02: /* CTRL+b */ case 0x02: /* CTRL+b */
make_block(st->cursor.x, st->cursor.y, 6, newterrain(T_OCEAN)); cnormalize(&st->cursor, &nx, &ny);
make_block(nx, ny, 6, newterrain(T_OCEAN));
st->modified = 1; st->modified = 1;
st->wnd_info->update |= 1; st->wnd_info->update |= 1;
st->wnd_status->update |= 1; st->wnd_status->update |= 1;
@ -811,10 +834,12 @@ handlekey(state * st, int c)
if (mr) { if (mr) {
region * first = mr->r; region * first = mr->r;
region * cur = (first&&first->next)?first->next:regions; region * cur = (first&&first->next)?first->next:regions;
while (cur!=first) { while (cur!=first) {
coordinate coord; coordinate coord;
region2coord(cur, &coord); region2coord(cur, &coord);
if (tagged_region(st->selected, &coord)) { cnormalize(&coord, &nx, &ny);
if (tagged_region(st->selected, nx, ny)) {
st->cursor = coord; st->cursor = coord;
st->wnd_info->update |= 1; st->wnd_info->update |= 1;
st->wnd_status->update |= 1; st->wnd_status->update |= 1;
@ -827,12 +852,31 @@ handlekey(state * st, int c)
} }
break; break;
case 'p':
if (planes) {
plane * pl = planes;
if (cursor->pl) {
while (pl && pl!=cursor->pl) {
pl = pl->next;
}
if (pl->next) {
cursor->pl = pl->next;
} else {
cursor->pl = get_homeplane();
}
} else {
cursor->pl = planes;
}
}
break;
case 'a': case 'a':
if (regions!=NULL) { if (regions!=NULL) {
map_region * mr = cursor_region(&st->display, cursor); map_region * mr = cursor_region(&st->display, cursor);
if (mr && mr->r) { if (mr && mr->r) {
region * cur = mr->r; region * cur = mr->r;
if (cur->planep==NULL) { plane * pl = rplane(cur);
if (pl==NULL) {
cur = r_standard_to_astral(cur); cur = r_standard_to_astral(cur);
} else if (is_astral(cur)) { } else if (is_astral(cur)) {
cur = r_astral_to_standard(cur); cur = r_astral_to_standard(cur);
@ -948,8 +992,9 @@ handlekey(state * st, int c)
} }
break; break;
case ' ': case ' ':
if (tagged_region(st->selected, cursor)) untag_region(st->selected, cursor); cnormalize(cursor, &nx, &ny);
else tag_region(st->selected, cursor); if (tagged_region(st->selected, nx, ny)) untag_region(st->selected, nx, ny);
else tag_region(st->selected, nx, ny);
break; break;
case 'A': case 'A':
sprintf(sbuffer, "%s/newfactions", basepath()); sprintf(sbuffer, "%s/newfactions", basepath());
@ -1055,8 +1100,8 @@ init_view(view * display, WINDOW * win)
{ {
display->topleft.x = 1; display->topleft.x = 1;
display->topleft.y = 1; display->topleft.y = 1;
display->topleft.p = 0; display->topleft.pl = get_homeplane();
display->plane = 0; display->pl = get_homeplane();
display->size.width = getmaxx(win)/TWIDTH; display->size.width = getmaxx(win)/TWIDTH;
display->size.height = getmaxy(win)/THEIGHT; display->size.height = getmaxy(win)/THEIGHT;
display->regions = calloc(display->size.height * display->size.width, sizeof(map_region)); display->regions = calloc(display->size.height * display->size.width, sizeof(map_region));
@ -1071,7 +1116,8 @@ update_view(view * vi)
map_region * mr = mr_get(vi, i, j); map_region * mr = mr_get(vi, i, j);
mr->coord.x = vi->topleft.x + i - j/2; mr->coord.x = vi->topleft.x + i - j/2;
mr->coord.y = vi->topleft.y + j; mr->coord.y = vi->topleft.y + j;
mr->coord.p = vi->plane; mr->coord.pl = vi->pl;
pnormalize(&mr->coord.x, &mr->coord.y, mr->coord.pl);
mr->r = findregion(mr->coord.x, mr->coord.y); mr->r = findregion(mr->coord.x, mr->coord.y);
} }
} }
@ -1081,8 +1127,8 @@ state *
state_open(void) state_open(void)
{ {
state * st = calloc(sizeof(state), 1); state * st = calloc(sizeof(state), 1);
st->display.plane = 0; st->display.pl = get_homeplane();
st->cursor.p = 0; st->cursor.pl = get_homeplane();
st->cursor.x = 0; st->cursor.x = 0;
st->cursor.y = 0; st->cursor.y = 0;
st->selected = calloc(1, sizeof(struct selection)); st->selected = calloc(1, sizeof(struct selection));
@ -1154,8 +1200,8 @@ run_mapper(void)
height = getmaxy(hwinmap)-y; height = getmaxy(hwinmap)-y;
coor2point(&st->cursor, &p); coor2point(&st->cursor, &p);
if (st->cursor.p != vi->plane) { if (st->cursor.pl != vi->pl) {
vi->plane = st->cursor.p; vi->pl = st->cursor.pl;
st->wnd_map->update |= 1; st->wnd_map->update |= 1;
} }
if (p.y < tl.y) { if (p.y < tl.y) {

View file

@ -29,8 +29,9 @@ typedef struct point {
} point; } point;
typedef struct coordinate { typedef struct coordinate {
/* Eine Koordinate in der Welt */ /* Eine Koordinate im Editor, nicht normalisiert */
int x, y, p; int x, y;
struct plane * pl;
} coordinate; } coordinate;
typedef struct map_region { typedef struct map_region {
@ -40,7 +41,7 @@ typedef struct map_region {
typedef struct view { typedef struct view {
struct map_region * regions; struct map_region * regions;
int plane; struct plane * pl;
coordinate topleft; /* upper left corner in map. */ coordinate topleft; /* upper left corner in map. */
extent size; /* dimensions. */ extent size; /* dimensions. */
} view; } view;
@ -69,6 +70,7 @@ typedef struct state {
} state; } state;
extern map_region * cursor_region(const view * v, const coordinate * c); extern map_region * cursor_region(const view * v, const coordinate * c);
extern void cnormalize(const coordinate * c, int * x, int * y);
extern state * current_state; extern state * current_state;
#define TWIDTH 2 /* width of tile */ #define TWIDTH 2 /* width of tile */

View file

@ -56,8 +56,11 @@ public:
node = node->nexthash; node = node->nexthash;
} }
coordinate * c = &self->coord; coordinate * c = &self->coord;
unsigned int key = ((c->x << 12) ^ c->y); unsigned int hash;
unsigned int hash = key & (MAXTHASH-1); int nx, ny;
cnormalize(c, &nx, &ny);
hash = ((nx << 12) ^ ny) & (MAXTHASH-1);
return next_tag(hash+1, current_state); return next_tag(hash+1, current_state);
} }
@ -77,13 +80,16 @@ selected_regions(void)
static void static void
gmtool_select_coordinate(int x, int y, bool select) gmtool_select_coordinate(int x, int y, bool select)
{ {
select_coordinate(current_state->selected, x, y, select?1:0); int nx = x, ny = y;
plane * pl = findplane(x, y);
pnormalize(&nx, &ny, pl);
select_coordinate(current_state->selected, nx, ny, select?1:0);
} }
static void static void
gmtool_select_region(region& r, bool select) gmtool_select_region(region& r, bool select)
{ {
select_coordinate(current_state->selected, r.x, r.y, select?1:0); select_coordinate(current_state->selected, r.x, r.y, select?1:0);
} }
static void gmtool_open(void) static void gmtool_open(void)

View file

@ -89,8 +89,8 @@ region_getherbtype(const region * r) {
static int static int
region_plane(const region * r) region_plane(const region * r)
{ {
if (r->planep==NULL) return 0; plane * pl = rplane(r);
return r->planep->id; return plane_id(pl);
} }
static void static void
@ -197,7 +197,10 @@ region_terraform(int x, int y, const char * tname)
} }
return NULL; return NULL;
} }
if (r==NULL) r = new_region(x, y, 0); if (r==NULL) {
struct plane * pl = findplane(x, y);
r = new_region(x, y, pl, 0);
}
terraform_region(r, terrain); terraform_region(r, terrain);
return r; return r;
} }
@ -224,12 +227,13 @@ region_remove(region * r)
} }
static void static void
plane_remove(int plane_id) plane_remove(int plid)
{ {
region ** rp = &regions; region ** rp = &regions;
while (*rp) { while (*rp) {
region * r = *rp; region * r = *rp;
if (r->planep && r->planep->id==plane_id) { plane * pl = rplane(r);
if (pl && pl->id==plid) {
remove_region(rp, r); remove_region(rp, r);
} else { } else {
rp = &r->next; rp = &r->next;
@ -240,19 +244,23 @@ plane_remove(int plane_id)
void void
region_move(region * r, int x, int y) region_move(region * r, int x, int y)
{ {
if (findregion(x,y)) { if (findregion(x, y)) {
log_error(("Bei %d, %d gibt es schon eine Region.\n", x, y)); log_error(("Bei %d, %d gibt es schon eine Region.\n", x, y));
return; return;
} }
#ifdef FAST_CONNECT #ifdef FAST_CONNECT
direction_t dir; direction_t dir;
plane * pl = rplane(r);
for (dir=0;dir!=MAXDIRECTIONS;++dir) { for (dir=0;dir!=MAXDIRECTIONS;++dir) {
region * rn = r->connect[dir]; region * rn = r->connect[dir];
int nx = x + delta_x[dir];
int ny = y + delta_y[dir];
pnormalize(&nx, &ny, pl);
if (rn!=NULL) { if (rn!=NULL) {
direction_t reldir = reldirection(rn, r); direction_t reldir = reldirection(rn, r);
rn->connect[reldir] = NULL; rn->connect[reldir] = NULL;
} }
rn = findregion(x+delta_x[dir], y+delta_y[dir]); rn = findregion(nx, ny);
if (rn!=NULL) { if (rn!=NULL) {
direction_t reldir = (direction_t)((dir + 3) % MAXDIRECTIONS); direction_t reldir = (direction_t)((dir + 3) % MAXDIRECTIONS);
rn->connect[reldir] = r; rn->connect[reldir] = r;

View file

@ -40,11 +40,13 @@ tolua_current_region(lua_State* L)
static int static int
tolua_select_coordinate(lua_State* L) tolua_select_coordinate(lua_State* L)
{ {
int x = (int)tolua_tonumber(L, 1, 0); int nx = (int)tolua_tonumber(L, 1, 0);
int y = (int)tolua_tonumber(L, 2, 0); int ny = (int)tolua_tonumber(L, 2, 0);
int select = tolua_toboolean(L, 3, 0); int select = tolua_toboolean(L, 3, 0);
plane * pl = findplane(nx, ny);
pnormalize(&nx, &ny, pl);
if (current_state) { if (current_state) {
select_coordinate(current_state->selected, x, y, select); select_coordinate(current_state->selected, nx, ny, select);
} }
return 0; return 0;
} }
@ -155,10 +157,13 @@ tolua_state_close(lua_State* L)
static int static int
tolua_make_island(lua_State * L) tolua_make_island(lua_State * L)
{ {
int x = (int)tolua_tonumber(L, 1, 0); plane * pl = (plane *)tolua_tousertype(L, 1, 0);
int y = (int)tolua_tonumber(L, 2, 0); int x = (int)tolua_tonumber(L, 2, 0);
int n = (int)tolua_tonumber(L, 3, 0); int y = (int)tolua_tonumber(L, 3, 0);
n = build_island_e3(x, y, n, n*3); int s = (int)tolua_tonumber(L, 4, 0);
int n = (int)tolua_tonumber(L, 5, s / 3);
if (pl) pnormalize(&x, &y, pl);
n = build_island_e3(x, y, n, s);
tolua_pushnumber(L, n); tolua_pushnumber(L, n);
return 1; return 1;
} }
@ -166,11 +171,13 @@ tolua_make_island(lua_State * L)
static int static int
tolua_make_block(lua_State * L) tolua_make_block(lua_State * L)
{ {
int x = (int)tolua_tonumber(L, 1, 0); plane * pl = (plane *)tolua_tousertype(L, 1, 0);
int y = (int)tolua_tonumber(L, 2, 0); int x = (int)tolua_tonumber(L, 2, 0);
int r = (int)tolua_tonumber(L, 3, 6); int y = (int)tolua_tonumber(L, 3, 0);
const char * str = tolua_tostring(L, 4, "ocean"); int r = (int)tolua_tonumber(L, 4, 6);
const char * str = tolua_tostring(L, 5, "ocean");
const struct terrain_type * ter = get_terrain(str); const struct terrain_type * ter = get_terrain(str);
if (pl) pnormalize(&x, &y, pl);
make_block(x, y, r, ter); make_block(x, y, r, ter);
return 0; return 0;
} }

View file

@ -24,8 +24,9 @@ without prior permission by the authors of Eressea.
#include <kernel/build.h> #include <kernel/build.h>
#include <kernel/building.h> #include <kernel/building.h>
#include <kernel/ship.h> #include <kernel/ship.h>
#include <kernel/plane.h>
#include <kernel/terrain.h> #include <kernel/terrain.h>
#include <modules/autoseed.h>
#include <attributes/key.h> #include <attributes/key.h>
#include <util/attrib.h> #include <util/attrib.h>
@ -220,10 +221,13 @@ tolua_region_create(lua_State* L)
int x = (int)tolua_tonumber(L, 1, 0); int x = (int)tolua_tonumber(L, 1, 0);
int y = (int)tolua_tonumber(L, 2, 0); int y = (int)tolua_tonumber(L, 2, 0);
const char * tname = tolua_tostring(L, 3, 0); const char * tname = tolua_tostring(L, 3, 0);
plane * pl = (plane *)tolua_tousertype(L, 4, 0);
const terrain_type * terrain = get_terrain(tname); const terrain_type * terrain = get_terrain(tname);
region * r = findregion(x, y); region * r, * result;
region * result = r;
if (!pl) pl = findplane(x, y);
pnormalize(&x, &y, pl);
r = result = findregion(x, y);
if (terrain==NULL) { if (terrain==NULL) {
if (r!=NULL) { if (r!=NULL) {
@ -234,7 +238,7 @@ tolua_region_create(lua_State* L)
} }
} }
if (r==NULL) { if (r==NULL) {
result = new_region(x, y, 0); result = new_region(x, y, pl, 0);
} }
if (result) { if (result) {
terraform_region(result, terrain); terraform_region(result, terrain);
@ -336,15 +340,96 @@ tolua_region_tostring(lua_State *L)
return 1; return 1;
} }
static int
tolua_plane_get(lua_State* L)
{
int id = (int)tolua_tonumber(L, 1, 0);
plane * pl = getplanebyid(id);
tolua_pushusertype(L, pl, "plane");
return 1;
}
static int
tolua_plane_create(lua_State* L)
{
int id = (int)tolua_tonumber(L, 1, 0);
int x = (int)tolua_tonumber(L, 2, 0);
int y = (int)tolua_tonumber(L, 3, 0);
int width = (int)tolua_tonumber(L, 4, 0);
int height = (int)tolua_tonumber(L, 5, 0);
const char * name = tolua_tostring(L, 6, 0);
plane * pl;
pl = create_new_plane(id, name, x, x+width-1, y, y+height-1, 0);
tolua_pushusertype(L, pl, "plane");
return 1;
}
static int tolua_plane_get_name(lua_State* L)
{
plane* self = (plane*) tolua_tousertype(L, 1, 0);
tolua_pushstring(L, self->name);
return 1;
}
static int tolua_plane_set_name(lua_State* L)
{
plane* self = (plane*)tolua_tousertype(L, 1, 0);
const char * str = tolua_tostring(L, 2, 0);
free(self->name);
if (str) self->name = strdup(str);
else self->name = 0;
return 0;
}
static int
tolua_plane_get_id(lua_State* L)
{
plane * self = (plane *)tolua_tousertype(L, 1, 0);
tolua_pushnumber(L, (lua_Number)self->id);
return 1;
}
static int
tolua_plane_tostring(lua_State *L)
{
plane * self = (plane *)tolua_tousertype(L, 1, 0);
lua_pushstring(L, self->name);
return 1;
}
static int
tolua_distance(lua_State *L)
{
int x1 = (int)tolua_tonumber(L, 1, 0);
int y1 = (int)tolua_tonumber(L, 2, 0);
int x2 = (int)tolua_tonumber(L, 3, 0);
int y2 = (int)tolua_tonumber(L, 4, 0);
plane * pl = (plane *)tolua_tousertype(L, 5, 0);
int result;
if (!pl) pl = get_homeplane();
pnormalize(&x1, &y1, pl);
pnormalize(&x2, &y2, pl);
result = koor_distance(x1, y1, x2, y2);
lua_pushnumber(L, result);
return 1;
}
void void
tolua_region_open(lua_State* L) tolua_region_open(lua_State* L)
{ {
/* register user types */ /* register user types */
tolua_usertype(L, "region"); tolua_usertype(L, "region");
tolua_usertype(L, "plane");
tolua_module(L, NULL, 0); tolua_module(L, NULL, 0);
tolua_beginmodule(L, NULL); tolua_beginmodule(L, NULL);
{ {
tolua_function(L, "distance", tolua_distance);
tolua_cclass(L, "region", "region", "", NULL); tolua_cclass(L, "region", "region", "", NULL);
tolua_beginmodule(L, "region"); tolua_beginmodule(L, "region");
{ {
@ -386,6 +471,18 @@ tolua_region_open(lua_State* L)
tolua_variable(L, "objects", tolua_region_get_objects, 0); tolua_variable(L, "objects", tolua_region_get_objects, 0);
} }
tolua_endmodule(L); tolua_endmodule(L);
tolua_cclass(L, "plane", "plane", "", NULL);
tolua_beginmodule(L, "plane");
{
tolua_function(L, "create", tolua_plane_create);
tolua_function(L, "get", tolua_plane_get);
tolua_function(L, "__tostring", tolua_plane_tostring);
tolua_variable(L, "id", tolua_plane_get_id, NULL);
tolua_variable(L, "name", tolua_plane_get_name, tolua_plane_set_name);
}
tolua_endmodule(L);
} }
tolua_endmodule(L); tolua_endmodule(L);
} }

View file

@ -834,7 +834,7 @@ tolua_unit_create(lua_State* L)
{ {
faction * f = (faction *)tolua_tousertype(L, 1, 0); faction * f = (faction *)tolua_tousertype(L, 1, 0);
region * r = (region *)tolua_tousertype(L, 2, 0); region * r = (region *)tolua_tousertype(L, 2, 0);
int num = (int)tolua_tonumber(L, 3, 0); int num = (int)tolua_tonumber(L, 3, 1);
if (f && r) { if (f && r) {
const race * rc = f->race; const race * rc = f->race;
const char * rcname = tolua_tostring(L, 4, NULL); const char * rcname = tolua_tostring(L, 4, NULL);

View file

@ -29,6 +29,7 @@ without prior permission by the authors of Eressea.
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/reports.h> #include <kernel/reports.h>
#include <kernel/building.h> #include <kernel/building.h>
#include <kernel/plane.h>
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/order.h> #include <kernel/order.h>
@ -554,7 +555,9 @@ static int
tolua_write_map(lua_State* L) tolua_write_map(lua_State* L)
{ {
const char * filename = tolua_tostring(L, 1, 0); const char * filename = tolua_tostring(L, 1, 0);
crwritemap(filename); if (filename) {
crwritemap(filename);
}
return 0; return 0;
} }
@ -602,7 +605,11 @@ tolua_get_region(lua_State* L)
{ {
int x = (int)tolua_tonumber(L, 1, 0); int x = (int)tolua_tonumber(L, 1, 0);
int y = (int)tolua_tonumber(L, 2, 0); int y = (int)tolua_tonumber(L, 2, 0);
region * r = findregion(x, y); struct plane * pl = (struct plane *)tolua_tousertype(L, 3, 0);
region * r;
if (!pl) pl = findplane(x, y);
pnormalize(&x, &y, pl);
r = findregion(x, y);
tolua_pushusertype(L, r, "region"); tolua_pushusertype(L, r, "region");
return 1; return 1;

View file

@ -130,6 +130,7 @@
<param name="recruit.allow_merge" value="1"/> <param name="recruit.allow_merge" value="1"/>
<param name="study.expensivemigrants" value="1"/> <param name="study.expensivemigrants" value="1"/>
<param name="study.speedup" value="1"/> <param name="study.speedup" value="1"/>
<param name="world.era" value="3"/>
<param name="rules.check_overload" value="0"/> <param name="rules.check_overload" value="0"/>
<param name="rules.combat.goblinbonus" value="3"/> <param name="rules.combat.goblinbonus" value="3"/>
<param name="rules.ship.capacity" value="1"/> <!-- --> <param name="rules.ship.capacity" value="1"/> <!-- -->
@ -145,6 +146,7 @@
<param name="rules.cavalry.mode" value="1"/> <param name="rules.cavalry.mode" value="1"/>
<param name="rules.magic.multipotion" value="1"/> <param name="rules.magic.multipotion" value="1"/>
<param name="rules.magic.wol_effect" value="5"/> <param name="rules.magic.wol_effect" value="5"/>
<param name="rules.magic.factionlist" value="0"/>
<param name="rules.magic.wol_type" value="2"/> <param name="rules.magic.wol_type" value="2"/>
<param name="rules.magic.common" value="tybied"/> <!-- tybied spells can be cast by anyone --> <param name="rules.magic.common" value="tybied"/> <!-- tybied spells can be cast by anyone -->
<param name="rules.magic.elfpower" value="1"/> <!-- elves get ring-of-power bonus in a forest --> <param name="rules.magic.elfpower" value="1"/> <!-- elves get ring-of-power bonus in a forest -->

View file

@ -249,9 +249,8 @@ local function test_spells()
free_game() free_game()
local r = region.create(0, 0, "plain") local r = region.create(0, 0, "plain")
local f = faction.create("enno@eressea.de", "human", "de") local f = faction.create("enno@eressea.de", "human", "de")
local u = unit.create(f, r) local u = unit.create(f, r, 1)
u.race = "elf" u.race = "elf"
u.number = 1
u:clear_orders() u:clear_orders()
u:add_item("money", 10000) u:add_item("money", 10000)
u:set_skill("magic", 5) u:set_skill("magic", 5)
@ -261,14 +260,19 @@ local function test_spells()
local nums = 0 local nums = 0
if f.spells~=nil then if f.spells~=nil then
for sp in f.spells do for sp in f.spells do
nums = nums + 1 nums = nums + 1
end end
assert(nums>0)
for sp in u.spells do
nums = nums - 1
end
assert(nums==0)
else
for sp in u.spells do
nums = nums + 1
end
assert(nums>0)
end end
assert(nums>0)
for sp in u.spells do
nums = nums - 1
end
assert(nums==0)
end end
local function test_produce() local function test_produce()
@ -438,7 +442,10 @@ function test_id()
assert(get_building(fortytwo)==b) assert(get_building(fortytwo)==b)
assert(get_building(atoi36(fortytwo))==b) assert(get_building(atoi36(fortytwo))==b)
local s = ship.create(r, "boat") local s = ship.create(r, "canoe")
if (s==nil) then
s = ship.create(r, "boat")
end
-- <not working> s.id = atoi36("42") -- <not working> s.id = atoi36("42")
local fortytwo = itoa36(s.id) local fortytwo = itoa36(s.id)
assert(get_ship(fortytwo)==s) assert(get_ship(fortytwo)==s)
@ -513,7 +520,7 @@ mytests = {
["taxes"] = test_taxes ["taxes"] = test_taxes
} }
fail = 0 fail = 0
for k, v in pairs(mytests) do for k, v in pairs(tests) do
local status, err = pcall(v) local status, err = pcall(v)
if not status then if not status then
fail = fail + 1 fail = fail + 1