hybrid:: refactored the common parts of prod and sl2, also used them when applicable

This commit is contained in:
Zeno Rogue 2019-08-24 14:07:46 +02:00
parent ab80b28782
commit 1e6970ca28
20 changed files with 169 additions and 224 deletions

View File

@ -37,7 +37,7 @@ EX bool hasbardir(cell *c) {
}
EX void preventbarriers(cell *c) {
if(prod) c = product::get_where(c).first;
if(hybri) c = hybrid::get_where(c).first;
if(c && c->bardir == NODIR) c->bardir = NOBARRIERS;
}

View File

@ -1389,7 +1389,7 @@ EX void initgraph() {
loadConfig();
#endif
arcm::current.parse();
if(geometry == gProduct) geometry = product::underlying;
if(hybri) geometry = hybrid::underlying;
#if CAP_COMMANDLINE
arg::read(2);

View File

@ -132,7 +132,7 @@ EX bool grailWasFound(cell *c) {
}
void hrmap::generateAlts(heptagon *h, int levs, bool link_cdata) {
if(prod) { product::in_underlying_map([&] { generateAlts(h, levs, link_cdata); }); }
if(hybri) { hybrid::in_underlying_map([&] { generateAlts(h, levs, link_cdata); }); }
if(!h->alt) return;
preventbarriers(h->c7);
if(h->c7) forCellEx(c2, h->c7) preventbarriers(c2);
@ -183,10 +183,10 @@ void hrmap::generateAlts(heptagon *h, int levs, bool link_cdata) {
EX heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special IS(0)) {
if(prod) {
c = product::get_where(c).first;
if(hybri) {
c = hybrid::get_where(c).first;
heptagon *res;
product::in_underlying_map([&] { res = createAlternateMap(c, rad, firststate, special); });
hybrid::in_underlying_map([&] { res = createAlternateMap(c, rad, firststate, special); });
return res;
}
@ -246,7 +246,7 @@ EX heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special
alt->emeraldval = 0;
alt->zebraval = 0;
alt->distance = 0;
alt->fieldval = nisot::current_view_level;
alt->fieldval = hybrid::current_view_level;
alt->c7 = NULL;
alt->alt = alt;
h->alt = alt;
@ -758,10 +758,10 @@ EX void buildEquidistant(cell *c) {
chance = hrand(100) < 10;
}
if(c->landparam > 30 && b == laOcean && !generatingEquidistant && !prod && hrand(10) < 5 && chance)
if(c->landparam > 30 && b == laOcean && !generatingEquidistant && !hybri && hrand(10) < 5 && chance)
buildAnotherEquidistant(c);
if(c->landparam > HAUNTED_RADIUS+5 && b == laGraveyard && !generatingEquidistant && !prod && hrand(100) < (PURE?25:5) && items[itBone] >= 10 && chance)
if(c->landparam > HAUNTED_RADIUS+5 && b == laGraveyard && !generatingEquidistant && !hybri && hrand(100) < (PURE?25:5) && items[itBone] >= 10 && chance)
buildAnotherEquidistant(c);
}
@ -978,8 +978,8 @@ EX void setLandSol(cell *c) {
}
}
EX void setLandProduct(cell *c) {
auto wc = product::get_where(c).first;
EX void setLandHybrid(cell *c) {
auto wc = hybrid::get_where(c).first;
c->barleft = wc->barleft;
c->barright = wc->barright;
c->bardir = wc->bardir;
@ -1278,7 +1278,7 @@ EX int wallchance(cell *c, bool deepOcean) {
/** should we generate the horocycles in the current geometry? */
EX bool horo_ok() {
return hyperbolic && !binarytiling && !archimedean && !penrose && !experimental && !prod;
return hyperbolic && !binarytiling && !archimedean && !penrose && !experimental && !hybri;
}
EX bool gp_wall_test() {
@ -1336,7 +1336,7 @@ EX void buildBigStuff(cell *c, cell *from) {
// buildgreatwalls
if(prod) ; /* Great Walls generated via the underlying geometry */
if(hybri) ; /* Great Walls generated via the underlying geometry */
else if(geometry == gNormal && celldist(c) < 3 && !GOLDBERG) {
if(top_land && c == cwt.at->master->move(3)->c7) {
@ -1666,8 +1666,8 @@ EX void moreBigStuff(cell *c) {
else if(geometry == gKiteDart3) {
if(kite::getshape(c->master) == kite::pKite) c->wall = waColumn;
}
else if(prod) {
auto d = product::get_where(c);
else if(hybri) {
auto d = hybrid::get_where(c);
if(d.first->wall == waColumn || (d.second&1)) c->wall = waColumn;
}
else if(WDIM == 3) {

View File

@ -146,10 +146,8 @@ EX cell *createMov(cell *c, int d) {
}
if(c->move(d)) return c->move(d);
else if(geometry == gProduct)
product::find_cell_connection(c, d);
else if(sl2)
slr::find_cell_connection(c, d);
else if(hybri)
hybrid::find_cell_connection(c, d);
#if CAP_BT
else if(penrose)
kite::find_cell_connection(c, d);
@ -455,9 +453,11 @@ EX int compdist(int dx[]) {
EX int celldist(cell *c) {
if(experimental) return 0;
if(prod) { auto w = product::get_where(c);
if(hybri) {
auto w = hybrid::get_where(c);
if(sl2) w.second = 0;
int d;
product::in_underlying_map([&] { d = celldist(w.first) + abs(w.second); });
hybrid::in_underlying_map([&] { d = celldist(w.first) + abs(w.second); });
return d;
}
if(fulltorus && WDIM == 2)
@ -490,10 +490,11 @@ static const int ALTDIST_ERROR = 90000;
EX int celldistAlt(cell *c) {
if(experimental) return 0;
if(prod) { auto w = product::get_where(c);
if(hybri) {
auto w = hybrid::get_where(c);
int d = c->master->alt && c->master->alt->alt ? c->master->alt->alt->fieldval : 0;
d = abs(w.second - d);
product::in_underlying_map([&] { d += celldistAlt(w.first); });
d = sl2 ? 0 : abs(w.second - d);
hybrid::in_underlying_map([&] { d += celldistAlt(w.first); });
return d;
}
if(masterless) {
@ -1000,9 +1001,10 @@ EX cell *random_in_distance(cell *c, int d) {
EX int celldistance(cell *c1, cell *c2) {
if(prod) { auto w1 = product::get_where(c1), w2 = product::get_where(c2);
if(prod) {
auto w1 = hybrid::get_where(c1), w2 = hybrid::get_where(c2);
int d;
product::in_underlying_map([&] { d = celldistance(w1.first, w2.first) + abs(w1.second - w2.second); });
hybrid::in_underlying_map([&] { d = celldistance(w1.first, w2.first) + abs(w1.second - w2.second); });
return d;
}
@ -1039,7 +1041,7 @@ EX int celldistance(cell *c1, cell *c2) {
if(cryst) return crystal::precise_distance(c1, c2);
#endif
if(masterless || archimedean || quotient || sol || (penrose && euclid) || experimental) {
if(masterless || archimedean || quotient || sol || (penrose && euclid) || experimental || sl2) {
if(saved_distances.count(make_pair(c1,c2)))
return saved_distances[make_pair(c1,c2)];

View File

@ -2668,7 +2668,7 @@ EX namespace sword {
};
/** dimensions available to the Sword */
#define SWORDDIM ((prod || sl2) ? 2 : WDIM)
#define SWORDDIM (hybri ? 2 : WDIM)
#endif
@ -2695,7 +2695,7 @@ EX namespace sword {
cell *pos2(cell *c, int s) {
int t = c->type;
if(prod || sl2) t -= 2;
if(hybri) t -= 2;
s *= 2;
s += sword_angles/t;
s %= (2 * sword_angles);
@ -2748,7 +2748,7 @@ EX namespace sword {
int s2 = neighborId(c2, c1);
if(s1 < 0 || s2 < 0) return d;
if(SWORDDIM == 2) {
int sub = (prod || sl2) ? 2 : 0;
int sub = (hybri) ? 2 : 0;
int t2 = c2->type - sub;
int t1 = c1->type - sub;
if(c1->c.mirror(s1))
@ -3397,7 +3397,7 @@ EX namespace windmap {
// cw.spin = 0;
neighbors.emplace_back();
auto &v = neighbors.back();
if(NONSTDVAR && !sphere && !archimedean && !prod)
if(NONSTDVAR && !sphere && !archimedean && !hybri)
for(int l=0; l<S7; l++) {
v.push_back(getId(cw + cth + l + wstep + cth));
}
@ -3414,7 +3414,7 @@ EX namespace windmap {
if(N == 18920) precomp = windcodes18920;
if(N == 5676) precomp = windcodes5676;
if(precomp && (hyperbolic || prod) && isize(currfp.matrices)) {
if(precomp && (hyperbolic || hybri) && isize(currfp.matrices)) {
int randval = hrand(isize(currfp.matrices));
for(int i=0; i<N; i++)
windcodes[i] = precomp[getid[fieldpattern::fieldval_uniq_rand(samples[i].at, randval)]-1];

View File

@ -511,7 +511,7 @@ EX void initConfig() {
addsaver(models::use_atan, "use_atan");
addsaver(arcm::current.symbol, "arcm-symbol", "4^5");
addsaverenum(product::underlying, "product-underlying");
addsaverenum(hybrid::underlying, "product-underlying");
for(int i=0; i<isize(ginf); i++) {
if(ginf[i].flags & qELLIPTIC)

View File

@ -774,10 +774,10 @@ void set_floor(const transmatrix& spin, hpcshape& sh) {
}
EX int shvid(cell *c) {
if(prod) {
if(hybri) {
int d;
cell *c1 = product::get_where(c).first;
product::in_underlying_map([&] { d = shvid(c1); });
cell *c1 = hybrid::get_where(c).first;
hybrid::in_underlying_map([&] { d = shvid(c1); });
return d;
}
else if(GOLDBERG)

View File

@ -455,37 +455,22 @@ void geometry_information::prepare_basics() {
goto finish;
}
if(prod) {
if(hybri) {
auto t = this;
product::in_underlying_geometry([&] {
t->rhexf = cgi.rhexf;
t->hexf = cgi.hexf;
t->crossf = cgi.crossf;
t->hcrossf = cgi.crossf;
t->tessf = cgi.tessf;
t->hexvdist = cgi.hexvdist;
t->hexhexdist = cgi.hexhexdist;
ld d = sl2 ? 2 : 1;
hybrid::in_underlying_geometry([&] {
t->rhexf = cgi.rhexf / d;
t->hexf = cgi.hexf / d;
t->crossf = cgi.crossf / d;
t->hcrossf = cgi.crossf / d;
t->tessf = cgi.tessf / d;
t->hexvdist = cgi.hexvdist / d;
t->hexhexdist = cgi.hexhexdist / d;
t->base_distlimit = cgi.base_distlimit-1;
});
goto prod_finish;
goto hybrid_finish;
}
if(sl2) {
dynamicval<eGeometry> g(geometry, gNormal);
check_cgi();
cgi.prepare_basics();
rhexf = cgi.rhexf/2;
hexf = cgi.hexf/2;
crossf = cgi.crossf/2;
hcrossf = cgi.hcrossf/2;
tessf = cgi.tessf/2;
hexvdist = cgi.hexvdist/2;
hexhexdist = cgi.hexhexdist/2;
base_distlimit = cgi.base_distlimit-1;
cgip = this;
goto prod_finish;
}
if((sphere || hyperbolic) && WDIM == 3 && !binarytiling) {
rhexf = hexf = 0.378077;
crossf = hcrossf = 0.620672;
@ -561,7 +546,7 @@ void geometry_information::prepare_basics() {
if(binarytiling) binary::build_tmatrix();
#endif
prod_finish:
hybrid_finish:
scalefactor = crossf / hcrossf7;
orbsize = crossf;
@ -935,7 +920,7 @@ EX void check_cgi() {
cgip = &cgis[s];
cgi.timestamp = ++ntimestamp;
if(prod) product::underlying_cgip->timestamp = ntimestamp;
if(hybri) hybrid::underlying_cgip->timestamp = ntimestamp;
if(isize(cgis) > 4) {
vector<pair<int, string>> timestamps;

View File

@ -243,14 +243,14 @@ struct horo_distance {
template<class T, class U>
void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
if(prod) {
auto w = product::get_where(base);
auto w = hybrid::get_where(base);
auto d = product_decompose(check(at)).first;
at = mscale(at, -d);
product::in_underlying_map([&] { virtualRebase(w.first, at, tohex, check); });
hybrid::in_underlying_map([&] { virtualRebase(w.first, at, tohex, check); });
if(d > cgi.plevel / 2) { w.second++; d -= cgi.plevel; }
if(d < -cgi.plevel / 2) { w.second--; d += cgi.plevel; }
at = mscale(at, +d);
base = product::get_at(w.first, w.second);
base = hybrid::get_at(w.first, w.second);
return;
}
if((euclid || sphere) && WDIM == 2) {

View File

@ -409,7 +409,7 @@ EX void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) {
int adj = 1 - ((sword_angles/cwt.at->type)&1);
#if CAP_QUEUE
if(!euclid && !prod) for(int a=0; a<sword_angles; a++) {
if(!euclid && !hybri) for(int a=0; a<sword_angles; a++) {
if(a == ang && items[itOrbSword]) continue;
if((a+sword_angles/2)%sword_angles == ang && items[itOrbSword2]) continue;
bool longer = sword::pos2(cwt.at, a-1) != sword::pos2(cwt.at, a+1);
@ -4426,7 +4426,7 @@ color_t transcolor(cell *c, cell *c2, color_t wcol) {
// how much should be the d-th wall darkened in 3D
int get_darkval(cell *c, int d) {
if(prod || sl2) {
if(hybri) {
return d >= c->type - 2 ? 4 : 0;
}
const int darkval_hbt[9] = {0,2,2,0,6,6,8,8,0};
@ -5056,7 +5056,7 @@ void drawcell_in_radar(cell *c, transmatrix V) {
EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
if(product::pmap) { product::drawcell_stack(c, V, spinv, mirrored); return; }
if(hybrid::pmap) { product::drawcell_stack(c, V, spinv, mirrored); return; }
cells_drawn++;
@ -6031,7 +6031,7 @@ EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
for(int a=0; a<c->type; a++)
if(c->move(a) && !isWall3(c->move(a), dummy)) {
if(pmodel == mdPerspective && !sphere && !quotient && !penrose && !nonisotropic && !prod && !experimental) {
if(pmodel == mdPerspective && !sphere && !quotient && !penrose && !nonisotropic && !hybri && !experimental) {
if(a < 4 && among(geometry, gHoroTris, gBinary3) && celldistAlt(c) >= celldistAlt(viewcenter())) continue;
else if(a < 2 && among(geometry, gHoroRec) && celldistAlt(c) >= celldistAlt(viewcenter())) continue;
else if(c->move(a)->master->distance > c->master->distance && c->master->distance > viewctr.at->distance && !quotient) continue;
@ -6999,7 +6999,7 @@ EX void drawMarkers() {
#endif
if(prod && !shmup::on) {
if(hybri && !shmup::on) {
using namespace sword;
int& ang = sword::dir[multi::cpid].angle;
@ -8043,8 +8043,7 @@ EX void drawBug(const cellwalker& cw, color_t col) {
EX cell *viewcenter() {
if(masterless) return centerover.at;
else if(prod) return product::get_at(viewctr.at->c7, nisot::current_view_level);
else if(sl2) return slr::get_at(viewctr.at->c7, nisot::current_view_level);
else if(hybri) return hybrid::get_at(viewctr.at->c7, hybrid::current_view_level);
else return viewctr.at->c7;
}

View File

@ -127,6 +127,7 @@ void addMessage(string s, char spamtype = 0);
#define nil (cgclass == gcNil)
#define sl2 (cgclass == gcSL2)
#define prod (cgclass == gcProduct)
#define hybri (prod || sl2)
#define hyperbolic (cgclass == gcHyperbolic)
#define nonisotropic (sol || nil || sl2)
#define translatable (euclid || nonisotropic)

View File

@ -911,7 +911,7 @@ EX bool confusingGeometry() {
}
EX ld master_to_c7_angle() {
if(prod) return product::in_underlying_geometry(master_to_c7_angle);
if(prod) return hybrid::in_underlying_geometry(master_to_c7_angle);
ld alpha = 0;
#if CAP_GP
if(cgi.gpdata) alpha = cgi.gpdata->alpha;
@ -1395,7 +1395,7 @@ EX void optimizeview() {
if(cbest) {
View = View * currentmap->relative_matrix(cbest, c, C0);
viewctr.at = cbest->master;
nisot::current_view_level = slr::get_where(cbest).second;
hybrid::current_view_level = hybrid::get_where(cbest).second;
}
return;
}
@ -1403,9 +1403,9 @@ EX void optimizeview() {
if(prod) {
ld z = zlevel(tC0(View));
View = mscale(View, -z);
product::in_underlying_map(optimizeview);
if(z > cgi.plevel / 2) { nisot::current_view_level--; z -= cgi.plevel; }
if(z < -cgi.plevel / 2) { nisot::current_view_level++; z += cgi.plevel; }
hybrid::in_underlying_map(optimizeview);
if(z > cgi.plevel / 2) { hybrid::current_view_level--; z -= cgi.plevel; }
if(z < -cgi.plevel / 2) { hybrid::current_view_level++; z += cgi.plevel; }
View = mscale(View, z);
return;
}
@ -1500,7 +1500,7 @@ EX void resetview() {
else centerover = cwt;
cwtV = View;
nisot::local_perspective = Id;
if(prod || sl2) nisot::current_view_level = product::get_where(cwt.at).second;
if(hybri) hybrid::current_view_level = hybrid::get_where(cwt.at).second;
// SDL_LockSurface(s);
// SDL_UnlockSurface(s);
}
@ -1987,7 +1987,7 @@ bool limited_generation(cell *c) {
EX bool do_draw(cell *c, const transmatrix& T) {
if(product::pmap) return product::in_actual([&] { return do_draw(product::get_at(c, nisot::current_view_level), T); });
if(hybrid::pmap) return hybrid::in_actual([&] { return do_draw(hybrid::get_at(c, hybrid::current_view_level), T); });
if(WDIM == 3) {
if(cells_drawn > vid.cells_drawn_limit) return false;
if(nil && pmodel == mdGeodesic) {

View File

@ -315,7 +315,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
if(d == 8 && !sphere) {
if(prod && polarb50(c) && (product::get_where(c).second & 3) == 2) {
if(prod && polarb50(c) && (hybrid::get_where(c).second & 3) == 2) {
c->wall = waPalace;
break;
}
@ -353,19 +353,19 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
if(GOLDBERG) ;
else {
int q = 0, s = 0;
if(!ishept(c)) for(int i=0; i<c->type - (prod ? 2 : 0); i++)
if(!ishept(c)) for(int i=0; i<c->type - (hybri ? 2 : 0); i++)
if(cdist50(c->move(i)) == 3 && polarb50(c->move(i)) && !ishept(c->move(i)))
q++, s += i;
if(q == 1 && c->move(s)->land == laPalace) {
switch(princess::generating ? 0 : hrand(2)) {
case 0:
c->wall = waClosedGate;
if(prod) toggleGates(c, waClosePlate, 1);
if(hybri) toggleGates(c, waClosePlate, 1);
c->move(s)->wall = waClosedGate;
break;
case 1:
c->wall = waOpenGate;
if(prod) toggleGates(c, waOpenPlate, 1);
if(hybri) toggleGates(c, waOpenPlate, 1);
c->move(s)->wall = waOpenGate;
break;
}
@ -704,7 +704,7 @@ EX 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(prod && cellHalfvine(c)) c->wall = waNone;
if(hybri && cellHalfvine(c)) c->wall = waNone;
if(NONSTDVAR && cellHalfvine(c)) {
c->wall = waNone;
forCellCM(c2, c) if(emeraldval(c2) == (v^1))
@ -1331,8 +1331,8 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
while(i) { if(i&1) b++; i>>=1; }
if(ctof(c) && (b&1) && hrand(100) < 20) c->wall = (z&2) ? waCharged : waGrounded;
}
else if(prod) {
cell *c1 = product::get_where(c).first;
else if(hybri) {
cell *c1 = hybrid::get_where(c).first;
if(among(c1->wall, waCharged, waGrounded))
c->wall = c1->wall;
else if(hrand(100) < 15)
@ -2565,11 +2565,11 @@ EX void setdist(cell *c, int d, cell *from) {
if(d <= 10 - getDistLimit()) lastexplore = shmup::on ? shmup::curtime : turncount;
if(prod) {
auto wc = product::get_where(c).first;
auto wf = from ? product::get_where(from).first : NULL;
if(hybri) {
auto wc = hybrid::get_where(c).first;
auto wf = from ? hybrid::get_where(from).first : NULL;
if(c->land && !wc->land) wc->land = c->land;
product::in_underlying_map([&] { setdist(wc, d, wf); });
hybrid::in_underlying_map([&] { setdist(wc, d, wf); });
}
if(buggyGeneration) {
@ -2634,7 +2634,7 @@ EX void setdist(cell *c, int d, cell *from) {
#if MAXMDIM == 4
else if(euclid && WDIM == 3) euclid3::set_land(c);
#endif
else if(prod) setLandProduct(c);
else if(hybri) setLandHybrid(c);
else if(sphere || fulltorus) setLandSphere(c);
else if(euclid) setLandEuclid(c);
else if(quotient) { setland(c, specialland); setLandQuotient(c); }

View File

@ -679,13 +679,13 @@ EX land_validity_t& land_validity(eLand l) {
using namespace lv;
if(prod || product::pmap) {
if(hybri || hybrid::pmap) {
if(among(l, laPrincessQuest, laPrairie, laMirrorOld, laMirror, laDual, laWarpCoast, laKraken, laBrownian, laWhirlpool, laWestWall, laHive, laClearing, laWhirlwind, laBlizzard, laBull, laTerracotta, laCrossroads5,
laEndorian, laDungeon, laMountain))
return lv::not_implemented;
if(among(l, laReptile, laDragon, laTortoise))
return lv::bad_graphics;
if(prod) return *PIU(&land_validity(l));
if(hybri) return *PIU(&land_validity(l));
}
#if !CAP_FIELD

View File

@ -748,7 +748,7 @@ EX void generateSnake(cell *c, int i, int snakecolor) {
c2 = c3;
c2->monst = moHexSnakeTail; c2->hitpoints = snakecolor;
int t = c2->type;
if(prod) t -= 2;
if(hybri) t -= 2;
i = (j + (t%4 == 0 ? t/2 : (len%2 ? 2 : t - 2))) % t;
createMov(c2, i);
if(!inpair(c2->move(i), cpair)) {

View File

@ -10,7 +10,6 @@ namespace hr {
EX namespace nisot {
typedef array<float, 3> ptlow;
EX int current_view_level;
EX transmatrix local_perspective;
#if HDR
inline bool local_perspective_used() { return nonisotropic || prod; }
@ -549,24 +548,26 @@ EX namespace nilv {
}
EX }
EX namespace product {
EX namespace hybrid {
EX int current_view_level;
EX eGeometry underlying;
EX geometry_information *underlying_cgip;
void configure() {
EX void configure(eGeometry g) {
if(g == gSL2) variation = eVariation::pure;
if(vid.always3) { vid.always3 = false; geom3::apply_always3(); }
check_cgi();
cgi.prepare_basics();
underlying = geometry;
underlying_cgip = cgip;
geometry = gProduct;
geometry = g;
ginf[gProduct] = ginf[underlying];
ginf[gProduct].cclass = gcProduct;
ginf[gProduct].g.gameplay_dimension++;
ginf[gProduct].g.graphical_dimension++;
}
hrmap *pmap;
geometry_information *pcgip;
@ -578,7 +579,7 @@ EX namespace product {
return t();
}
struct hrmap_product : hrmap {
struct hrmap_hybrid : hrmap {
hrmap *underlying_map;
@ -597,6 +598,7 @@ EX namespace product {
}
cell *getCell(cell *u, int h) {
if(sl2) h = gmod(h, 14);
cell*& c = at[make_pair(u, h)];
if(!c) { c = newCell(u->type+2, u->master); where[c] = {u, h}; }
return c;
@ -604,38 +606,78 @@ EX namespace product {
cell* gamestart() override { return getCell(underlying_map->gamestart(), 0); }
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) override {
return in_underlying([&] { return calc_relative_matrix(where[c2].first, where[c1].first, point_hint); }) * mscale(Id, cgi.plevel * (where[c2].second - where[c1].second));
}
hrmap_product() {
hrmap_hybrid() {
in_underlying([this] { initcells(); underlying_map = currentmap; });
for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL;
}
~hrmap_product() {
~hrmap_hybrid() {
in_underlying([this] { delete currentmap; });
for(auto& p: at) tailored_delete(p.second);
}
};
hrmap_hybrid* hmap() { return (hrmap_hybrid*) currentmap; }
EX cell *get_at(cell *base, int level) {
return hmap()->getCell(base, level);
}
EX pair<cell*, int> get_where(cell *c) { return hmap()->where[c]; }
void find_cell_connection(cell *c, int d) {
auto m = hmap();
if(d >= c->type - 2) {
cell *c1 = get_at(m->where[c].first, m->where[c].second + (d == c->type-1 ? 1 : -1));
c->c.connect(d, c1, c1->type - 3 + c->type - d, false);
}
else {
auto cu = m->where[c].first;
auto cu1 = m->in_underlying([&] { return cu->cmove(d); });
int d1 = cu->c.spin(d);
int s = sl2 ? - d1*2 + d*2 + 7 : 0;
cell *c1 = get_at(cu1, m->where[c].second + s);
c->c.connect(d, c1, d1, cu->c.mirror(d));
}
}
EX void in_underlying_map(const reaction_t& f) {
if(!hybri) f();
else hmap()->in_underlying(f);
}
#if HDR
template<class T> auto in_underlying_geometry(const T& f) -> decltype(f()) {
if(!hybri) return f();
dynamicval<eGeometry> g(geometry, underlying);
dynamicval<geometry_information*> gc(cgip, underlying_cgip);
return f();
}
#define PIU(x) hr::hybrid::in_underlying_geometry([&] { return (x); })
#endif
EX }
EX namespace product {
struct hrmap_product : hybrid::hrmap_hybrid {
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) override {
return in_underlying([&] { return calc_relative_matrix(where[c2].first, where[c1].first, point_hint); }) * mscale(Id, cgi.plevel * (where[c2].second - where[c1].second));
}
void draw() override {
in_underlying([this] { currentmap->draw(); });
}
};
EX cell *get_at(cell *base, int level) {
return ((hrmap_product*)currentmap)->getCell(base, level);
}
EX pair<cell*, int> get_where(cell *c) { return ((hrmap_product*)currentmap)->where[c]; }
EX int cwall_offset, cwall_mask;
void drawcell_stack(cell *c, transmatrix V, int spinv, bool mirrored) {
if(sphere) gmatrix[c] = V; /* some computations need gmatrix0 for underlying geometry */
bool s = sphere;
in_actual([&] {
cell *c0 = get_at(c, nisot::current_view_level);
hybrid::in_actual([&] {
cell *c0 = hybrid::get_at(c, hybrid::current_view_level);
cwall_offset = wall_offset(c0);
if(s) cwall_mask = (1<<c->type) - 1;
else {
@ -653,47 +695,33 @@ EX namespace product {
for(int z=-max_z; z<=max_z; z++) {
if(z == 0) cwall_mask ^= (2<<c->type);
if(z == 1) cwall_mask ^= (1<<c->type);
cell *c1 = get_at(c, nisot::current_view_level+z);
cell *c1 = hybrid::get_at(c, hybrid::current_view_level+z);
setdist(c1, 7, NULL);
drawcell(c1, V * mscale(Id, cgi.plevel * z), spinv, mirrored);
}
});
}
void find_cell_connection(cell *c, int d) {
auto m = (hrmap_product*)currentmap;
if(d >= c->type - 2) {
cell *c1 = get_at(m->where[c].first, m->where[c].second + (d == c->type-1 ? 1 : -1));
c->c.connect(d, c1, c1->type - 3 + c->type - d, false);
}
else {
auto cu = m->where[c].first;
auto cu1 = m->in_underlying([&] { return cu->cmove(d); });
cell *c1 = get_at(cu1, m->where[c].second);
c->c.connect(d, c1, cu->c.spin(d), cu->c.mirror(d));
}
}
EX hyperpoint get_corner(cell *c, int i, ld z) {
ld lev = cgi.plevel * z / 2;
dynamicval<eGeometry> g(geometry, underlying);
dynamicval<geometry_information*> gc(cgip, underlying_cgip);
dynamicval<eGeometry> g(geometry, hybrid::underlying);
dynamicval<geometry_information*> gc(cgip, hybrid::underlying_cgip);
return mscale(get_corner_position(c, i), exp(lev));
}
EX int wall_offset(cell *c) {
int id = underlying == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c);
int id = hybrid::underlying == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c);
if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, -1);
int &wo = cgi.walloffsets[id];
if(wo == -1) {
cell *c1 = get_where(c).first;
cell *c1 = hybrid::get_where(c).first;
wo = isize(cgi.shWall3D);
int won = wo + c->type;
cgi.reserve_wall3d(won);
for(int i=0; i<c1->type; i++) {
hyperpoint w;
in_underlying_geometry([&] {
hybrid::in_underlying_geometry([&] {
/* mirror image of C0 in the axis h1-h2 */
hyperpoint h1 = get_corner_position(c1, i);
hyperpoint h2 = get_corner_position(c1, i+1);
@ -722,7 +750,7 @@ EX namespace product {
return wo;
}
EX bool product_sphere() { return ginf[underlying].cclass == gcSphere; }
EX bool product_sphere() { return ginf[hybrid::underlying].cclass == gcSphere; }
EX hyperpoint inverse_exp(hyperpoint h) {
hyperpoint res;
@ -752,22 +780,6 @@ EX namespace product {
return zshift(res, h[2]);
}
EX void in_underlying_map(const reaction_t& f) {
if(!prod) f();
else ((hrmap_product*)currentmap)->in_underlying(f);
}
#if HDR
template<class T> auto in_underlying_geometry(const T& f) -> decltype(f()) {
if(!prod) return f();
dynamicval<eGeometry> g(geometry, underlying);
dynamicval<geometry_information*> gc(cgip, underlying_cgip);
return f();
}
#define PIU(x) hr::product::in_underlying_geometry([&] { return (x); })
#endif
EX }
EX namespace slr {
@ -1025,30 +1037,8 @@ EX namespace slr {
return spin(2 * M_PI * i / 7) * xpush(tessf7/2) * spin(M_PI - 2 * M_PI * j / 7);
}
struct hrmap_psl2 : hrmap {
struct hrmap_psl2 : hybrid::hrmap_hybrid {
hrmap *underlying_map;
map<pair<cell*, int>, cell*> at;
map<cell*, pair<cell*, int>> where;
heptagon *getOrigin() override { return underlying_map->getOrigin(); }
template<class T> auto in_underlying(const T& t) -> decltype(t()) {
dynamicval<eGeometry> g(geometry, gNormal);
dynamicval<hrmap*> gu(currentmap, underlying_map);
return t();
}
cell *getCell(cell *u, int h) {
h = gmod(h, 14);
cell*& c = at[make_pair(u, h)];
if(!c) { c = newCell(u->type+2, u->master); where[c] = {u, h}; }
return c;
}
cell* gamestart() override { return getCell(underlying_map->gamestart(), 0); }
virtual transmatrix relative_matrix(cell *c2, cell *c1, const struct hyperpoint& point_hint) override {
for(int i=0; i<c1->type; i++) if(c1->move(i) == c2) return adjmatrix(i, c1->c.spin(i));
if(gmatrix0.count(c2) && gmatrix0.count(c1))
@ -1082,40 +1072,8 @@ EX namespace slr {
}
}
}
hrmap_psl2() {
in_underlying([this] { initcells(); underlying_map = currentmap; });
for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL;
}
~hrmap_psl2() {
in_underlying([this] { delete currentmap; });
for(auto& p: at) tailored_delete(p.second);
}
};
EX cell *get_at(cell *base, int level) {
return ((hrmap_psl2*)currentmap)->getCell(base, level);
}
EX pair<cell*, int> get_where(cell *c) { return ((hrmap_psl2*)currentmap)->where[c]; }
void find_cell_connection(cell *c, int d) {
auto m = (hrmap_psl2*)currentmap;
if(d >= c->type - 2) {
cell *c1 = get_at(m->where[c].first, m->where[c].second + (d == c->type-1 ? 1 : -1));
c->c.connect(d, c1, c1->type - 3 + c->type - d, false);
}
else {
auto cu = m->where[c].first;
auto cu1 = m->in_underlying([&] { return cu->cmove(d); });
int d1 = cu->c.spin(d);
cell *c1 = get_at(cu1, m->where[c].second - d1*2 + d*2 + 7);
c->c.connect(d, c1, d1, false);
}
}
EX }
EX namespace nisot {

View File

@ -56,7 +56,7 @@ int eupattern4(cell *c) {
EX bool ishept(cell *c) {
// EUCLIDEAN
if(euclid) return eupattern(c) == 0;
else return c->type == S7 + (prod ? 2 : 0);
else return c->type == S7 + (hybri ? 2 : 0);
}
EX bool ishex1(cell *c) {
@ -372,10 +372,10 @@ EX pair<int, bool> fieldval(cell *c) {
EX int fieldval_uniq(cell *c) {
if(experimental) return 0;
else if(prod) {
auto c1 = product::get_where(c).first;
else if(hybri) {
auto c1 = hybrid::get_where(c).first;
int res;
product::in_underlying_map([&] { res = fieldval_uniq(c1); });
hybrid::in_underlying_map([&] { res = fieldval_uniq(c1); });
return res;
}
else if(sphere) {
@ -409,10 +409,10 @@ EX int fieldval_uniq(cell *c) {
}
EX int fieldval_uniq_rand(cell *c, int randval) {
if(prod) {
auto c1 = product::get_where(c).first;
if(hybri) {
auto c1 = hybrid::get_where(c).first;
int res;
product::in_underlying_map([&] { res = fieldval_uniq_rand(c1, randval); });
hybrid::in_underlying_map([&] { res = fieldval_uniq_rand(c1, randval); });
return res;
}
if(sphere || euclid || NONSTDVAR)
@ -1374,7 +1374,7 @@ EX bool pseudohept(cell *c) {
#if CAP_IRR
if(IRREGULAR) return irr::pseudohept(c);
#endif
if(prod) { auto d = product::get_where(c); return (d.second & 1) && PIU(pseudohept(d.first)); }
if(hybri) { auto d = hybrid::get_where(c); return (sl2 ? true : (d.second & 1)) && PIU(pseudohept(d.first)); }
#if CAP_BT
if(nil) return c->master->zebraval & c->master->emeraldval & c->master->fieldval & 1;
if(sol) return (c->master->emeraldval % 3 == 2) && (c->master->zebraval % 3 == 2) && (c->master->distance % 2);

View File

@ -1113,7 +1113,7 @@ void geometry_information::prepare_shapes() {
#endif
DEBBI(DF_POLY, ("buildpolys"));
if(WDIM == 3 && !prod) {
if(WDIM == 3 && !hybri) {
if(sphere) SD3 = 3, SD7 = 5;
else SD3 = SD7 = 4;
}

View File

@ -872,7 +872,7 @@ EX void saveStats(bool emergency IS(false)) {
if(randomPatternsMode) return;
if(dual::state) return;
if(archimedean) return;
if(prod) return;
if(hybri) return;
if(daily::on) return;
if(peace::on) return;
if(!gold()) return;
@ -1159,7 +1159,7 @@ EX void set_geometry(eGeometry target) {
int old_DIM = GDIM;
stop_game();
ors::reset();
if(target == gProduct) product::configure();
if(among(target, gProduct, gSL2)) hybrid::configure(target);
geometry = target;
if(chaosmode && bounded) chaosmode = false;
@ -1288,7 +1288,7 @@ EX void switch_game_mode(char switchWhat) {
chaosmode = false;
princess::challenge = false;
if(sol || bounded) set_geometry(gNormal);
if(prod) set_geometry(product::underlying);
if(prod) set_geometry(hybrid::underlying);
dual::disable();
break;
#endif
@ -1310,7 +1310,7 @@ EX void switch_game_mode(char switchWhat) {
shmup::on = !shmup::on;
princess::challenge = false;
if(!shmup::on) racing::on = false;
if(prod) set_geometry(product::underlying);
if(prod) set_geometry(hybrid::underlying);
break;
case rg::randpattern:

View File

@ -219,7 +219,7 @@ EX namespace yendor {
nyi.path[0] = yendor;
}
else if(prod) {
else if(hybri) {
/* I am lazy */
for(int i=1; i<=YDIST-1; i++) nyi.path[i] = nyi.path[i-1]->cmove(nyi.path[i-1]->type-1);
}
@ -1055,7 +1055,7 @@ int modecodetable[42][6] = {
modecode_t modecode() {
// bit 61: product
if(prod) return PIU(modecode()) | (1ll << 61);
if(hybri) return PIU(modecode()) | (1ll << 61);
#if CAP_SAVE
if(anticheat::tampered || cheater || geometry >= gGUARD) return 6;
#endif