diff --git a/bigstuff.cpp b/bigstuff.cpp index 4c42ce72..cea301ba 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -105,8 +105,10 @@ bool grailWasFound(cell *c) { void generateAlts(heptagon *h, int levs, bool link_cdata) { if(!h->alt) return; - preventbarriers(h->c7); - for(int i=0; ic7->mov[i]); + if(!irr::on) { + preventbarriers(h->c7); + for(int i=0; ic7->mov[i]); + } if(gp::on) for(int i=0; ic7); for(int i=0; imov[i], c, i))); + if(gp::on || irr::on) return hdist0(tC0(shmup::calc_relative_matrix(c->mov[i], c, i))); return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf; } diff --git a/cell.cpp b/cell.cpp index b95b0660..40760c95 100644 --- a/cell.cpp +++ b/cell.cpp @@ -73,7 +73,10 @@ hrmap_hyperbolic::hrmap_hyperbolic() { h.alt = NULL; h.distance = 0; isnonbitrunc = nonbitrunc; - h.c7 = newCell(S7, origin); + if(irr::on) + irr::link_start(origin); + else + h.c7 = newCell(S7, origin); } // --- spherical geometry --- @@ -107,7 +110,7 @@ struct hrmap_spherical : hrmap { h.spintable = 0; h.fieldval = i; for(int i=0; isetspin(2, 3-i); } } + + if(irr::on) { + irr::link_start(dodecahedron[0]); + for(int i=0; ifieldval = S7*i; h->rval0 = h->rval1 = 0; h->cdata = NULL; h->distance = 0; - h->c7 = newCell(S7, h); + if(!irr::on) h->c7 = newCell(S7, h); } for(int j=0; jmove[j]->alt = createStep(allh[i]->alt, j); */ } + if(irr::on) { + irr::link_start(allh[0]); + for(int i=0; imov[d]) return c->mov[d]; + else if(irr::on) { + irr::link_cell(c, d); + } else if(nonbitrunc && gp::on) { gp::extend_map(c, d); if(!c->mov[d]) { @@ -951,7 +971,8 @@ void clearHexes(heptagon *at) { delete at->cdata; at->cdata = NULL; } - if(at->c7) subcell(at->c7, clearcell); + if(irr::on) irr::clear_links(at); + else if(at->c7) subcell(at->c7, clearcell); } void unlink_cdata(heptagon *h) { @@ -1017,7 +1038,7 @@ void verifycell(cell *c) { } void verifycells(heptagon *at) { - if(gp::on) return; + if(gp::on || irr::on) return; for(int i=0; imove[i] && at->move[i]->move[at->spin(i)] && at->move[i]->move[at->spin(i)] != at) { printf("hexmix error %p [%d s=%d] %p %p\n", at, i, at->spin(i), at->move[i], at->move[i]->move[at->spin(i)]); } @@ -1066,6 +1087,7 @@ int celldist(cell *c) { if(sphere) return celldistance(c, currentmap->gamestart()); if(ctof(c)) return c->master->distance; if(gp::on) return gp::compute_dist(c, celldist); + if(irr::on) return c->master->distance; int dx[MAX_S3]; for(int u=0; umaster->distance; @@ -1400,7 +1422,7 @@ int getCdata(cell *c, int j) { int jj = 0; auto ar = gp::get_masters(c); for(int k=0; k<3; k++) - jj += getHeptagonCdata(ar[k]->master)->val[j]; + jj += getHeptagonCdata(ar[k])->val[j]; return jj; } } @@ -1411,9 +1433,9 @@ int getBits(cell *c) { else if(c->type != 6) return getHeptagonCdata(c->master)->bits; else { auto ar = gp::get_masters(c); - int b0 = getHeptagonCdata(ar[0]->master)->bits; - int b1 = getHeptagonCdata(ar[1]->master)->bits; - int b2 = getHeptagonCdata(ar[2]->master)->bits; + int b0 = getHeptagonCdata(ar[0])->bits; + int b1 = getHeptagonCdata(ar[1])->bits; + int b2 = getHeptagonCdata(ar[2])->bits; return (b0 & b1) | (b1 & b2) | (b2 & b0); } } @@ -1475,7 +1497,7 @@ int celldistance(cell *c1, cell *c2) { return 64; } - if(gp::on || euclid) { + if(gp::on || euclid || irr::on) { if(saved_distances.count(make_pair(c1,c2))) return saved_distances[make_pair(c1,c2)]; diff --git a/compileunits.h b/compileunits.h index e2aad4dd..8886b529 100644 --- a/compileunits.h +++ b/compileunits.h @@ -32,6 +32,7 @@ #include "language.cpp" #include "cell.cpp" #include "goldberg.cpp" +#include "irregular.cpp" #include "pattern2.cpp" #include "flags.cpp" #include "yendor.cpp" diff --git a/complex.cpp b/complex.cpp index d92f8c86..b897ac43 100644 --- a/complex.cpp +++ b/complex.cpp @@ -3094,7 +3094,7 @@ namespace windmap { // cw.spin = 0; neighbors.emplace_back(); auto &v = neighbors.back(); - if(gp::on) + if(gp::on || irr::on) for(int l=0; lmaster, cw.spin); hs = hs + l + wstep; diff --git a/floorshapes.cpp b/floorshapes.cpp index 93a81925..a01f0c84 100644 --- a/floorshapes.cpp +++ b/floorshapes.cpp @@ -218,9 +218,17 @@ void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) { } } +namespace irr { void generate_floorshapes(); } void generate_floorshapes() { + if(irr::on) { + printf("generating irregular floorshapes...\n"); + irr::generate_floorshapes(); + printf("done\n"); + return; + } + if(gp::on) { return; } @@ -489,6 +497,103 @@ namespace gp { } } +namespace irr { + + map usedml; + + void generate_floorshapes() { + + if(irr::cells.empty()) return; + + for(auto pfsh: all_escher_floorshapes) { + auto& fsh = *pfsh; + generate_matrices_scale(1, fsh.noftype); + auto& m = hept_matrices; + + /* if(siid == 0) + for(auto& ma: m.v) ma.first = ma.first * pispin; */ + + fsh.b.resize(irr::sc); + + for(int id=0; id cornerlist; + + int cor = isize(vs.vertices); + for(int j=0; j &shv, i int id = gp::get_plainshape_id(c); queuepolyat(V, shv[id], col, prio); } + else if(irr::on) { + int id = irr::cellindex[c]; + if(id < 0 || id >= isize(shv)) { + return; + } + queuepolyat(V, shv[id], col, prio); + } else if((euclid || gp::on) && ishex1(c)) queuepolyat(V * pispin, shv[0], col, prio); else if(!(S7&1) && nonbitrunc) { @@ -566,8 +678,13 @@ void viewmat() { gp::just_matrices = false; } // if(gp::on && !gp::usedml.count(cwt.c)) return; - for(auto& v: (pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { +// for(auto& v: (pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { // for(auto& v: (gp::on ? gp::usedml[cwt.c] : pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { +// hyperpoint h1 = gmatrix[cwt.c] * v.second[0] * hpxyz(1,0,0); + id = irr::cellindex[cwt.c]; + for(auto& v: irr::usedml[id].v) { +// for(auto& v: (gp::on ? gp::usedml[cwt.c] : pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { + hyperpoint h1 = gmatrix[cwt.c] * v.second[0] * hpxyz(1,0,0); hyperpoint h2 = gmatrix[cwt.c] * v.second[0] * hpxyz(0,1,0); hyperpoint h3 = gmatrix[cwt.c] * v.second[0] * hpxyz(0,0,1); diff --git a/geometry.cpp b/geometry.cpp index db7ca1c7..e0108193 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -170,6 +170,7 @@ void precalc() { base_distlimit = ginf[geometry].distlimit[nonbitrunc]; gp::compute_geometry(); + irr::compute_geometry(); } transmatrix ddi(ld dir, ld dist) { diff --git a/goldberg.cpp b/goldberg.cpp index f0fa17c1..0ef2f1c0 100644 --- a/goldberg.cpp +++ b/goldberg.cpp @@ -857,16 +857,18 @@ namespace hr { namespace gp { return dmain + length(centerloc-at) - length(centerloc); } - array get_masters(cell *c) { + array get_masters(cell *c) { if(gp::on) { auto li = get_local_info(c); be_in_triangle(li); auto cm = c->master; int i = li.last_dir; - return make_array(cm->c7, createStep(cm, i)->c7, createStep(cm, fix7(i+1))->c7); + return make_array(cm, createStep(cm, i), createStep(cm, fix7(i+1))); } - else - return make_array(c->mov[0], c->mov[2], c->mov[4]); + else if(irr::on) + return irr::get_masters(c); + else + return make_array(c->mov[0]->master, c->mov[2]->master, c->mov[4]->master); } int compute_dist(cell *c, int master_function(cell*)) { diff --git a/graph.cpp b/graph.cpp index e16a37c9..1fddbd00 100644 --- a/graph.cpp +++ b/graph.cpp @@ -158,6 +158,7 @@ void drawSpeed(const transmatrix& V) { } int ctof(cell *c) { + if(irr::on) return irr::ctof(c); if(nonbitrunc && !gp::on) return 1; // if(euclid) return 0; return ishept(c) ? 1 : 0; @@ -232,7 +233,14 @@ void drawLightning(const transmatrix& V) { } int displaydir(cell *c, int d) { - if(euclid) + if(irr::on) { + auto id = irr::cellindex[c]; + auto& vs = irr::cells[id]; + if(d < 0 || d >= c->type) return 0; + auto& p = vs.jpoints[vs.neid[d]]; + return -int(atan2(p[1], p[0]) * S84 / 2 / M_PI + MODFIXER + .5); + } + else if(euclid) return - d * S84 / c->type; else return S42 - d * S84 / c->type; @@ -2092,7 +2100,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) { Vb = Vb * pispin; Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir)); } - else if(gp::on) { + else if(gp::on || irr::on) { transmatrix T = shmup::calc_relative_matrix(c->mov[c->mondir], c, c->mondir); Vb = Vb * T * rspintox(tC0(inverse(T))) * xpush(tentacle_length); } @@ -3076,6 +3084,7 @@ bool noAdjacentChasms(cell *c) { // does the current geometry allow nice duals bool has_nice_dual() { + if(irr::on) return false; if(!nonbitrunc) return true; if((S7 & 1) == 0) return true; if(!gp::on) return false; @@ -3171,8 +3180,8 @@ bool placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, int col) { else prio = PPR_REDWALL-2+4*(sidepar-SIDE_SLEV); transmatrix V2 = V * ddspin(c, i); - - if(gp::on) { + + if(gp::on || irr::on) { draw_shapevec(c, V2, qfi.fshape->gpside[sidepar][i], col, prio); return false; } @@ -4024,7 +4033,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { case laSwitch: set_floor(shSwitchFloor); - if(ctof(c)) for(int i=0; itype; i++) + if(ctof(c) && !gp::on && !irr::on) for(int i=0; itype; i++) queuepoly(Vf * ddspin(c, i, S6) * xpush(rhexf), shSwitchDisk, darkena(minf[active_switch()].color, fd, 0xFF)); break; @@ -4709,7 +4718,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { int prec = sphere ? 3 : 1; - if(gp::on) { + if(irr::on) { + int id = irr::cellindex[c]; + auto &vs = irr::cells[id]; + for(int t=0; ttype; t++) + if(c->mov[t] && c->mov[t] < c) + queueline(V * vs.vertices[t], V * vs.vertices[(1+t)%c->type], gridcolor(c, c->mov[t]), prec); + } + else if(gp::on) { vid.linewidth *= gp::scale * 2; if(isWarped(c) && has_nice_dual()) { if(pseudohept(c)) for(int t=0; ttype; t++) diff --git a/heptagon.cpp b/heptagon.cpp index 1204a70b..55284bdd 100644 --- a/heptagon.cpp +++ b/heptagon.cpp @@ -75,7 +75,10 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fix h->move[pard] = parent; tsetspin(h->spintable, pard, d); parent->move[d] = h; tsetspin(parent->spintable, d, pard); if(parent->c7) { - h->c7 = newCell(S7, h); + if(irr::on) + irr::link_next(parent, d); + else + h->c7 = newCell(S7, h); h->rval0 = h->rval1 = 0; h->cdata = NULL; h->emeraldval = emerald_heptagon(parent->emeraldval, d); h->zebraval = zebra_heptagon(parent->zebraval, d); diff --git a/hyper.h b/hyper.h index 020015ef..4c661f56 100644 --- a/hyper.h +++ b/hyper.h @@ -78,7 +78,7 @@ void addMessage(string s, char spamtype = 0); #define S3 ginf[geometry].vertex #define hyperbolic_37 (S7 == 7 && S3 == 3) #define hyperbolic_not37 ((S7 > 7 || S3 > 3) && hyperbolic) -#define weirdhyperbolic ((S7 > 7 || S3 > 3 || gp::on) && hyperbolic) +#define weirdhyperbolic ((S7 > 7 || S3 > 3 || gp::on || irr::on) && hyperbolic) #define stdhyperbolic (S7 == 7 && S3 == 3 && !gp::on) #define cgclass (ginf[geometry].cclass) @@ -2549,6 +2549,20 @@ struct hrmap_hyperbolic : hrmap { void verify() { verifycells(origin); } }; +namespace quotientspace { hrmap *new_map(); } +namespace irr { + extern bool on; + void link_to_base(heptagon *h, heptspin base); + void link_start(heptagon *h); + void link_next(heptagon *h, int d); + void may_link_next(heptagon *h, int d); + void link_cell(cell *c, int d); + void clear_links(heptagon *h); + bool pseudohept(cell*); + array get_masters(cell *c); + bool ctof(cell* c); + } + extern hrmap *currentmap; extern vector allmaps; @@ -3149,7 +3163,7 @@ namespace gp { int solve_triangle(int dmain, int d0, int d1, loc at); - array get_masters(cell *c); + array get_masters(cell *c); } int get_sightrange(); diff --git a/hypgraph.cpp b/hypgraph.cpp index a0cc5d40..34d7b04c 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -486,6 +486,8 @@ ld master_to_c7_angle() { } transmatrix actualV(const heptspin& hs, const transmatrix& V) { + if(irr::on) + return V * spin(M_PI + 2 * M_PI / S7 * (hs.spin + irr::periodmap[hs.h].base.spin)); return (hs.spin || nonbitrunc) ? V * spin(hs.spin*2*M_PI/S7 + master_to_c7_angle()) : V; } @@ -564,10 +566,22 @@ void drawrec(const heptspin& hs, hstate s, const transmatrix& V) { transmatrix V10; const transmatrix& V1 = hs.mirrored ? (V10 = V * Mirror) : V; + bool draw = c->pathdist < PINFD; + if(gp::on) { gp::drawrec(c, actualV(hs, V1)); } + else if(irr::on) { + auto& hi = irr::periodmap[hs.h]; + transmatrix V0 = actualV(hs, V1); + auto& vc = irr::cells_of_heptagon[hi.base.h]; + for(int i=0; ipathdist < PINFD && in_qrange(V)) for(int d=0; d jpoints; + hyperpoint p; + transmatrix pusher, rpusher; + vector neid; + vector spin; + vector vertices; + int localindex; + bool is_pseudohept; + int patterndir; + }; + +map cellindex; + +vector cells; + +ld inner(hyperpoint h1, hyperpoint h2) { + return + hyperbolic ? h1[2] * h2[2] - h1[0] * h2[0] - h1[1] * h2[1] : + h1[2] * h2[2] + h1[0] * h2[0] + h1[1] * h2[1]; + } + +hyperpoint circumscribe(hyperpoint a, hyperpoint b, hyperpoint c) { + using namespace hyperpoint_vec; + hyperpoint h = C0; + + b = b - a; + c = c - a; + + if(inner(b,b) < 0) { + b = b / sqrt(-inner(b, b)); + c = c + b * inner(c, b); + h = h + b * inner(h, b); + } + else { + b = b / sqrt(inner(b, b)); + c = c - b * inner(c, b); + h = h - b * inner(h, b); + } + + if(inner(c,c) < 0) { + c = c / sqrt(-inner(c, c)); + h = h + c * inner(h, c); + } + else { + c = c / sqrt(inner(c, c)); + h = h - c * inner(h, c); + } + + if(h[2] < 0) h[0] = -h[0], h[1] = -h[1], h[2] = -h[2]; + + ld i = inner(h, h); + if(i > 0) h /= sqrt(i); + else h /= -sqrt(-i); + + return h; + } + +bool clockwise(hyperpoint h1, hyperpoint h2) { + return h1[0] * h2[1] > h1[1] * h2[0]; + } + +map > cells_of_heptagon; + +int runlevel; +vector edgelens, distlens; + +void make_cells_of_heptagon() { + cells_of_heptagon.clear(); + for(int i=0; imaster]; + p1.localindex = isize(vc); + vc.push_back(i); + } + } + +hrmap *base; + +bool gridmaking; + +bool step(int delta) { + + if(!gridmaking) return false; + timetowait = 0; + + auto& all = base->allcells(); + + auto t = SDL_GetTicks(); + while(SDL_GetTicks() < t + 250) + switch(runlevel) { + case 0: { + + cells.clear(); + cells_of_heptagon.clear(); + + if(sc <= isize(all) * 2) { + for(auto h: all) { + cellinfo s; s.patterndir = -1; + s.owner = h, s.p = spin(hrand(1000)) * xpush(.01) * C0; + cells.emplace_back(s); + } + } + runlevel++; + break; + } + + case 1: { + while(isize(cells) < sc) { + if(SDL_GetTicks() > t + 250) { make_cells_of_heptagon(); return false; } + cellinfo s; s.patterndir = -1; + ld bestval = 0; + for(int j=0; j<10; j++) { + int k = hrand(isize(all)); + cell *c = all[k]; + hyperpoint h = randomPointIn(c->type); + ld mindist = 1e6; + for(auto p: cells) { + ld val = hdist(h, shmup::calc_relative_matrix(p.owner, c, h) * p.p); + if(val < mindist) mindist = val; + } + if(mindist > bestval) bestval = mindist, s.owner = c, s.p = h; + } + // printf("%lf %p %s\n", bestval, s.owner, display(s.p)); + cells.emplace_back(s); + } + make_cells_of_heptagon(); + runlevel++; + break; + } + + case 2: { + + sort(cells.begin(), cells.end(), [] (cellinfo &s1, cellinfo &s2) { return hdist0(s1.p) < hdist0(s2.p); }); + make_cells_of_heptagon(); + + edgelens.clear(); + distlens.clear(); + + int stats[16]; + for(int k=0; k<16; k++) stats[k] = 0; + + for(int i=0; i 8 || isize(cells[i].vertices) < 3) { + cells[i] = cells.back(); + i--; cells.pop_back(); + } + if(isize(cells) < sc*3/4) runlevel = 0; + else if(isize(cells) < sc) runlevel = 1; + else runlevel++; + break; + } + + case 4: { + + ld minedge = edgelens[isize(edgelens) / 2] / 5; + if(edgelens[0] < minedge) { + printf("rearranging\n"); + for(int i=0; imov[i], s.owner, s.p) * C0); + // spin(2 * M_PI * i / S7) * xpush(hcrossf) * C0); + if(dists[i] < dist) + d = i, dist = dists[i]; + } + if(d != -1 && dists[(d+1) % S7] > dists[(d+S7-1) % S7]) + d = (d + S7 - 1) % S7; + s.patterndir = d; + } + + break; + } + + case 10: + return false; + } + + return false; + } + +void compute_geometry() { + if(irr::on) { + ld scal = sqrt(isize(cells_of_heptagon) * 1. / sc); + crossf *= scal; + hepvdist *= scal; + rhexf *= scal; + } + } + +bool draw_cell_schematics(cell *c, transmatrix V) { + if(gridmaking) { + heptagon *h = c->master; + for(int i: cells_of_heptagon[h]) { + auto& p = cells[i]; + if(p.owner == c) { + queuestr(V * rgpushxto0(p.p), .1, its(i), isize(p.vertices) > 8 ? 0xFF0000 : 0xFFFFFF); + int N = isize(p.vertices); + for(int j=0; jmaster->move[p.patterndir]->c7, c, p.p) * C0, 0x00FF00FF); + } + } + } + return false; + } + +struct heptinfo { + heptspin base; + vector subcells; + }; + +map periodmap; + +void link_to_base(heptagon *h, heptspin base) { + // printf("linking %p to %p/%d\n", h, base.h, base.spin); + auto &hi = periodmap[h]; + hi.base = base; + for(int k: cells_of_heptagon[base.h]) { + cell *c = newCell(isize(cells[k].vertices), h); + hi.subcells.push_back(c); + cellindex[c] = k; + } + h->c7 = hi.subcells[0]; + } + +void clear_links(heptagon *h) { + auto& hi = periodmap[h]; + for(cell *c: hi.subcells) { + for(int i=0; itype; i++) if(c->mov[i]) c->mov[i]->mov[c->spin(i)] = NULL; + cellindex.erase(c); + delete c; + } + h->c7 = NULL; + periodmap.erase(h); + } + +void link_start(heptagon *h) { + link_to_base(h, heptspin(cells[0].owner->master, 0)); + } + +void link_next(heptagon *parent, int d) { + if(!periodmap.count(parent)) + link_to_base(parent, heptspin(cells[0].owner->master, 0)); + // printf("linking next: %p direction %d [s%d]\n", parent, d, parent->spin(d)); + auto *h = parent->move[d]; + heptspin hs = periodmap[parent].base + d + wstep - parent->spin(d); + link_to_base(h, hs); + } + +void may_link_next(heptagon *parent, int d) { + if(!periodmap.count(parent->move[d])) + link_next(parent, d); + } + + +void link_cell(cell *c, int d) { + // printf("linking cell: %p direction %d\n", c, d); + int ci = cellindex[c]; + auto& sc = cells[ci]; + int ci2 = sc.neid[d]; + auto& sc2 = cells[ci2]; + + heptagon *master2 = NULL; + + if(sc2.owner == sc.owner) { + master2 = c->master; + // printf("local\n"); + } + else { + int dirs = 0; + int os = periodmap[c->master].base.spin; + for(int d=0; dmaster == sc.owner->master->move[(os+d)%S7]) { + heptspin hss(c->master, d); + hss += wstep; + master2 = hss.h; + // printf("master2 is %p; base = %p; should be = %p\n", master2, periodmap[master2].base.h, sc2.owner->master); + dirs++; + } + if(dirs != 1) { printf("dirs error\n"); exit(1); } + } + + cell *c2 = periodmap[master2].subcells[sc2.localindex]; + c->mov[d] = c2; + tsetspin(c->spintable, d, sc.spin[d]); + c2->mov[sc.spin[d]] = c; + tsetspin(c2->spintable, sc.spin[d], d); + } + +void show_gridmaker() { + cmode = sm::SIDE; + gamescreen(0); + dialog::init(XLAT("Irregular grid")); + dialog::addSelItem(XLAT("activate"), its(runlevel), 'f'); + dialog::display(); + if(runlevel == 10) dialog::add_action([] { + popScreen(); + pop_game(); + for(hrmap *& hm : allmaps) if(hm == base) hm = NULL; + stop_game(); + irr::on = true; + nonbitrunc = true; + need_reset_geometry = true; + gridmaking = false; + start_game(); + }); + keyhandler = [] (int sym, int uni) { + dialog::handleNavigation(sym, uni); + // no exit + }; + } + +void create_map() { + push_game(); + switch(geometry) { + case gNormal: + geometry = gKleinQuartic; + break; + + case gOctagon: + geometry = gBolza2; + break; + + default: ; + break; + } + + nonbitrunc = true; + need_reset_geometry = true; + start_game(); + base = currentmap; + drawthemap(); + pushScreen(show_gridmaker); + runlevel = 0; + gridmaking = true; + } + +int readArgs() { + using namespace arg; + + if(0) ; + else if(argis("-irr")) { + PHASE(3); + shift(); sc = argi(); + restart_game(); + create_map(); + } + else return 1; + return 0; + } + +bool pseudohept(cell* c) { + return cells[cellindex[c]].is_pseudohept; + } + +bool ctof(cell* c) { + return cells[cellindex[c]].patterndir == -1; + } + +array get_masters(cell *c) { + int d = cells[cellindex[c]].patterndir; + heptspin s = periodmap[c->master].base; + heptspin s0 = heptspin(c->master, 0) + (d - s.spin); + return make_array(s0.h, (s0 + wstep).h, (s0 + 1 + wstep).h); + } + +auto hook = + addHook(hooks_args, 100, readArgs) + + addHook(hooks_drawcell, 100, draw_cell_schematics) + + addHook(shmup::hooks_turn, 100, step); + + }} + +/* + if(mouseover && !ctof(mouseover)) { + for(auto h: gp::get_masters(mouseover)) + queueline(shmup::ggmatrix(h->c7)*C0, shmup::ggmatrix(mouseover)*C0, 0xFFFFFFFF); + } + +*/ diff --git a/landgen.cpp b/landgen.cpp index 962b6189..67f31887 100644 --- a/landgen.cpp +++ b/landgen.cpp @@ -210,14 +210,14 @@ void giantLandSwitch(cell *c, int d, cell *from) { else { if(d == 9) { - cell *c2 = gp::on ? c->master->c7 : c; + cell *c2 = (gp::on || irr::on) ? c->master->c7 : c; if(cdist50(c2) == 3 && polarb50(c2) == 1) c->wall = waPalace; } if(d == 8 && sphere) { int gs = getHemisphere(c,0); - if(gp::on) { + if(gp::on || irr::on) { int v = 1; forCellEx(c2, c) if(getHemisphere(c2, 0) != gs) v = 2; @@ -583,7 +583,7 @@ void giantLandSwitch(cell *c, int d, cell *from) { else if(v == 25 || v == 59 || v == 27 || v == 57) c->wall = waVineHalfB; else c->wall = waNone; - if(gp::on && cellHalfvine(c)) { + if((gp::on || irr::on) && cellHalfvine(c)) { c->wall = waNone; forCellCM(c2, c) if(emeraldval(c2) == (v^1)) c->wall = waVinePlant; diff --git a/landlock.cpp b/landlock.cpp index 4eec6f6a..937f27f3 100644 --- a/landlock.cpp +++ b/landlock.cpp @@ -1159,6 +1159,15 @@ land_validity_t& land_validity(eLand l) { if(isWarped(l) && a4 && gp::on) return dont_work; + if((isWarped(l) || l == laDual) && irr::on) + return dont_work; + + if(irr::on && among(l, laStorms, laPrairie, laBlizzard, laVolcano)) + return dont_work; + + if(irr::on && among(l, laWhirlpool, laCamelot, laCaribbean, laClearing, laTemple, laHive, laMirror, laMirrorOld, laReptile, laKraken, laBurial)) + return dont_work; + // equidistant-based lands if(isEquidLand(l)) { // no equidistants supported in chaos mode diff --git a/menus.cpp b/menus.cpp index 45dcf0e7..c32d81ee 100644 --- a/menus.cpp +++ b/menus.cpp @@ -826,7 +826,7 @@ void setAppropriateOverview() { pushScreen(yendor::showMenu); else if(peace::on) pushScreen(peace::showMenu); - else if((geometry != gNormal || gp::on) && !chaosmode && !(geometry == gEuclid && isCrossroads(specialland)) && !(weirdhyperbolic && specialland == laCrossroads4)) { + else if((geometry != gNormal || gp::on || irr::on) && !chaosmode && !(geometry == gEuclid && isCrossroads(specialland)) && !(weirdhyperbolic && specialland == laCrossroads4)) { runGeometryExperiments(); } else { diff --git a/pattern2.cpp b/pattern2.cpp index 18dcddf2..24b400f8 100644 --- a/pattern2.cpp +++ b/pattern2.cpp @@ -49,11 +49,13 @@ bool ishex2(cell *c) { else return c->type != S6; } +int emeraldval(heptagon *h) { return h->emeraldval >> 3; } + int emeraldval(cell *c) { if(euclid) return eupattern(c); if(sphere) return 0; if(ctof(c)) - return c->master->emeraldval >> 3; + return emeraldval(c->master); else { auto ar = gp::get_masters(c); return emerald_hexagon( @@ -96,9 +98,9 @@ int fiftyval(cell *c) { else { auto ar = gp::get_masters(c); return bitmajority( - fiftyval(ar[0]), - fiftyval(ar[1]), - fiftyval(ar[2])) + 512; + ar[0]->fiftyval, + ar[1]->fiftyval, + ar[2]->fiftyval) + 512; } } @@ -109,47 +111,47 @@ int cdist50(cell *c) { return "0123333332112332223322233211233333322"[eufifty(c)] - '0'; else return "012333321112322232222321123"[eufifty(c)] - '0'; } - if(c->type != 6) return cdist50(fiftyval(c)); + if(ctof(c)) return cdist50(c->master->fiftyval); auto ar = gp::get_masters(c); - int a0 = cdist50(ar[0]); - int a1 = cdist50(ar[1]); - int a2 = cdist50(ar[2]); + int a0 = cdist50(ar[0]->fiftyval); + int a1 = cdist50(ar[1]->fiftyval); + int a2 = cdist50(ar[2]->fiftyval); if(a0 == 0 || a1 == 0 || a2 == 0) return 1; return a0+a1+a2-5; } int land50(cell *c) { - if(c->type != 6) return land50(fiftyval(c)); - else if(sphere || euclid) return 0; + if(sphere || euclid) return 0; + else if(ctof(c)) return land50(fiftyval(c)); else { auto ar = gp::get_masters(c); for(int i=0; i<3; i++) - if(cdist50(ar[i]) < 3) return land50(ar[i]); + if(cdist50(ar[i]->fiftyval) < 3) return land50(ar[i]->fiftyval); return 0; } } int polara50(cell *c) { - if(c->type != 6) return polara50(fiftyval(c)); - else if(sphere || euclid || S7>7 || S6>6) return 0; - else if(gp::on) return polara50(fiftyval(c->master->c7)); + if(sphere || euclid || S7>7 || S6>6) return 0; + else if(gp::on || irr::on) return polara50(fiftyval(c->master->c7)); + else if(ctof(c)) return polara50(fiftyval(c)); else { auto ar = gp::get_masters(c); for(int i=0; i<3; i++) - if(cdist50(ar[i]) < 3) return polara50(ar[i]); + if(cdist50(ar[i]->fiftyval) < 3) return polara50(ar[i]->fiftyval); return 0; } } int polarb50(cell *c) { if(euclid) return true; - if(c->type != 6) return polarb50(fiftyval(c)); - else if(sphere || euclid || S7>7 || S6>6) return true; - else if(gp::on) return polarb50(fiftyval(c->master->c7)); + if(sphere || euclid || S7>7 || S6>6) return true; + else if(gp::on || irr::on) return polarb50(fiftyval(c->master->c7)); + else if(ctof(c)) return polarb50(fiftyval(c)); else { auto ar = gp::get_masters(c); for(int i=0; i<3; i++) - if(cdist50(ar[i]) < 3) return polarb50(ar[i]); + if(cdist50(ar[i]->fiftyval) < 3) return polarb50(ar[i]->fiftyval); return 0; } } @@ -158,30 +160,32 @@ int elhextable[28][3] = { {0,1,2}, {1,2,9}, {1,9,-1}, {1,8,-1}, {1,-1,-1} }; +int fiftyval049(heptagon *h) { + int i = h->fiftyval / 32; + if(i <= 7) return i; + if(quotient) return 0; + vector allcodes; + for(int k=0; k<7; k++) { + heptagon *h2 = createStep(h, k); + if(polara50(h2->fiftyval) == polara50(h->fiftyval) && polarb50(h2->fiftyval) == polarb50(h->fiftyval)) + allcodes.push_back(fiftyval049(h2)); + } + int d = allcodes[1] - allcodes[0]; + if(d == -1 || d == 6) swap(allcodes[0], allcodes[1]); + // printf("%d,%d: %d\n", allcodes[0], allcodes[1], allcodes[0] + 7); + return allcodes[0] + 7; + } + int fiftyval049(cell *c) { if(euclid) return fiftyval(c) / 32; - else if(ctof(c)) { - int i = fiftyval(c) / 32; - if(i <= 7) return i; - if(quotient) return 0; - vector allcodes; - for(int k=0; k<7; k++) { - cell *c2 = createStep(c->master, k)->c7; - if(polara50(c2) == polara50(c) && polarb50(c2) == polarb50(c)) - allcodes.push_back(fiftyval049(c2)); - } - int d = allcodes[1] - allcodes[0]; - if(d == -1 || d == 6) swap(allcodes[0], allcodes[1]); - // printf("%d,%d: %d\n", allcodes[0], allcodes[1], allcodes[0] + 7); - return allcodes[0] + 7; - } + else if(ctof(c)) return fiftyval049(c->master); else if(sphere) return 0; else { int a[3], qa=0; int pa = polara50(c), pb = polarb50(c); auto ar = gp::get_masters(c); for(int i=0; i<3; i++) - if(polara50(ar[i]) == pa && polarb50(ar[i]) == pb) + if(polara50(ar[i]->fiftyval) == pa && polarb50(ar[i]->fiftyval) == pb) a[qa++] = fiftyval049(ar[i]); // 0-1-2 sort(a, a+qa); @@ -248,6 +252,7 @@ int val46(cell *c); int zebra40(cell *c) { if(euclid) return eupattern(c); + else if(irr::on) return c->master->zebraval/10; else if(a46) { int v = val46(c); if(v<4) return v; @@ -285,9 +290,9 @@ int zebra40(cell *c) { else { int ii[3], z; auto ar = gp::get_masters(c); - ii[0] = (ar[0]->master->zebraval/10); - ii[1] = (ar[1]->master->zebraval/10); - ii[2] = (ar[2]->master->zebraval/10); + ii[0] = (ar[0]->zebraval/10); + ii[1] = (ar[1]->zebraval/10); + ii[2] = (ar[2]->zebraval/10); for(int r=0; r<2; r++) if(ii[1] < ii[0] || ii[2] < ii[0]) z = ii[0], ii[0] = ii[1], ii[1] = ii[2], ii[2] = z; @@ -304,14 +309,14 @@ int zebra40(cell *c) { } int zebra3(cell *c) { - if(c->type != 6) return (c->master->zebraval/10)/4; - else if(sphere || S7>7 || S6>6) return 0; + if(ctof(c)) return (c->master->zebraval/10)/4; + else if(euclid || sphere || S7>7 || S6>6) return 0; else { int ii[3]; auto ar = gp::get_masters(c); - ii[0] = (ar[0]->master->zebraval/10)/4; - ii[1] = (ar[1]->master->zebraval/10)/4; - ii[2] = (ar[2]->master->zebraval/10)/4; + ii[0] = (ar[0]->zebraval/10)/4; + ii[1] = (ar[1]->zebraval/10)/4; + ii[2] = (ar[2]->zebraval/10)/4; if(ii[0] == ii[1]) return ii[0]; if(ii[1] == ii[2]) return ii[1]; if(ii[2] == ii[0]) return ii[2]; @@ -328,7 +333,7 @@ pair fieldval(cell *c) { int fieldval_uniq(cell *c) { if(sphere) { - if(ctof(c)) return c->master->fieldval; + if(ctof(c) || gp::on || irr::on) return c->master->fieldval; else return createMov(c, 0)->master->fieldval + 256 * createMov(c,2)->master->fieldval + (1<<16) * createMov(c,4)->master->fieldval; } else if(torus) { @@ -338,7 +343,7 @@ int fieldval_uniq(cell *c) { auto p = cell_to_pair(c); return gmod(p.first * torusconfig::dx + p.second * torusconfig::dy, torusconfig::qty); } - if(ctof(c) || gp::on) return c->master->fieldval/S7; + if(ctof(c) || gp::on || irr::on) return c->master->fieldval/S7; else { int z = 0; for(int u=0; umaster->fieldval, randval)/7; @@ -708,7 +713,8 @@ namespace patterns { } void val_all(cell *c, patterninfo &si, int sub, int pat) { - if(a46) val46(c, si, sub, pat); + if(irr::on) si.symmetries = 1; + else if(a46) val46(c, si, sub, pat); else if(a38) val38(c, si, sub, pat); else if(sphere) valSibling(c, si, sub, pat); else if(euclid4) valEuclid4(c, si, sub); @@ -1005,6 +1011,7 @@ namespace patterns { } int geosupport_threecolor() { + if(irr::on) return 0; if(!nonbitrunc && S3 == 3) { if(S7 % 2) return 1; return 2; @@ -1019,6 +1026,7 @@ int geosupport_threecolor() { int geosupport_graveyard() { // always works in bitrunc geometries if(!nonbitrunc) return 2; + if(irr::on) return 0; // always works in patterns supporting three-color int tc = max(geosupport_threecolor(), gp_threecolor()); @@ -1130,6 +1138,7 @@ int pattern_threecolor(cell *c) { // in the 'pure heptagonal' tiling, returns true for a set of cells // which roughly corresponds to the heptagons in the normal tiling bool pseudohept(cell *c) { + if(irr::on) return irr::pseudohept(c); if(gp::on && gp_threecolor() == 2) return gp::pseudohept_val(c) == 0; if(gp::on && gp_threecolor() == 1 && (S7&1) && (S3 == 3)) diff --git a/shmup.cpp b/shmup.cpp index ad4b3abf..cd70d0a7 100644 --- a/shmup.cpp +++ b/shmup.cpp @@ -3313,7 +3313,12 @@ void destroyBoats(cell *c) { } transmatrix master_relative(cell *c, bool get_inverse) { - if(gp::on) { + if(irr::on) { + int id = irr::cellindex[c]; + ld alpha = 2 * M_PI / S7 * irr::periodmap[c->master].base.spin; + return get_inverse ? irr::cells[id].rpusher * spin(-alpha-master_to_c7_angle()): spin(alpha + master_to_c7_angle()) * irr::cells[id].pusher; + } + else if(gp::on) { if(c == c->master->c7) { return spin((get_inverse?-1:1) * master_to_c7_angle()); } diff --git a/system.cpp b/system.cpp index 2a4fdd21..aca9eac3 100644 --- a/system.cpp +++ b/system.cpp @@ -1029,10 +1029,10 @@ namespace gamestack { bool pushed() { return isize(gd); } void push() { - if(geometry) { + /* if(geometry) { printf("ERROR: push implemented only in non-hyperbolic geometry\n"); exit(1); - } + } */ gamedata gdn; gdn.hmap = currentmap; gdn.cwt = cwt;