big change: more configuration for the torus (and also Klein bottle)

This commit is contained in:
Zeno Rogue 2017-12-28 16:46:10 +01:00
parent d67ca714fd
commit 11569c693d
21 changed files with 546 additions and 287 deletions

View File

@ -732,9 +732,18 @@ void setLandSphere(cell *c) {
}
}
eLand euland[65536];
eLand euland[max_vec];
eLand switchable(eLand nearland, eLand farland, eucoord c) {
eLand& get_euland(int c) {
return euland[c & (max_vec-1)];
}
void clear_euland(eLand first) {
for(int i=0; i<max_vec; i++) euland[i] = laNone;
euland[0] = euland[1] = euland[max_vec-1] = first;
}
eLand switchable(eLand nearland, eLand farland, int c) {
if(specialland == laCrossroads4) {
if(hrand(15) == 0)
return getNewLand(nearland);
@ -755,37 +764,36 @@ eLand switchable(eLand nearland, eLand farland, eucoord c) {
}
}
eLand getEuclidLand(eucoord c) {
if(euland[c]) return euland[c];
if(c == 0 || c == eucoord(-1) || c == 1)
return euland[c] = specialland;
if(euland[eucoord(c-2)] && ! euland[eucoord(c-1)]) getEuclidLand(c-1);
if(euland[eucoord(c+2)] && ! euland[eucoord(c+1)]) getEuclidLand(c+1);
if(euland[eucoord(c-1)]) return
euland[c] = switchable(euland[c-1], euland[eucoord(c-2)], c);
if(euland[eucoord(c+1)]) return
euland[c] = switchable(euland[c+1], euland[eucoord(c+2)], c);
return euland[c] = laCrossroads;
eLand getEuclidLand(int c) {
auto& la = get_euland(c);
if(la) return la;
if(get_euland(c-2) && !get_euland(c-1)) getEuclidLand(c-1);
if(get_euland(c-1)) return
la = switchable(get_euland(c-1), get_euland(c-2), c);
if(get_euland(c+2) && !get_euland(c+1)) getEuclidLand(c+1);
if(get_euland(c+1)) return
la = switchable(get_euland(c+1), get_euland(c+2), c);
return la = laCrossroads;
}
void setLandEuclid(cell *c) {
setland(c, specialland);
if(specialland == laCrossroads) {
eucoord x, y;
decodeMaster(c->master, x, y);
int x, y;
tie(x,y) = cell_to_pair(c);
setland(c, getEuclidLand(y+2*x));
}
if(specialland == laTerracotta) {
eucoord x, y;
decodeMaster(c->master, x, y);
if((y+2*x) % 16 == 1) {
int x, y;
tie(x,y) = cell_to_pair(c);
if(((y+2*x) & 15) == 1) {
setland(c, laMercuryRiver);
c->wall = waMercury;
}
}
if(specialland == laCrossroads4) {
eucoord x, y;
decodeMaster(c->master, x, y);
int x, y;
tie(x,y) = cell_to_pair(c);
c->land = getEuclidLand(y);
}
if(specialland == laWhirlpool) {
@ -794,30 +802,29 @@ void setLandEuclid(cell *c) {
}
if(specialland == laPrincessQuest) setland(c, laPalace);
if(specialland == laOcean) {
eucoord x, y;
decodeMaster(c->master, x, y);
int y0 = y; if(y>50000) y0 -= 65536; y0 += 10;
if(y0 == 0)
int x, y;
tie(x,y) = cell_to_pair(c);
y += 10;
if(y == 0)
{ setland(c, laBarrier); if(ishept(c)) c->land = laRlyeh; }
else if(y0<0) setland(c, laRlyeh);
else c->landparam = y0;
else if(y<0) setland(c, laRlyeh);
else c->landparam = y;
}
if(specialland == laIvoryTower || specialland == laDungeon) {
eucoord x, y;
decodeMaster(c->master, x, y);
int y0 = y; if(y>50000) y0 -= 65536; y0 = -y0; y0 -= 5;
if(y0 == 0)
int x, y;
tie(x,y) = cell_to_pair(c); y -= 5;
if(y == 0)
{setland(c, laBarrier); if(ishept(c)) setland(c, laAlchemist); }
else if(y0<0) setland(c, laAlchemist);
else if(y<0) setland(c, laAlchemist);
else {
c->landparam = y0;
c->landparam = y;
}
}
if(specialland == laElementalWall) {
eucoord x, y;
decodeMaster(c->master, x, y);
int y0 = y; if(y>32768) y0 -= 65536;
int x0 = x +y/2;
int x, y;
tie(x,y) = cell_to_pair(c);
int x0 = x + (y>>1);
int y0 = y;
int id = 0;
if(y0&16) id += 2;
@ -843,10 +850,10 @@ void setLandEuclid(cell *c) {
}
}
if(specialland == laCrossroads3) {
eucoord x, y;
decodeMaster(c->master, x, y);
int y0 = y; if(y>32768) y0 -= 65536;
int x0 = x +y/2;
int x, y;
tie(x,y) = cell_to_pair(c);
int y0 = y;
int x0 = x + y/2;
x0 += 24; y0 += 8;
@ -862,11 +869,11 @@ void setLandEuclid(cell *c) {
}
}
if(specialland == laWarpCoast) {
eucoord x, y;
decodeMaster(c->master, x, y);
int x, y;
tie(x,y) = cell_to_pair(c);
int zz = a4 ? short(x) : 2*short(x)+short(y) + 10;
zz %= 30; if(zz<0) zz += 30;
int zz = a4 ? x : 2*x+y + 10;
zz = gmod(zz, 30);
if(zz >= 15)
setland(c, laWarpSea);
else

357
cell.cpp
View File

@ -192,7 +192,20 @@ heptagon *getDodecahedron(int i) {
// --- euclidean geometry ---
cell*& euclideanAtCreate(eucoord x, eucoord y);
cell*& euclideanAtCreate(int vec);
static const int max_vec = (1<<15);
int pair_to_vec(int x, int y) {
return x + (y << 15);
}
pair<int, int> vec_to_pair(int vec) {
int x = vec & ((1<<15)-1);
int y = (vec >> 15);
if(x >= (1<<14)) x -= (1<<15), y++;
return {x, y};
}
namespace torusconfig {
// the configuration of the torus topology.
@ -208,14 +221,176 @@ namespace torusconfig {
int def_qty = 127*3, dx = 1, def_dy = -11*2;
int qty = def_qty, dy = def_dy;
int sdx = 12, sdy = 12;
// new values to change
int newqty, newdy;
int newqty, newdy, newsdx, newsdy;
int torus_cx, torus_cy;
enum eTorusMode {
tmSingleHex,
tmSingle,
tmSlantedHex,
tmStraight,
tmStraightHex,
tmKlein,
tmKleinHex
};
static const flagtype TF_SINGLE = 1;
static const flagtype TF_SIMPLE = 2;
static const flagtype TF_WEIRD = 4;
static const flagtype TF_HEX = 16;
static const flagtype TF_SQUARE = 32;
static const flagtype TF_KLEIN = 256;
struct torusmode_info {
string name;
flagtype flags;
};
vector<torusmode_info> tmodes = {
{"single row (hex)", TF_SINGLE | TF_HEX},
{"single row (squares)", TF_SINGLE | TF_SQUARE},
{"parallelogram (hex)", TF_SIMPLE | TF_HEX},
{"rectangle (squares)", TF_SIMPLE | TF_SQUARE},
{"rectangle (hex)", TF_WEIRD | TF_HEX},
{"Klein bottle (squares)", TF_SIMPLE | TF_KLEIN | TF_SQUARE},
{"Klein bottle (hex)", TF_WEIRD | TF_KLEIN | TF_HEX},
};
eTorusMode torus_mode, newmode;
flagtype tmflags() { return tmodes[torus_mode].flags; }
int getqty() {
if(tmflags() & TF_SINGLE)
return qty;
else
return sdx * sdy;
}
int getvec(int x, int y) {
if(tmflags() & TF_SINGLE)
return x * dx + y * dy;
else if(tmflags() & TF_SIMPLE)
return pair_to_vec(x, y);
else
return pair_to_vec(-y - 2 * x, 3 * y);
}
int id_to_vec(int id, bool mirrored = false) {
if(tmflags() & TF_SINGLE)
return id;
else {
int dx = id % sdx;
int dy = id / sdx;
if(mirrored)
dy = -dy, dx += sdx;
if(tmflags() & TF_SIMPLE)
return pair_to_vec(dx, dy);
else
return pair_to_vec(- 2 * dx - (dy & 1), 3 * dy);
}
}
pair<int, bool> vec_to_id_mirror(int vec) {
if(tmflags() & TF_SINGLE) {
return {gmod(vec, qty), false};
}
else {
int x, y;
tie(x,y) = vec_to_pair(vec);
bool mirror = false;
if(tmflags() & TF_KLEIN) {
if(tmflags() & TF_WEIRD) {
x = gmod(x, 4 * sdx);
mirror = x > 0 && x <= 2 * sdx;
}
else {
x = gmod(x, 2 * sdx);
mirror = x >= sdx;
}
if(mirror) y = -y;
}
if(tmflags() & TF_WEIRD) {
y /= 3; x = (x + (y&1)) / -2;
}
x = gmod(x, sdx), y = gmod(y, sdy);
return {y * sdx + x, mirror};
}
}
int vec_to_id(int vec) {
return vec_to_id_mirror(vec).first;
}
void torus_test() {
printf("Testing torus vec_to_pair/pair_to_vec...\n");
for(int x=-10; x<=10; x++)
for(int y=-10; y<=10; y++) {
auto p = vec_to_pair(pair_to_vec(x, y));
if(p.first != x || p.second != y)
printf("Failed for (%d,%d) -> [%d] -> (%d,%d)\n", x, y, pair_to_vec(x,y), p.first, p.second);
}
printf("Testing id_to_vec / vec_to_id...\n");
for(int i=0; i < getqty(); i++)
for(int m=0; m< (torus_mode == tmKlein ? 2 : 1); m++)
if(vec_to_id_mirror(id_to_vec(i, m)) != pair<int,bool> (i,m))
printf("Failed for id %d.%d [%d] (%d.%d)\n", i, m, id_to_vec(i,m), vec_to_id(id_to_vec(i,m)), vec_to_id_mirror(id_to_vec(i,m)).second);
}
int tester = addHook(hooks_tests, 0, torus_test);
void activate() {
if(tmflags() & TF_HEX)
ginf[gTorus].vertex = 3, ginf[gTorus].sides = 6;
else
ginf[gTorus].vertex = 4, ginf[gTorus].sides = 4;
}
}
int decodeId(heptagon* h);
heptagon* encodeId(int id);
int euclid_getvec(int dx, int dy) {
if(torus) return torusconfig::getvec(dx, dy);
else return pair_to_vec(dx, dy);
}
template<class T> void build_euclidean_moves(cell *c, int vec, const T& builder) {
int x, y;
tie(x,y) = vec_to_pair(vec);
c->type = a4 ? (nontruncated || ((x^y^1) & 1) ? 4 : 8) : 6;
if(c->type == 4) {
int m = nontruncated ? 1 : 2;
builder(euclid_getvec(+1,+0), 0, 2 * m);
builder(euclid_getvec(+0,+1), 1, 3 * m);
builder(euclid_getvec(-1,+0), 2, 0 * m);
builder(euclid_getvec(+0,-1), 3, 1 * m);
}
else if(c->type == 8) {
builder(euclid_getvec(+1,+0), 0, 2);
builder(euclid_getvec(+1,+1), 1, 5);
builder(euclid_getvec(+0,+1), 2, 3);
builder(euclid_getvec(-1,+1), 3, 7);
builder(euclid_getvec(-1,+0), 4, 0);
builder(euclid_getvec(-1,-1), 5, 1);
builder(euclid_getvec(+0,-1), 6, 1);
builder(euclid_getvec(+1,-1), 7, 3);
}
else /* 6 */ {
builder(euclid_getvec(+1,+0), 0, 3);
builder(euclid_getvec(+0,+1), 1, 4);
builder(euclid_getvec(-1,+1), 2, 5);
builder(euclid_getvec(-1,+0), 3, 0);
builder(euclid_getvec(+0,-1), 4, 1);
builder(euclid_getvec(+1,-1), 5, 2);
}
}
struct hrmap_torus : hrmap {
vector<cell*> all;
@ -229,25 +404,27 @@ struct hrmap_torus : hrmap {
hrmap_torus() {
using namespace torusconfig;
all.resize(qty);
for(int i=0; i<qty; i++) {
all[i] = newCell(6, NULL);
all[i]->master = encodeId(i);
int q = getqty();
all.resize(q);
for(int i=0; i<q; i++) {
all[i] = newCell(8, encodeId(i));
}
dx %= qty;
dy %= qty;
for(int i=0; i<qty; i++) {
all[i]->mov[0] = all[(i+dx+2*qty)%qty];
all[i]->mov[1] = all[(i+dy+2*qty)%qty];
all[i]->mov[2] = all[(i+dy-dx+2*qty)%qty];
all[i]->mov[3] = all[(i-dx+2*qty)%qty];
all[i]->mov[4] = all[(i-dy+2*qty)%qty];
all[i]->mov[5] = all[(i-dy+dx+2*qty)%qty];
for(int j=0; j<6; j++)
tsetspin(all[i]->spintable, j, (j+3) % 6);
for(int i=0; i<q; i++) {
int iv = id_to_vec(i);
build_euclidean_moves(all[i], iv, [&] (int delta, int d, int d2) {
auto im = vec_to_id_mirror(iv + delta);
all[i]->mov[d] = all[im.first];
tsetspin(all[i]->spintable, d, im.second);
});
}
for(cell *c: all) for(int d=0; d<c->type; d++) {
cell *c2 = c->mov[d];
for(int d2=0; d2<c2->type; d2++)
if(c2->mov[d2] == c)
tsetspin(c->spintable, d, d2 + (8 * c->spin(d)));
}
celllister cl(gamestart(), 100, 100000000, NULL);
dists.resize(qty);
dists.resize(q);
for(int i=0; i<size(cl.lst); i++)
dists[decodeId(cl.lst[i]->master)] = cl.dists[i];
}
@ -257,27 +434,20 @@ struct hrmap_torus : hrmap {
}
};
int toridMod(int id) {
using namespace torusconfig;
id %= qty; if(id < 0) id += qty;
return id;
}
hrmap_torus *torusmap() {
return dynamic_cast<hrmap_torus*> (currentmap);
}
cell *getTorusId(int id) {
/* cell *getTorusId(int id) {
hrmap_torus *cur = torusmap();
if(!cur) return NULL;
return cur->all[toridMod(id)];
}
return cur->all[id];
} */
struct hrmap_euclidean : hrmap {
cell *gamestart() {
return euclideanAtCreate(0,0);
return euclideanAtCreate(0);
}
struct euclideanSlab {
@ -299,8 +469,10 @@ struct hrmap_euclidean : hrmap {
euclidean[y][x] = NULL;
}
cell*& at(eucoord x, eucoord y) {
euclideanSlab*& slab = euclidean[y>>8][x>>8];
cell*& at(int vec) {
auto p = vec_to_pair(vec);
int x = p.first, y = p.second;
euclideanSlab*& slab = euclidean[(y>>8)&255][(x>>8)&255];
if(!slab) slab = new hrmap_euclidean::euclideanSlab;
return slab->a[y&255][x&255];
}
@ -317,30 +489,43 @@ struct hrmap_euclidean : hrmap {
}
};
cellwalker vec_to_cellwalker(int vec) {
if(!torus)
return cellwalker(euclideanAtCreate(vec), 0, false);
else {
hrmap_torus *cur = torusmap();
if(!cur) return cellwalker(NULL, 0);
auto p = torusconfig::vec_to_id_mirror(vec);
return cellwalker(cur->all[p.first], 0, p.second);
}
}
int cellwalker_to_vec(cellwalker cw) {
int id = decodeId(cw.c->master);
if(!torus) return id;
return torusconfig::id_to_vec(id, cw.mirrored);
}
int cell_to_vec(cell *c) {
int id = decodeId(c->master);
if(!torus) return id;
return torusconfig::id_to_vec(id, false);
}
auto cell_to_pair(cell *c) {
return vec_to_pair(cell_to_vec(c));
}
union heptacoder {
heptagon *h;
struct { eucoord x; eucoord y; } c;
int id;
};
void decodeMaster(heptagon *h, eucoord& x, eucoord& y) {
if(torus) { printf("decodeMaster on torus\n"); exit(1); }
heptacoder u;
u.h = h; x = u.c.x; y = u.c.y;
}
int decodeId(heptagon* h) {
heptacoder u;
u.h = h; return u.id;
}
heptagon* encodeMaster(eucoord x, eucoord y) {
if(torus) { printf("encodeMaster on torus\n"); exit(1); }
heptacoder u;
u.c.x = x; u.c.y = y;
return u.h;
}
heptagon* encodeId(int id) {
heptacoder u;
u.id = id;
@ -528,11 +713,10 @@ cell *createMov(cell *c, int d) {
}
if(euclid && !c->mov[d]) {
eucoord x, y;
decodeMaster(c->master, x, y);
int id = decodeId(c->master);
for(int dx=-1; dx<=1; dx++)
for(int dy=-1; dy<=1; dy++)
euclideanAtCreate(x+dx, y+dy);
euclideanAtCreate(id + pair_to_vec(dx, dy));
if(!c->mov[d]) { printf("fail!\n"); }
}
@ -597,43 +781,18 @@ void eumerge(cell* c1, cell *c2, int s1, int s2) {
// map<pair<eucoord, eucoord>, cell*> euclidean;
cell*& euclideanAt(eucoord x, eucoord y) {
cell*& euclideanAt(int vec) {
if(torus) { printf("euclideanAt called\n"); exit(1); }
hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap);
return euc->at(x, y);
return euc->at(vec);
}
cell*& euclideanAtCreate(eucoord x, eucoord y) {
cell*& c = euclideanAt(x,y);
cell*& euclideanAtCreate(int vec) {
cell*& c = euclideanAt(vec);
if(!c) {
c = newCell(a4 ? (nontruncated || ((x^y^1) & 1) ? 4 : 8) : 6, NULL);
c->master = encodeMaster(x,y);
euclideanAt(x,y) = c;
if(c->type == 4) {
int m = nontruncated ? 1 : 2;
eumerge(c, euclideanAt(x+1,y), 0, 2 * m);
eumerge(c, euclideanAt(x,y+1), 1, 3 * m);
eumerge(c, euclideanAt(x-1,y), 2, 0 * m);
eumerge(c, euclideanAt(x,y-1), 3, 1 * m);
}
else if(c->type == 8) {
eumerge(c, euclideanAt(x+1,y), 0, 2);
eumerge(c, euclideanAt(x+1,y+1), 1, 5);
eumerge(c, euclideanAt(x,y+1), 2, 3);
eumerge(c, euclideanAt(x-1,y+1), 3, 7);
eumerge(c, euclideanAt(x-1,y), 4, 0);
eumerge(c, euclideanAt(x-1,y-1), 5, 1);
eumerge(c, euclideanAt(x,y-1), 6, 1);
eumerge(c, euclideanAt(x+1,y-1), 7, 3);
}
else /* 6 */ {
eumerge(c, euclideanAt(x+1,y), 0, 3);
eumerge(c, euclideanAt(x,y+1), 1, 4);
eumerge(c, euclideanAt(x-1,y+1), 2, 5);
eumerge(c, euclideanAt(x-1,y), 3, 0);
eumerge(c, euclideanAt(x,y-1), 4, 1);
eumerge(c, euclideanAt(x+1,y-1), 5, 2);
}
c = newCell(8, encodeId(vec));
euclideanAt(vec) = c;
build_euclidean_moves(c, vec, [c,vec] (int delta, int d, int d2) { eumerge(c, euclideanAt(vec + delta), d, d2); });
}
return c;
}
@ -735,7 +894,7 @@ void verifycells(heptagon *at) {
verifycell(at->c7);
}
int eudist(short sx, short sy) {
int eudist(int sx, int sy) {
int z0 = abs(sx);
int z1 = abs(sy);
if(a4) return z0 + z1;
@ -743,6 +902,11 @@ int eudist(short sx, short sy) {
return max(max(z0,z1), z2);
}
int eudist(int vec) {
auto p = vec_to_pair(vec);
return eudist(p.first, p.second);
}
int compdist(int dx[]) {
int mi = dx[0];
for(int u=0; u<S3; u++) mi = min(mi, dx[u]);
@ -764,9 +928,7 @@ int celldist(cell *c) {
if(euclid) {
if(torus)
return torusmap()->dists[decodeId(c->master)];
eucoord x, y;
decodeMaster(c->master, x, y);
return eudist(x, y);
return eudist(decodeId(c->master));
}
if(sphere) return celldistance(c, currentmap->gamestart());
if(ctof(c)) return c->master->distance;
@ -787,8 +949,8 @@ int euclidAlt(short x, short y);
int celldistAlt(cell *c) {
if(euclid) {
if(torus) return celldist(c);
eucoord x, y;
decodeMaster(c->master, x, y);
int x, y;
tie(x,y) = vec_to_pair(decodeId(c->master));
return euclidAlt(x, y);
}
if(sphere || quotient) {
@ -1046,11 +1208,11 @@ cdata *getEuclidCdata(heptagon *h) {
return &xx;
}
eucoord x, y;
int x, y;
hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap);
if(euc->eucdata.count(h)) return &(euc->eucdata[h]);
decodeMaster(h, x, y);
tie(x,y) = vec_to_pair(decodeId(h));
if(x == 0 && y == 0) {
cdata xx;
@ -1062,14 +1224,14 @@ cdata *getEuclidCdata(heptagon *h) {
while(!((x|y)&ord)) ord <<= 1, bid++;
for(int k=0; k<3; k++) {
eucoord x1 = x + (k<2 ? ord : 0);
eucoord y1 = y - (k>0 ? ord : 0);
int x1 = x + (k<2 ? ord : 0);
int y1 = y - (k>0 ? ord : 0);
if((x1&ord) || (y1&ord)) continue;
eucoord x2 = x - (k<2 ? ord : 0);
eucoord y2 = y + (k>0 ? ord : 0);
int x2 = x - (k<2 ? ord : 0);
int y2 = y + (k>0 ? ord : 0);
cdata *d1 = getEuclidCdata(encodeMaster(x1,y1));
cdata *d2 = getEuclidCdata(encodeMaster(x2,y2));
cdata *d1 = getEuclidCdata(encodeId(pair_to_vec(x1,y1)));
cdata *d2 = getEuclidCdata(encodeId(pair_to_vec(x2,y2)));
cdata xx;
double disp = pow(2, bid/2.) * 6;
@ -1134,11 +1296,8 @@ int celldistance(cell *c1, cell *c2) {
if(euclid) {
if(torus)
return torusmap()->dists[toridMod(decodeId(c1->master)-decodeId(c2->master))];
eucoord x1, y1, x2, y2;
decodeMaster(c1->master, x1, y1);
decodeMaster(c2->master, x2, y2);
return eudist(x1-x2, y1-y2);
return torusmap()->dists[torusconfig::vec_to_id(decodeId(c1->master)-decodeId(c2->master))];
return eudist(decodeId(c1->master) - decodeId(c2->master));
}
if(sphere || quotient == 1) {

View File

@ -1613,7 +1613,7 @@ geometryinfo ginf[gGUARD] = {
{"elliptic", "elliptic", 5, 3, qELLIP, gcSphere, {{SEE_ALL, SEE_ALL}}},
{"Zebra quotient", "Zebra", 7, 3, qZEBRA, gcHyperbolic, {{7, 5}}},
{"field quotient", "field", 7, 3, qFIELD, gcHyperbolic, {{7, 5}}},
{"torus", "torus", 6, 3, qTORUS, gcEuclid, {{7, FORBIDDEN}}},
{"torus/Klein bottle", "torus", 6, 3, qTORUS, gcEuclid, {{7, FORBIDDEN}}},
{"octagons", "oct", 8, 3, 0, gcHyperbolic, {{6, 4}}},
{"four pentagons", "4x5", 5, 4, 0, gcHyperbolic, {{6, 4}}},
{"four hexagons", "4x6", 6, 4, 0, gcHyperbolic, {{5, 3}}},

View File

@ -228,13 +228,27 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu
autocheat = true;
currfp.init(p);
}
else if(argis("-test"))
callhooks(hooks_tests);
else if(argis("-tpar")) {
torusconfig::torus_mode = torusconfig::tmSingle;
shift(); sscanf(args(), "%d,%d,%d",
&torusconfig::qty,
&torusconfig::dx,
&torusconfig::dy
);
}
else if(argis("-tparx")) {
shift(); sscanf(args(), "%d,%d,%d",
(int*) &torusconfig::torus_mode,
&torusconfig::sdx,
&torusconfig::sdy
);
if(torusconfig::torus_mode == torusconfig::tmSingle)
torusconfig::qty = torusconfig::sdx,
torusconfig::dy = torusconfig::sdy;
torusconfig::activate();
}
else if(argis("-cs")) {
shift();
fieldpattern::matrix M = currfp.strtomatrix(args());
@ -345,6 +359,14 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu
PHASEFROM(2);
shift(); whatever = argf(); resetGeometry();
}
else if(argis("-wei")) {
PHASEFROM(2);
shift(); whateveri = argf(); resetGeometry();
}
else if(argis("-wei2")) {
PHASEFROM(2);
shift(); whateveri2 = argf(); resetGeometry();
}
else if(argis("-rch")) {
PHASEFROM(2);
reptilecheat = true; autocheat = true; firstland = laReptile;

View File

@ -12,8 +12,8 @@ namespace whirlwind {
int fzebra3(cell *c) {
if(euclid) {
if(torus) return 0;
eucoord x, y;
decodeMaster(c->master, x, y);
int x, y;
tie(x,y) = cell_to_pair(c);
return 1+((((signed short)(y)+int(50000))/3)%3);
}
if(S7 == 5) return getHemisphere(c, 0) > 0 ? 1 : 2;
@ -809,8 +809,9 @@ namespace clearing {
if(pseudohept(c)) return;
c->monst = moMutant;
eucoord x, y;
decodeMaster(c->master, x, y);
int x, y;
tie(x,y) = cell_to_pair(c);
int xco = x * 2 + y + 1;
c->stuntime = (8-xco/2) & 15;
// 2, 4, 5, 7
@ -2701,8 +2702,8 @@ namespace prairie {
c->LHU.fi.rval = 0;
}
else if(euclid) {
eucoord x, y;
decodeMaster(c->master, x, y);
int x, y;
tie(x,y) = cell_to_pair(c);
c->LHU.fi.rval = (y&15);
}
else if(sphere) {
@ -3391,8 +3392,8 @@ namespace dungeon {
if(euclid) {
if(torus) return;
eucoord x, y;
decodeMaster(c->master, x, y);
int x, y;
tie(x, y) = cell_to_pair(c);
string tab[] = {
".####...",
"L...L...",

View File

@ -30,7 +30,8 @@ movedir joydir;
movedir mousedest;
ld shiftmul = 1;
cell *mouseover, *mouseover2, *lmouseover, *centerover;
cell *mouseover, *mouseover2, *lmouseover;
cellwalker centerover;
ld modist, modist2, centdist;
int lastt;
@ -340,7 +341,7 @@ void handleKeyNormal(int sym, int uni) {
// vid.yshift = 1 - vid.yshift;
// vid.drawmousecircle = true;
}
if(sym == 'm' && canmove && (centerover == cwt.c ? mouseover : centerover))
if(sym == 'm' && canmove && (centerover == cwt ? mouseover : centerover.c))
performMarkCommand(mouseover);
}
@ -351,9 +352,9 @@ void handleKeyNormal(int sym, int uni) {
if(sym == 't' && uni != 'T' && uni != 'T'-64 && canmove) {
if(playermoved && items[itStrongWind]) {
cell *c = whirlwind::jumpDestination(cwt.c);
if(c) centerover = c;
if(c) centerover.c = c;
}
targetRangedOrb(centerover, roKeyboard);
targetRangedOrb(centerover.c, roKeyboard);
sym = 0; uni = 0;
}
}

View File

@ -5795,8 +5795,7 @@ void activateSafety(eLand l) {
firstland = l;
safetyland = l;
safetyseed = time(NULL);
for(int i=0; i<65536; i++) euland[i] = laNone;
euland[0] = euland[1] = firstland;
clear_euland(firstland);
safety = true; avengers = 0;
clearMemory();
initcells();

View File

@ -84,20 +84,76 @@ void showQuotientConfig() {
dialog::display();
}
bool torus_chamfer;
void showTorusConfig() {
cmode = sm::SIDE | sm::TORUSCONFIG;
gamescreen(2);
dialog::init(XLAT("advanced configuration"));
dialog::addSelItem(XLAT("number of cells (n)"), its(torusconfig::newqty), 'n');
dialog::addSelItem(XLAT("cell bottom-right from 0 (d)"), its(torusconfig::newdy), 'd');
auto& mode = torusconfig::tmodes[torusconfig::newmode];
if(torusconfig::newqty % 3)
dialog::addInfo("best if n is divisible by 3", 0x808080);
dialog::addSelItem(XLAT("mode"), XLAT(mode.name), 'm');
bool single = (mode.flags & torusconfig::TF_SINGLE);
bool square = (mode.flags & torusconfig::TF_SQUARE);
bool simple = (mode.flags & torusconfig::TF_SIMPLE);
if(single) {
dialog::addSelItem(XLAT("number of cells (n)"), its(torusconfig::newqty), 'n');
if(torusconfig::TF_HEX)
dialog::addSelItem(XLAT("cell bottom-right from 0 (d)"), its(torusconfig::newdy), 'd');
else
dialog::addSelItem(XLAT("cell below 0 (d)"), its(torusconfig::newdy), 'd');
}
else {
if(torusconfig::newsdx < 1) torusconfig::newsdx = 1;
if(torusconfig::newsdy < 1) torusconfig::newsdy = 1;
dialog::addSelItem(XLAT("width (x)"), its(torusconfig::newsdx), 'x');
dialog::addSelItem(XLAT("height (y)"), its(torusconfig::newsdy), 'y');
}
if((torusconfig::newdy + 999999) % 3 != 2)
dialog::addInfo("best if d+1 is divisible by 3", 0x808080);
if(square) dialog::addBoolItem(XLAT("chamfering"), !torus_chamfer, 't');
else dialog::addInfo("", 100);
int valid = 2;
if(single) {
if(square) {
dialog::addInfo("this mode has bad patterns", 0x808080), valid = 1;
if(!torus_chamfer && valid == 1)
dialog::addInfo("incompatible with chamfering", 0x808080), valid = 0;
}
else {
if(torusconfig::newqty % 3)
dialog::addInfo(XLAT("best if %1 is divisible by %2", "n", "3"), 0x808080), valid = 1;
if((torusconfig::newdy + 999999) % 3 != 2)
dialog::addInfo(XLAT("best if %1 is divisible by %2", "d+1", "3"), 0x808080), valid = 1;
}
}
else {
if(square) {
if(torusconfig::newsdx & 1)
dialog::addInfo(XLAT("best if %1 is divisible by %2", "x", "2"), 0x808080), valid = 1;
if(torusconfig::newsdy & 1)
dialog::addInfo(XLAT("best if %1 is divisible by %2", "y", "2"), 0x808080), valid = 1;
if(!torus_chamfer && valid == 1)
dialog::addInfo("incompatible with chamfering", 0x808080), valid = 0;
}
else if(simple) {
if(torusconfig::newsdx & 1)
dialog::addInfo(XLAT("best if %1 is divisible by %2", "x", "3"), 0x808080), valid = 1;
if(torusconfig::newsdy & 1)
dialog::addInfo(XLAT("best if %1 is divisible by %2", "y", "3"), 0x808080), valid = 1;
}
else {
if(torusconfig::newsdx & 1)
dialog::addInfo(XLAT("best if %1 is divisible by %2", "x", "3"), 0x808080), valid = 1;
if(torusconfig::newsdy & 1)
dialog::addInfo(XLAT("best if %1 is divisible by %2", "y", "2"), 0x808080), valid = 0;
}
}
dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z');
@ -108,22 +164,39 @@ void showTorusConfig() {
dialog::addItem("activate", 'a');
dialog::addItem("default", 'c');
keyhandler = [] (int sym, int uni) {
if(uni == 'n')
keyhandler = [=] (int sym, int uni) {
if(uni == 'm') {
int i = torusconfig::newmode + 1;
if(i >= size(torusconfig::tmodes)) i = 0;
torusconfig::newmode = torusconfig::eTorusMode(i);
}
else if(uni == 'n' && single)
dialog::editNumber(torusconfig::newqty, 0, 1000, 3, torusconfig::def_qty, XLAT("number of cells (n)"), "");
else if(uni == 'd')
dialog::editNumber(torusconfig::newdy, -1000, 1000, 3, -torusconfig::def_dy, XLAT("cell bottom-right from 0 (d)"), "");
else if((uni == 'a' || uni == '\n') && torusconfig::newqty >= 3 && abs(torusconfig::newdy) < torusconfig::newqty ) {
targetgeometry = gEuclid; restartGame('g');
else if(uni == 'd' && single)
dialog::editNumber(torusconfig::newdy, -1000, 1000, 3, -torusconfig::def_dy, XLAT("cell below 0 (d)"), "");
else if(uni == 'x' && !single)
dialog::editNumber(torusconfig::newsdx, 0, 1000, square ? 2 : 3, 12, XLAT("width (x)"), "");
else if(uni == 'y' && !single)
dialog::editNumber(torusconfig::newsdy, 0, 1000, square ? 2 : simple ? 3 : 2, 12, XLAT("height (y)"), "");
else if(uni == 't')
torus_chamfer = !torus_chamfer;
else if((uni == 'a' || uni == '\n') && torusconfig::newqty >= 3 && valid) {
targetgeometry = gNormal; restartGame('g', false, true);
torusconfig::torus_mode = torusconfig::newmode;
torusconfig::qty = torusconfig::newqty;
torusconfig::dy = torusconfig::newdy;
targetgeometry = gTorus; restartGame('g');
torusconfig::sdx = torusconfig::newsdx;
torusconfig::sdy = torusconfig::newsdy;
torusconfig::activate();
if((square && torus_chamfer) != nontruncated) restartGame('7', false, true);
targetgeometry = gTorus; restartGame('g', false, true);
}
else if(uni == 'c') {
targetgeometry = gEuclid; restartGame('g');
targetgeometry = gEuclid; restartGame('g', false, true);
torusconfig::torus_mode = torusconfig::tmSingle;
torusconfig::qty = torusconfig::def_qty;
torusconfig::dy = torusconfig::def_dy;
targetgeometry = gTorus; restartGame('g');
targetgeometry = gTorus; restartGame('g', false, true);
}
else if(uni == 'z') editScale();
#if CAP_RUG
@ -263,6 +336,10 @@ void showEuclideanMenu() {
if(torus)
torusconfig::newdy = torusconfig::dy,
torusconfig::newqty = torusconfig::qty,
torusconfig::newsdx = torusconfig::sdx,
torusconfig::newsdy = torusconfig::sdy,
torusconfig::newmode = torusconfig::torus_mode,
torus_chamfer = nontruncated,
pushScreen(showTorusConfig);
if(quotient==2) pushScreen(showQuotientConfig);
}

View File

@ -3284,12 +3284,12 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
mouseover2 = c;
}
if(!torus) {
if(!euclid) {
double dfc = euclid ? intval(VC0, C0) : VC0[2];
if(dfc < centdist) {
centdist = dfc;
centerover = c;
centerover = cellwalker(c, spinv, mirrored);
}
}
@ -3380,10 +3380,19 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
if(cmode & sm::TORUSCONFIG) {
using namespace torusconfig;
int cd = torus_cx * dx + torus_cy * newdy;
cd %= newqty; if(cd<0) cd += newqty;
string label = its(cd);
queuestr(V, cd ? .2 : .6, label, cd == 0 ? 0xFFFF0040 : 0xFFFFFFD0, 1);
string label;
bool small;
if(tmflags() & TF_SINGLE) {
int cd = torus_cx * dx + torus_cy * newdy;
cd %= newqty; if(cd<0) cd += newqty;
label = its(cd);
small = cd;
}
else {
small = true;
label = its(torus_cx) + "," + its(torus_cy);
}
queuestr(V, small ? .2 : .6, label, small ? 0xFFFFFFD0 : 0xFFFF0040, 1);
}
asciicol = wcol;
@ -4744,8 +4753,8 @@ void drawMarkers() {
#if CAP_MODEL
m = netgen::mode == 0;
#endif
if(centerover && !playermoved && m && !conformal::on)
queuecircleat(centerover, .70 - .06 * sin(ticks/200.0),
if(centerover.c && !playermoved && m && !conformal::on)
queuecircleat(centerover.c, .70 - .06 * sin(ticks/200.0),
darkena(int(175 + 25 * sin(ticks / 200.0)), 0, 0xFF));
if(multi::players > 1 || multi::alwaysuse) for(int i=0; i<numplayers(); i++) {
@ -4925,7 +4934,7 @@ void drawthemap() {
modist2 = 1e20; mouseover2 = NULL;
centdist = 1e20;
if(!torus) centerover = NULL;
if(!euclid) centerover.c = NULL;
for(int i=0; i<multi::players; i++) {
multi::ccdist[i] = 1e20; multi::ccat[i] = NULL;
@ -5406,7 +5415,7 @@ void restartGraph() {
linepatterns::clearAll();
if(currentmap) {
if(euclid) {
centerover = torus ? getTorusId(0) : euclideanAtCreate(0,0);
centerover = vec_to_cellwalker(0);
}
else {
viewctr.h = currentmap->getOrigin();
@ -5419,7 +5428,7 @@ void restartGraph() {
auto graphcm = addHook(clearmemory, 0, [] () {
DEBB(DF_INIT, (debugfile,"clear graph memory\n"));
mouseover = centerover = lmouseover = NULL;
mouseover = centerover.c = lmouseover = NULL;
for(int i=0; i<ANIMLAYERS; i++) animations[i].clear();
gmatrix.clear(); gmatrix0.clear();
flashes.clear();
@ -5505,7 +5514,7 @@ void drawBug(const cellwalker& cw, int col) {
}
cell *viewcenter() {
if(euclid) return centerover;
if(euclid) return centerover.c;
else return viewctr.h->c7;
}

View File

@ -650,7 +650,7 @@ int windtotal;
void describeMouseover() {
DEBB(DF_GRAPH, (debugfile,"describeMouseover\n"));
cell *c = mousing ? mouseover : playermoved ? NULL : centerover;
cell *c = mousing ? mouseover : playermoved ? NULL : centerover.c;
string& out = mouseovers;
if(!c || instat || getcstat != '-') { }
else if(c->wall != waInvisibleFloor) {
@ -701,12 +701,10 @@ void describeMouseover() {
out += " " + describeRPM(c->land);
if(euclid && cheater) {
if(torus) {
out += " ("+its(decodeId(c->master))+")";
}
else {
eucoord x, y;
decodeMaster(c->master, x, y);
out += " ("+its(cell_to_vec(c))+")";
if(!torus || torusconfig::torus_mode != torusconfig::tmSingle) {
int x, y;
tie(x,y) = cell_to_pair(c);
out += " ("+its(short(x))+","+its(short(y))+")";
}
}

13
hyper.h
View File

@ -541,7 +541,7 @@ void drawCircle(int x, int y, int size, int color);
void fixcolor(int& col);
int displaydir(cell *c, int d);
hyperpoint gethyper(ld x, ld y);
void resetview(); extern heptspin viewctr; extern cell *centerover;
void resetview(); extern heptspin viewctr; extern cellwalker centerover;
void drawthemap();
void drawfullmap();
bool displaystr(int x, int y, int shift, int size, const char *str, int color, int align);
@ -829,7 +829,6 @@ bool isElemental(eLand l);
int coastval(cell *c, eLand base);
int getHauntedDepth(cell *c);
eLand randomElementalLand();
extern eLand euland[65536];
bool notDippingForExtra(eItem i, eItem x);
void placePrizeOrb(cell *c);
void wandering();
@ -1388,6 +1387,7 @@ void movecost(cell* from, cell *to);
void checkmove();
transmatrix eumove(ld x, ld y);
transmatrix eumove(int vec);
transmatrix eumovedir(int d);
int reptilemax();
@ -1690,7 +1690,7 @@ template<class T, class U> int addHook(hookset<T>*& m, int prio, const U& hook)
return 0;
}
extern purehookset hooks_frame, hooks_stats, clearmemory, hooks_config;
extern purehookset hooks_frame, hooks_stats, clearmemory, hooks_config, hooks_tests;
template<class T, class... U> void callhooks(hookset<T> *h, U... args) {
if(h) for(auto& p: *h) p.second(args...);
@ -2252,9 +2252,6 @@ struct celllister {
};
typedef unsigned short eucoord;
void decodeMaster(heptagon *h, eucoord& x, eucoord& y);
hrmap *newAltMap(heptagon *o);
#define currfp fieldpattern::getcurrfp()
@ -2423,3 +2420,7 @@ transmatrix cview();
extern string truncatenames[2];
extern bool need_mouseh;
extern int whateveri, whateveri2;
void clear_euland(eLand first);

View File

@ -395,6 +395,12 @@ transmatrix eumove(ld x, ld y) {
return Mat;
}
transmatrix eumove(int vec) {
int x, y;
tie(x,y) = vec_to_pair(vec);
return eumove(x, y);
}
transmatrix eumovedir(int d) {
if(a4) {
d = d & 3;
@ -426,16 +432,10 @@ ld matrixnorm(const transmatrix& Mat) {
void drawEuclidean() {
DEBB(DF_GRAPH, (debugfile,"drawEuclidean\n"));
sphereflip = Id;
eucoord px=0, py=0;
if(!centerover) centerover = cwt.c;
if(!centerover.c) centerover = cwt;
// printf("centerover = %p player = %p [%d,%d]-[%d,%d]\n", lcenterover, cwt.c,
// mindx, mindy, maxdx, maxdy);
int pid;
const bool b = torus;
if(b)
pid = decodeId(centerover->master);
else
decodeMaster(centerover->master, px, py);
int pvec = cellwalker_to_vec(centerover);
int minsx = mindx-1, maxsx=maxdx+1, minsy=mindy-1, maxsy=maxdy+1;
mindx=maxdx=mindy=maxdy=0;
@ -451,25 +451,16 @@ void drawEuclidean() {
torusconfig::torus_cx = dx;
torusconfig::torus_cy = dy;
reclevel = eudist(dx, dy);
cell *c;
transmatrix Mat;
if(b) {
reclevel = eudist(dx, dy);
c = getTorusId(pid+torusconfig::dx*dx+torusconfig::dy*dy);
Mat = eumove(dx,dy);
}
else {
eucoord x = dx+px;
eucoord y = dy+py;
c = euclideanAt(x,y);
Mat = eumove(x, y);
}
if(!c) continue;
cellwalker cw = vec_to_cellwalker(pvec + euclid_getvec(dx, dy));
transmatrix Mat = eumove(dx,dy);
if(!cw.c) continue;
Mat = View0 * Mat;
if(torus) {
if(true) {
ld locald = matrixnorm(Mat);
if(locald < centerd) centerd = locald, centerover = c, View = View0 * eumove(dx, dy);
if(locald < centerd) centerd = locald, centerover = cw, View = View0 * eumove(dx, dy);
}
// Mat[0][0] = -1;
@ -488,8 +479,8 @@ void drawEuclidean() {
if(dy > maxdy) maxdy = dy;
}
if(cx >= -cellrad && cy >= -cellrad && cx < vid.xres+cellrad && cy < vid.yres+cellrad)
if(dodrawcell(c)) {
drawcell(c, Mat, 0, false);
if(dodrawcell(cw.c)) {
drawcell(cw.c, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored);
}
}
}
@ -596,7 +587,7 @@ void resetview() {
if(!euclid)
viewctr.h = cwt.c->master,
viewctr.spin = cwt.spin;
else centerover = cwt.c;
else centerover = cwt;
// SDL_LockSurface(s);
// SDL_UnlockSurface(s);
}

View File

@ -324,8 +324,8 @@ void giantLandSwitch(cell *c, int d, cell *from) {
c->wall = waCavefloor;
}
else if(euclid) {
eucoord x, y;
decodeMaster(c->master, x, y);
int x, y;
tie(x,y) = cell_to_pair(c);
if(((y-2)&7) < 4) c->wall = waCavewall;
else c->wall = waCavefloor;
}
@ -407,10 +407,9 @@ void giantLandSwitch(cell *c, int d, cell *from) {
v = hrand(100) < 25 ? 24 : 16;
}
else if(euclid) {
eucoord x, y;
decodeMaster(c->master, x, y);
int y0 = ((short)y) % 6;
if(y0<0) y0+=6;
int x, y;
tie(x,y) = cell_to_pair(c);
int y0 = gmod(y, 6);
if(y0 == 3 || y0 == 4) v=24; else v=0;
}
else v = emeraldval(c);
@ -466,8 +465,8 @@ void giantLandSwitch(cell *c, int d, cell *from) {
if(d==8) {
if(torus) ;
else if(euclid) {
eucoord x, y;
decodeMaster(c->master, x, y);
int x,y;
tie(x,y) = cell_to_pair(c);
if(y&1) c->wall = waTrapdoor;
else c->wall = waNone;
}
@ -486,9 +485,9 @@ void giantLandSwitch(cell *c, int d, cell *from) {
if(d==8) {
if(torus) ;
else if(euclid) {
eucoord x, y;
decodeMaster(c->master, x, y);
int dy = ((short)y)%3; if(dy<0) dy += 3;
int x,y;
tie(x,y) = cell_to_pair(c);
int dy = gmod(y, 3);
if(dy == 1) c->wall = waVinePlant;
}
else {
@ -1033,9 +1032,9 @@ void giantLandSwitch(cell *c, int d, cell *from) {
if(pid == torusconfig::qty*2/3) c->wall = waGrounded;
}
else if(euclid) {
eucoord x, y;
decodeMaster(c->master, x, y);
if(short(x+1)%3 == 0 && short(y)%3 == 0) {
int x,y;
tie(x,y) = cell_to_pair(c);
if((x+1)%3 == 0 && y%3 == 0) {
if(hrand(100) < 50)
c->wall = hrand(2) ? waCharged : waGrounded;
}
@ -1043,8 +1042,8 @@ void giantLandSwitch(cell *c, int d, cell *from) {
bool sand = false;
for(int i=0; i<c->type; i++) {
createMov(c, i);
decodeMaster(c->mov[i]->master, x, y);
if(short(x+1)%3 == 0 && short(y)%3 == 0) sand = true;
tie(x,y) = cell_to_pair(c->mov[i]);
if((x+1)%3 == 0 && (y)%3 == 0) sand = true;
}
if(sand && hrand(100) < 20)
c->wall = waSandstone;

View File

@ -102,7 +102,7 @@ namespace mapstream {
save(fgeomextras[current_extra].current_prime_id);
}
}
addToQueue(bounded ? currentmap->gamestart() : cwt.c->master->c7);
addToQueue((bounded || euclid) ? currentmap->gamestart() : cwt.c->master->c7);
for(int i=0; i<size(cellbyid); i++) {
cell *c = cellbyid[i];
if(i) {

View File

@ -674,7 +674,7 @@ namespace netgen {
}
if(!created) {
View = Id;
if(centerover) viewctr.h = centerover->master;
if(centerover.c) viewctr.h = centerover.c->master;
else viewctr.h = cwt.c->master;
playermoved = false;
dataFromHR();
@ -690,7 +690,7 @@ namespace netgen {
}
if(uni == 's') {
View = Id;
if(centerover) viewctr.h = centerover->master;
if(centerover.c) viewctr.h = centerover.c->master;
else viewctr.h = cwt.c->master;
playermoved = false;
}

View File

@ -3,25 +3,21 @@
// Copyright (C) 2011-2017 Zeno Rogue, see 'hyper.cpp' for details
int eupattern(cell *c) {
int v = cell_to_vec(c);
if(a4) {
if(torus) return (decodeId(c->master)*2) % 3;
eucoord x, y;
decodeMaster(c->master, x, y);
int x, y;
tie(x,y) = vec_to_pair(v);
return ((x&1) + 2*(y&1)) % 3;
}
if(torus) return (decodeId(c->master)*2) % 3;
eucoord x, y;
decodeMaster(c->master, x, y);
short z = (short(y+2*x))%3;
z %= 3;
if(z<0) z += 3;
return z;
else {
return gmod(v*2, 3);
}
}
int eupattern4(cell *c) {
if(torus) return 0;
eucoord x, y;
decodeMaster(c->master, x, y);
int v = cell_to_vec(c);
int x, y;
tie(x,y) = vec_to_pair(v);
return (x&1) + ((y&1)) * 2;
}
@ -58,14 +54,14 @@ unsigned bitmajority(unsigned a, unsigned b, unsigned c) {
}
int eufifty(cell *c) {
eucoord x, y;
if(torus) {
if(c->land == laWildWest) return decodeId(c->master) % 37;
else return decodeId(c->master) % 27;
if(c->land == laWildWest) return cell_to_vec(c) % 37;
else return cell_to_vec(c) % 27;
}
decodeMaster(c->master, x, y);
int ix = short(x) + 99999 + short(y);
int iy = short(y) + 99999;
int x, y;
tie(x,y) = cell_to_pair(c);
int ix = x + 99999 + y;
int iy = y + 99999;
if(c->land == laWildWest)
return (ix + iy * 26 + 28) % 37;
else {
@ -314,12 +310,7 @@ int fieldval_uniq(cell *c) {
return decodeId(c->master);
}
else if(euclid) {
eucoord x, y;
decodeMaster(c->master, x, y);
int i = (short int)(x) * torusconfig::dx + (short int)(y) * torusconfig::dy;
i %= torusconfig::qty;
if(i<0) i += torusconfig::qty;
return i;
return torusconfig::vec_to_id(cell_to_vec(c));
}
if(ctof(c)) return c->master->fieldval/S7;
else {

12
rug.cpp
View File

@ -664,10 +664,10 @@ void preset(rugpoint *m) {
double c2 = b->edges[k2].len/blen;
double cz = (c1*c1-c2*c2+1) / 2;
double ch = sqrt(c2*c2 - cz*cz);
double ch = sqrt(c2*c2 - cz*cz + 1e-10);
double az = (a1*a1-a2*a2+1) / 2;
double ah = sqrt(a2*a2 - az*az);
double ah = sqrt(a2*a2 - az*az + 1e-10);
// c->h = a->h + (b->h-a->h) * cz + ch * ort
hyperpoint ort = (c->flat - a->flat - cz * (b->flat-a->flat)) / ch;
@ -675,14 +675,17 @@ void preset(rugpoint *m) {
// m->h = a->h + (b->h-a->h) * az - ah * ort
hyperpoint res = a->flat + (b->flat-a->flat) * az - ah * ort;
for(int i=0; i<3; i++) h[i] += res[i];
h += res;
preset_points.emplace_back(hypot(blen * (ah+ch), blen * (az-cz)), c);
q++;
printf("A %lf %lf %lf %lf C %lf %lf %lf %lf\n", a1, a2, az, ah, c1, c2, cz, ch);
}
}
if(q>0) for(int i=0; i<3; i++) m->flat[i] = h[i]/q;
if(q>0) m->flat = h/q;
printf("preset (%d) -> %s\n", q, display(m->flat));
}
ld sse(hyperpoint h) {
@ -1164,6 +1167,7 @@ void actDraw() {
Uint8 *keystate = SDL_GetKeyState(NULL);
int qm = 0;
double alpha = (ticks - lastticks) / 1000.0;
alpha /= 2.5;
lastticks = ticks;
transmatrix t = Id;

View File

@ -3328,19 +3328,11 @@ transmatrix &ggmatrix(cell *c) {
if(t[2][2] == 0) {
if(torus) {
forCellIdEx(c2, i, c)
if(celldistance(c2, centerover) < celldistance(c, centerover))
if(celldistance(c2, centerover.c) < celldistance(c, centerover.c))
t = ggmatrix(c2) * eumovedir(3+i);
}
else if(euclid) {
eucoord xh, yh, xc, yc;
decodeMaster(c->master, xh, yh);
decodeMaster(centerover->master, xc, yc);
short xd(xh-xc), yd(yh-yc);
t = gmatrix[centerover] * eumove(xd, yd);
/* printf("H[%d,%d] C[%d,%d] ", int(xh),int(yh), int(xc),int(yc));
printf("%d,%d t = \n", xd, yd); display(t);
printf("gmatrix0 = \n");
display(gmatrix0[c]); */
t = gmatrix[centerover.c] * eumove(cell_to_vec(c) - cellwalker_to_vec(centerover));
}
else
t = actualV(viewctr, cview()) * calc_relative_matrix(c, viewctr.h);

View File

@ -150,11 +150,11 @@ void initgame() {
yendor::lastchallenge = yendor::challenge;
yendor::init(2);
for(int i=0; i<65536; i++) euland[i] = laNone;
clear_euland(specialland);
if(euclid && specialland == laPrincessQuest) {
cell *c = euclideanAtCreate(EPX, EPY);
cell *c = euclideanAtCreate(pair_to_vec(EPX, EPY));
princess::generating = true;
c->land = laPalace;
for(int j=BARLEV; j>=0; j--) setdist(c, j, NULL);

View File

@ -641,7 +641,7 @@ void init_textureconfig() {
addsaver(patterns::whichPattern, "pattern", 0);
addsaver(patterns::subpattern_flags, "pattern flags", 0);
cell *ctr = euclid ? centerover : viewctr.h->c7;
cell *ctr = euclid ? centerover.c : viewctr.h->c7;
si_save = patterns::getpatterninfo0(ctr);
addsaver(si_save.id, "center type", 1);

View File

@ -55,6 +55,11 @@ int gcd(int i, int j) {
return i ? gcd(j%i, i) : j;
}
int gmod(int i, int j) {
i %= j; if(i<0) i += j;
return i;
}
// debug utilities
extern FILE *debugfile;
@ -116,3 +121,6 @@ void profile_info() {
#define profile_info()
#endif
int whateveri, whateveri2;
purehookset hooks_tests;