extra guards

This commit is contained in:
Zeno Rogue 2020-10-15 16:33:52 +02:00
parent 76462aa1e7
commit d64c5e338c
41 changed files with 266 additions and 32 deletions

View File

@ -89,8 +89,6 @@ struct archimedean_tiling {
};
#endif
#if CAP_ARCM
#if HDR
static const int sfPH = 1;
static const int sfLINE = 2;
@ -99,6 +97,8 @@ static const int sfTHREE = 8;
static const int sfSEMILINE = 16;
#endif
#if CAP_ARCM
EX archimedean_tiling current;
EX archimedean_tiling fake_current;
@ -1450,10 +1450,10 @@ EX int valence() {
return total / isize(current.faces);
}
#endif
EX map<gp::loc, cdata>& get_cdata() { return ((arcm::hrmap_archimedean*) (currentmap))->eucdata; }
#endif
EX }
}

View File

@ -79,7 +79,14 @@ int utfsize(char c) {
}
EX int get_sightrange() { return getDistLimit() + sightrange_bonus; }
EX int get_sightrange_ambush() { return max(get_sightrange(), ambush::distance); }
EX int get_sightrange_ambush() {
#if CAP_COMPLEX2
return max(get_sightrange(), ambush::distance);
#else
return get_sightrange();
#endif
}
bool display_data::in_anaglyph() { return vid.stereo_mode == sAnaglyph; }
bool display_data::stereo_active() { return vid.stereo_mode != sOFF; }
@ -603,7 +610,9 @@ EX void resetGL() {
matched_programs.clear();
glhr::current_glprogram = nullptr;
ray::reset_raycaster();
#if CAP_RUG
if(rug::glbuf) rug::close_glbuf();
#endif
}
#endif
@ -1161,7 +1170,9 @@ EX void initgraph() {
#if CAP_CONFIG
loadConfig();
#endif
#if CAP_ARCM
arcm::current.parse();
#endif
if(hybri) geometry = hybrid::underlying;
#if CAP_COMMANDLINE

View File

@ -21,6 +21,7 @@ EX int newRoundTableRadius() {
return 28 + 2 * items[itHolyGrail];
}
#if CAP_COMPLEX2
EX int getAnthraxData(cell *c, bool b) {
int d = celldistAlt(c);
int rad = 28 + 3 * camelot::anthraxBonus;
@ -36,10 +37,13 @@ EX int getAnthraxData(cell *c, bool b) {
if(b) return rad;
return d;
}
#endif
EX int roundTableRadius(cell *c) {
if(eubinary) return 28;
#if CAP_COMPLEX2
if(tactic::on) return getAnthraxData(c, true);
#endif
if(!c->master->alt) return 28;
return c->master->alt->alt->emeraldval & GRAIL_RADIUS_MASK;
}
@ -55,7 +59,9 @@ EX int celldistAltRelative(cell *c) {
if(sphere || quotient) {
return celldist(c) - 3;
}
#if CAP_COMPLEX2
if(tactic::on) return getAnthraxData(c, false);
#endif
return celldistAlt(c) - roundTableRadius(c);
}
@ -1805,12 +1811,14 @@ EX void moreBigStuff(cell *c) {
if(c->master->emeraldval % 2)
c->wall = waColumn;
}
#if CAP_BT
else if(geometry == gHoroTris || geometry == gHoroRec) {
if(c->c.spin(bt::updir()) != 0) c->wall = waColumn;
}
else if(geometry == gKiteDart3) {
if(kite::getshape(c->master) == kite::pKite) c->wall = waColumn;
}
#endif
else if(in_s2xe()) {
auto d = hybrid::get_where(c);
if(!PIU(pseudohept(d.first))) c->wall = waColumn;

View File

@ -18,6 +18,10 @@ EX namespace bt {
return false;
#endif
}
#if !CAP_BT
EX int updir() { return 0; }
#endif
#if CAP_BT
#if HDR
@ -1031,7 +1035,6 @@ EX int celldistance3(heptagon *c1, heptagon *c2) {
}
EX int celldistance3(cell *c1, cell *c2) { return celldistance3(c1->master, c2->master); }
#endif
EX hyperpoint get_horopoint(ld y, ld x) {
return xpush(-y) * bt::parabolic(x) * C0;
@ -1091,6 +1094,7 @@ EX hyperpoint get_corner_horo_coordinates(cell *c, int i) {
auto hooksw = addHook(hooks_swapdim, 100, [] {
if(bt::in()) build_tmatrix();
});
#endif
}

View File

@ -179,8 +179,11 @@ EX heptagon* hyperbolic_origin() {
h.cdata = NULL;
h.alt = NULL;
h.distance = 0;
#if CAP_IRR
if(IRREGULAR) irr::link_start(origin);
else h.c7 = newCell(odegree, origin);
else
#endif
h.c7 = newCell(odegree, origin);
return origin;
}
@ -554,7 +557,9 @@ EX int celldistAlt(cell *c) {
/** direction upwards in the tree */
EX int updir(heptagon *h) {
#if CAP_BT
if(bt::in()) return bt::updir();
#endif
#if MAXMDIM >= 4
if(WDIM == 3 && reg3::in_rule()) {
for(int i=0; i<S7; i++) if(h->move(i) && h->move(i)->distance < h->distance)
@ -815,10 +820,12 @@ cdata *getHeptagonCdata(heptagon *h) {
if(sphere || quotient) h = currentmap->gamestart()->master;
bool starting = h->s == hsOrigin;
#if CAP_BT
if(bt::in()) {
if(bt::mapside(h) == 0) starting = true;
for(int i=0; i<h->type; i++) if(bt::mapside(h->cmove(i)) == 0) starting = true;
}
#endif
if(starting) {
h->cdata = new cdata(orig_cdata);
@ -866,7 +873,12 @@ cdata *getHeptagonCdata(heptagon *h) {
cdata *getEuclidCdata(gp::loc h) {
int x = h.first, y = h.second;
#if CAP_ARCM
auto& data = arcm::in() ? arcm::get_cdata() : euc::get_cdata();
#else
auto& data = euc::get_cdata();
#endif
// hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap);
if(data.count(h)) return &(data[h]);
@ -918,6 +930,7 @@ int ld_to_int(ld x) {
return int(x + 1000000.5) - 1000000;
}
#if CAP_ARCM
EX gp::loc pseudocoords(cell *c) {
transmatrix T = arcm::archimedean_gmatrix[c->master].second;
return {ld_to_int(T[0][LDIM]), ld_to_int((spin(60*degree) * T)[0][LDIM])};
@ -935,6 +948,7 @@ EX cdata *arcmCdata(cell *c) {
dynamicval<hrmap*> cm(currentmap, arcm::current_altmap);
return getHeptagonCdata(h2);
}
#endif
EX int getCdata(cell *c, int j) {
if(fake::in()) return FPIU(getCdata(c, j));
@ -944,10 +958,12 @@ EX int getCdata(cell *c, int j) {
return UIU(getCdata(c1, j));
}
else if(euc::in()) return getEuclidCdata(euc2_coordinates(c))->val[j];
#if CAP_ARCM
else if(arcm::in() && euclid)
return getEuclidCdata(pseudocoords(c))->val[j];
else if(arcm::in() && hyperbolic)
return arcmCdata(c)->val[j]*3;
#endif
else if(!geometry_supports_cdata()) return 0;
else if(ctof(c)) return getHeptagonCdata(c->master)->val[j]*3;
else {
@ -967,10 +983,12 @@ EX int getBits(cell *c) {
return UIU(getBits(c1));
}
else if(euc::in()) return getEuclidCdata(euc2_coordinates(c))->bits;
else if(arcm::in() && euclid)
#if CAP_ARCM
else if(arcm::in() && euclid)
return getEuclidCdata(pseudocoords(c))->bits;
else if(arcm::in() && (hyperbolic || sl2))
return arcmCdata(c)->bits;
#endif
else if(!geometry_supports_cdata()) return 0;
else if(c == c->master->c7) return getHeptagonCdata(c->master)->bits;
else {

View File

@ -534,11 +534,13 @@ void celldrawer::setcolors() {
break;
case waMineUnknown: case waMineMine:
#if CAP_COMPLEX2
if(mine::marked_safe(c))
fcol = wcol = gradient(wcol, 0x40FF40, 0, 0.2, 1);
else if(mine::marked_mine(c))
fcol = wcol = gradient(wcol, 0xFF4040, -1, sintick(100), 1);
// fallthrough
#endif
case waMineOpen:
if(wmblack || wmascii) {
@ -1352,7 +1354,9 @@ void celldrawer::draw_features() {
}
case waTerraWarrior:
#if CAP_COMPLEX2
drawTerraWarrior(V, terracotta::randterra ? (c->landparam & 7) : (5 - (c->landparam & 7)), 7, 0);
#endif
break;
case waBoat: case waStrandedBoat:

View File

@ -2800,12 +2800,18 @@ EX namespace sword {
EX void determine_sword_angles() {
sword_angles = 2;
if(SWORDDIM == 3) sword_angles = 1;
#if CAP_IRR
else if(IRREGULAR) sword_angles = 840;
#endif
#if CAP_BT
else if(bt::in()) sword_angles = 42;
#endif
#if CAP_ARCM
else if(arcm::in()) {
if(!PURE) possible_divisor((BITRUNCATED ? 2 : 1) * isize(arcm::current.faces));
if(!DUAL) for(int f: arcm::current.faces) possible_divisor(f);
}
#endif
else {
possible_divisor(S7);
if(BITRUNCATED) possible_divisor(S3);

View File

@ -577,7 +577,9 @@ EX void initConfig() {
addsaverenum(pconf.basic_model, "basic model");
addsaver(pconf.use_atan, "use_atan");
#if CAP_ARCM
addsaver(arcm::current.symbol, "arcm-symbol", "4^5");
#endif
addsaverenum(hybrid::underlying, "product-underlying");
for(int i=0; i<isize(ginf); i++) {

View File

@ -480,11 +480,13 @@ EX void handleKeyNormal(int sym, int uni) {
}
#endif
#if CAP_COMPLEX2
if(DEFAULTNOR(sym)) {
gmodekeys(sym, uni);
if(uni == 'm' && canmove && (centerover == cwt.at ? mouseover : centerover))
mine::performMarkCommand(mouseover);
}
#endif
if(DEFAULTCONTROL) {
if(sym == '.' || sym == 's') movepcto(-1, 1);

View File

@ -9,7 +9,6 @@
namespace hr {
EX namespace crystal {
#if CAP_CRYSTAL
#if HDR
static const int MAXDIM = 7;
@ -34,6 +33,8 @@ struct ldcoord : public array<ld, MAXDIM> {
static const ldcoord ldc0 = {};
#endif
#if CAP_CRYSTAL
/** Crystal can be bitruncated either by changing variation to bitruncated.
* In case of the 4D Crystal, the standard HyperRogue bitruncation becomes
* confused by having both the original and new vertices of degree 8.

View File

@ -721,12 +721,14 @@ int read_cheat_args() {
inv::compute();
}
#endif
#if CAP_COMPLEX2
else if(argis("-ambush")) {
// make all ambushes use the given number of dogs
// example: hyper -W Hunt -IP Shield 1 -ambush 60
PHASE(3) cheat();
shift(); ambush::fixed_size = argi();
}
#endif
else if(argis("-testdistances")) {
PHASE(3); shift(); test_distances(argi());
}

View File

@ -93,9 +93,11 @@ void launch(int seed, int elimit, int hlimit) {
cl1 = cl.lst;
for(cell *c: cl.lst) {
c->wall = waNone, c->land = laCanvas;
#if CAP_ARCM
int id = arcm::current.tilegroup[arcm::id_of(c->master)];
color_t yellows[5] = { 0x80C080, 0x80C0C0, 0x8080C0, 0xC080C0, 0xC0C080 };
c->landparam = yellows[id];
#endif
}
println(hlog, "c1 size = ", isize(cl.lst));
}

View File

@ -150,11 +150,13 @@ EX namespace euc {
tmatrix[i] = eumove(shifttable[i]);
camelot_center = NULL;
build_torus3(geometry);
#if CAP_IRR
if(!valid_irr_torus()) {
addMessage(XLAT("Error: period mismatch"));
eu_input = irr::base_config;
build_torus3(geometry);
}
#endif
}
heptagon *getOrigin() override {
@ -168,6 +170,7 @@ EX namespace euc {
auto h = tailored_alloc<heptagon> (S7);
if(!IRREGULAR)
h->c7 = newCell(S7, h);
#if CAP_IRR
else {
coord m0 = shifttable[0];
transmatrix dummy;
@ -180,6 +183,7 @@ EX namespace euc {
break;
}
}
#endif
h->distance = 0;
h->cdata = NULL;
h->alt = NULL;
@ -534,6 +538,7 @@ EX namespace euc {
}
EX bool valid_irr_torus() {
#if CAP_IRR
if(!IRREGULAR) return true;
if(eu.twisted) return false;
for(int i=0; i<2; i++) {
@ -547,6 +552,7 @@ EX namespace euc {
eu.canonicalize(x0, dm0, dummy, mirr);
if(x0 != euzero || dm0 != eutester) return false;
}
#endif
return true;
}

View File

@ -81,7 +81,9 @@ EX namespace fake {
transmatrix S1, S2;
ld dist;
in_underlying([c, d, &S1, &S2, &dist] {
#if CAP_ARCM
dynamicval<bool> u(arcm::use_gmatrix, false);
#endif
transmatrix T = currentmap->adj(c, d);
S1 = rspintox(tC0(T));
transmatrix T1 = spintox(tC0(T)) * T;
@ -89,12 +91,16 @@ EX namespace fake {
S2 = xpush(-dist) * T1;
});
#if CAP_ARCM
if(arcm::in()) {
int t = arcm::id_of(c->master);
int t2 = arcm::id_of(c->move(d)->master);
auto& cof = arcm::current_or_fake();
cgi.adjcheck = cof.inradius[t/2] + cof.inradius[t2/2];
}
#else
if(0) ;
#endif
else if(WDIM == 2) {
@ -400,7 +406,9 @@ EX ld around;
/** @brief the value of 'around' which makes the tiling Euclidean */
EX ld compute_euclidean() {
#if CAP_ARCM
if(arcm::in()) return arcm::current.N * 2 / arcm::current.euclidean_angle_sum;
#endif
if(WDIM == 2) return 4 / (S7-2.) + 2;
if(underlying == gRhombic3) return 3;
@ -411,8 +419,10 @@ EX ld compute_euclidean() {
}
EX ld around_orig() {
#if CAP_ARCM
if(arcm::in())
return arcm::current.N;
#endif
if(WDIM == 2)
return S3;
if(underlying == gRhombic3)

View File

@ -886,24 +886,30 @@ EX int shvid(cell *c) {
}
else if(GOLDBERG_INV)
return gp::get_plainshape_id(c);
#if CAP_IRR
else if(IRREGULAR)
return irr::cellindex[c];
#endif
#if CAP_ARCM
else if(arcm::in()) {
auto& ac = arcm::current;
int id = arcm::id_of(c->master);
if(ac.regular && id>=2 && id < 2*ac.N) id &= 1;
return id;
}
#endif
else if(arb::in())
return arb::id_of(c->master);
else if(geosupport_football() == 2)
return pseudohept(c);
#if CAP_BT
else if(geometry == gBinaryTiling)
return c->type-6;
else if(kite::in())
return kite::getshape(c->master);
else if(geometry == gBinary4 || geometry == gTernary)
return c->master->zebraval;
#endif
else if(inforder::mixed()) {
int t = c->type;
static vector<bool> computed;

View File

@ -300,6 +300,7 @@ void set_or_configure_geometry(eGeometry g) {
addMessage(XLAT("Only works with (semi-)regular tilings"));
return;
}
#if CAP_ARCM
if(arcm::in()) {
int steps, single_step;
if(!arcm::current.get_step_values(steps, single_step)) {
@ -307,6 +308,7 @@ void set_or_configure_geometry(eGeometry g) {
return;
}
}
#endif
}
}
dual::may_split_or_do([g] { set_geometry(g); });
@ -542,8 +544,10 @@ EX void select_quotient_screen() {
}
else if(g == gFieldQuotient)
pushScreen(showQuotientConfig);
#if CAP_CRYSTAL
else if(g == gCrystal)
pushScreen(crystal::show);
#endif
else {
dual::may_split_or_do([g] { set_geometry(g); });
start_game();
@ -709,7 +713,9 @@ EX void showEuclideanMenu() {
worldsize = euc::eu.det;
if(BITRUNCATED) worldsize *= (a4 ? 2 : 3);
if(GOLDBERG) worldsize *= cgi.gpdata->area;
#if CAP_IRR
if(IRREGULAR) worldsize *= isize(irr::cells) / isize(irr::cells_of_heptagon);
#endif
}
else
worldsize = denom ? nom / denom : 0;
@ -796,15 +802,19 @@ EX void showEuclideanMenu() {
dialog::add_action(select_quotient);
#if CAP_ARCM
if(arcm::in()) {
dialog::addItem(XLAT("advanced parameters"), '4');
dialog::add_action_push(arcm::show);
}
#endif
#if CAP_CRYSTAL
if(cryst) {
dialog::addItem(XLAT("advanced parameters"), '4');
dialog::add_action_push(crystal::show);
}
#endif
if(fake::available()) {
dialog::addItem(XLAT("fake curvature"), '4');

View File

@ -673,8 +673,12 @@ void geometry_information::prepare_basics() {
plevel = vid.plevel_factor * scalefactor;
single_step = 1;
if(hybri && !prod) {
#if CAP_ARCM
if(hybrid::underlying == gArchimedean)
arcm::current.get_step_values(psl_steps, single_step);
#else
if(0) ;
#endif
else {
single_step = S3 * S7 - 2 * S7 - 2 * S3;
psl_steps = 2 * S7;
@ -914,7 +918,7 @@ EX void apply_always3() {
#if MAXMDIM >= 4
EX void switch_always3() {
if(dual::split(switch_always3)) return;
#if CAP_GL
#if CAP_GL && CAP_RUG
if(rug::rugged) rug::close();
#endif
vid.always3 = !vid.always3;
@ -947,7 +951,7 @@ EX void switch_always3() {
EX void switch_fpp() {
#if MAXMDIM >= 4
#if CAP_GL
#if CAP_GL && CAP_RUG
if(rug::rugged) rug::close();
#endif
if(dual::split(switch_fpp)) return;
@ -1027,7 +1031,9 @@ EX string cgi_string() {
if(GOLDBERG_INV) V("GP", its(gp::param.first) + "," + its(gp::param.second));
if(IRREGULAR) V("IRR", its(irr::irrid));
#if CAP_ARCM
if(arcm::in()) V("ARCM", arcm::current.symbol);
#endif
if(arb::in()) V("ARB", its(arb::current.order));

View File

@ -398,6 +398,7 @@ ld hrmap_standard::spin_angle(cell *c, int d) {
ld hexshift = 0;
if(c == c->master->c7 && (S7 % 2 == 0) && BITRUNCATED) hexshift = cgi.hexshift + 2*M_PI/c->type;
else if(cgi.hexshift && c == c->master->c7) hexshift = cgi.hexshift;
#if CAP_IRR
if(IRREGULAR) {
auto id = irr::cellindex[c];
auto& vs = irr::cells[id];
@ -405,8 +406,8 @@ ld hrmap_standard::spin_angle(cell *c, int d) {
auto& p = vs.jpoints[vs.neid[d]];
return -atan2(p[1], p[0]) - hexshift;
}
else
return M_PI - d * 2 * M_PI / c->type - hexshift;
#endif
return M_PI - d * 2 * M_PI / c->type - hexshift;
}
EX transmatrix ddspin(cell *c, int d, ld bonus IS(0)) { return currentmap->spin_to(c, d, bonus); }

View File

@ -806,6 +806,7 @@ EX namespace gp {
dialog::addBreak(100);
#if CAP_IRR
if(irr::supports(geometry)) {
dialog::addBoolItem(XLAT("irregular"), IRREGULAR, 'i');
dialog::add_action(dialog::add_confirmation([=] () {
@ -817,6 +818,7 @@ EX namespace gp {
if(!IRREGULAR) irr::visual_creator();
}));
}
#endif
dialog::addBreak(100);
int style = 0;

View File

@ -1020,7 +1020,11 @@ EX void drawTerraWarrior(const shiftmatrix& V, int t, int hp, double footphase)
EX void drawPlayer(eMonster m, cell *where, const shiftmatrix& V, color_t col, double footphase, bool stop IS(false)) {
charstyle& cs = getcs();
#if CAP_COMPLEX2
auto& knighted = camelot::knighted;
#else
const bool knighted = false;
#endif
if(mapeditor::drawplayer && !mapeditor::drawUserShape(V, mapeditor::sgPlayer, cs.charid, cs.skincolor, where)) {
@ -1264,8 +1268,10 @@ void drawMimic(eMonster m, cell *where, const shiftmatrix& V, color_t col, doubl
else if(!where || shmup::curtime >= shmup::getPlayer()->nextshot)
queuepoly(VBODY * VBS, cgi.shPKnife, darkena(col, 0, 0XC0));
#if CAP_COMPLEX2
if(camelot::knighted)
queuepoly(VBODY3 * VBS, cgi.shKnightCloak, darkena(col, 1, 0xC0));
#endif
queuepoly(VHEAD1, (cs.charid&1) ? cgi.shFemaleHair : cgi.shPHead, darkena(col, 1, 0XC0));
queuepoly(VHEAD, cgi.shPFace, darkena(col, 0, 0XC0));
@ -3410,7 +3416,11 @@ EX bool placeSidewall(cell *c, int i, int sidepar, const shiftmatrix& V, color_t
#endif
bool openorsafe(cell *c) {
#if CAP_COMPLEX2
return c->wall == waMineOpen || mine::marked_safe(c);
#else
return false;
#endif
}
#define Dark(x) darkena(x,0,0xFF)
@ -3788,7 +3798,9 @@ EX void gridline(const shiftmatrix& V, const hyperpoint h1, const hyperpoint h2,
EX int wall_offset(cell *c) {
if(hybri || WDIM == 2) return hybrid::wall_offset(c);
#if CAP_BT
if(kite::in() && kite::getshape(c->master) == kite::pKite) return 10;
#endif
return 0;
}

View File

@ -928,8 +928,12 @@ EX void describeMouseover() {
if(isReptile(c->wall))
out += " [" + turnstring((unsigned char) c->wparam) + "]";
#if CAP_COMPLEX2
if(c->monst == moKnight)
out += XLAT(", %1 the Knight", camelot::knight_name(c));
#else
if(0) ;
#endif
else if(c->monst) {
out += ", "; out += XLAT1(minf[c->monst].name);
@ -950,10 +954,12 @@ EX void describeMouseover() {
out += ", ";
out += XLAT1(iinf[c->item].name);
if(c->item == itBarrow) out += " (x" + its(c->landparam) + ")";
if(c->land == laHunting) {
#if CAP_COMPLEX2
if(c->land == laHunting) {
int i = ambush::size(c, c->item);
if(i) out += " (" + XLAT("ambush:") + " " + its(i) + ")";
}
#endif
if(c->item == itBabyTortoise && tortoise::seek())
out += " " + tortoise::measure(tortoise::babymap[c]);
if(!c->monst) set_help_to(c->item);
@ -1000,12 +1006,14 @@ EX void describeMouseover() {
callhooks(hooks_mouseover, c);
if(mousey < vid.fsize * 3/2 && getcstat == '-' && !instat) getcstat = SDLK_F1;
#if CAP_TOUR
if(tour::on && !tour::texts) {
if(tour::slides[tour::currentslide].flags & tour::NOTITLE)
mouseovers = "";
else
mouseovers = XLAT(tour::slides[tour::currentslide].name);
}
#endif
}
EX void showHelp() {

View File

@ -11,7 +11,7 @@
#define SCU
#endif
#if CAP_ROGUEVIZ
#if CAP_ROGUEVIZ || defined(MAXMDIM)
#define MAXMDIM 4
#else
#define MAXMDIM 3

View File

@ -2430,8 +2430,10 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
}
break;
case laBrownian:
case laBrownian:
#if CAP_COMPLEX2
brownian::build(c, d);
#endif
break;
case laMirrored:
@ -2807,6 +2809,7 @@ EX void setdist(cell *c, int d, cell *from) {
if(d >= BARLEV) {
#if CAP_BT
if(bt::in() && WDIM == 3 && !c->land && !sn::in()) {
ld z = vid.binary_width;
cell *cseek = c;
@ -2816,6 +2819,7 @@ EX void setdist(cell *c, int d, cell *from) {
while(z < 3.999 && step < 10) cseek = cseek->cmove(bt::updir()), z *= scale;
if(cseek->master->emeraldval) setland(c, eLand(cseek->master->emeraldval));
}
#endif
if(!c->land && from && (WDIM == 3 || !among(from->land, laBarrier, laElementalWall, laHauntedWall, laOceanWall)) && !quotient && !(chaosmode > 1)) {
if(!hasbardir(c)) setland(c, from->land);

View File

@ -318,10 +318,12 @@ EX eItem wanderingTreasure(cell *c) {
/** generate the wandering monsters */
EX void wandering() {
#if CAP_COMPLEX2
if(mine::in_minesweeper()) {
mine::count_status();
return;
}
#endif
if(!canmove) return;
if(!gen_wandering) return;
if(racing::on) return;

View File

@ -295,11 +295,17 @@ EX namespace dual {
}
else {
variation = eVariation::pure;
#if CAP_ARCM
geometry = s == 0 ? gEuclidSquare : gArchimedean;
#else
geometry = gEuclidSquare;
#endif
}
firstland = specialland = laCrossroads4;
#if CAP_ARCM
if(geometry == gArchimedean)
arcm::current.parse("4,4,4,4,4");
#endif
check_cgi();
cgi.require_basics();
dgd[s].storegame();

View File

@ -1355,7 +1355,11 @@ EX namespace hybrid {
gp::draw_li = WDIM == 2 ? gp::get_local_info(c1) : PIU(gp::get_local_info(c1));
}
auto ugeometry = hybri ? hybrid::underlying : geometry;
#if CAP_ARCM
int id = ugeometry == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c);
#else
int id = shvid(c);
#endif
if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, {-1, nullptr});
auto &wop = cgi.walloffsets[id];
int &wo = wop.first;
@ -2067,8 +2071,13 @@ EX namespace rots {
if(i == c1->type-1) return uzpush(-cgi.plevel) * spin(-2*cgi.plevel);
if(i == c1->type-2) return uzpush(+cgi.plevel) * spin(+2*cgi.plevel);
cell *c2 = c1->cmove(i);
#if CAP_ARCM
int id1 = hybrid::underlying == gArchimedean ? arcm::id_of(c1->master) + 20 * arcm::parent_index_of(c1->master) : shvid(c1);
int id2 = hybrid::underlying == gArchimedean ? arcm::id_of(c2->master) + 20 * arcm::parent_index_of(c2->master) : shvid(c2);
#else
int id1 = shvid(c1);
int id2 = shvid(c2);
#endif
int j = c1->c.spin(i);
int id = id1 + (id2 << 10) + (i << 20) + (j << 26);
auto &M = saved_matrices_ray[id];
@ -2094,8 +2103,13 @@ EX namespace rots {
if(i == c1->type-2) return uzpush(-cgi.plevel) * spin(-2*cgi.plevel);
if(i == c1->type-1) return uzpush(+cgi.plevel) * spin(+2*cgi.plevel);
cell *c2 = c1->cmove(i);
#if CAP_ARCM
int id1 = hybrid::underlying == gArchimedean ? arcm::id_of(c1->master) + 20 * arcm::parent_index_of(c1->master) : shvid(c1);
int id2 = hybrid::underlying == gArchimedean ? arcm::id_of(c2->master) + 20 * arcm::parent_index_of(c2->master) : shvid(c2);
#else
int id1 = shvid(c1);
int id2 = shvid(c2);
#endif
int j = c1->c.spin(i);
int id = id1 + (id2 << 10) + (i << 20) + (j << 26);
auto &M = saved_matrices[id];

View File

@ -88,7 +88,9 @@ EX bool reduceOrbPower(eItem it, int cap) {
return true;
}
if(items[it] > cap && timerghost) items[it] = cap;
#if CAP_COMPLEX2
mine::auto_teleport_charges();
#endif
return false;
}
@ -596,7 +598,9 @@ EX void teleportTo(cell *dest) {
checkmoveO();
movecost(from, dest, 2);
#if CAP_COMPLEX2
mine::auto_teleport_charges();
#endif
}
EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMonster dashmon IS(moNone)) {

View File

@ -1682,11 +1682,13 @@ EX namespace patterns {
ep.extra_params["ey"] = y;
if(S7 == 6) ep.extra_params["ez"] = -x-y;
}
#if CAP_CRYSTAL
if(cryst) {
crystal::ldcoord co = crystal::get_ldcoord(c);
for(int i=0; i<crystal::MAXDIM; i++)
ep.extra_params["x"+its(i)] = co[i];
}
#endif
if(asonov::in()) {
auto co = asonov::get_coord(c->master);
ep.extra_params["ax"] = szgmod(co[0], asonov::period_xy);

View File

@ -718,24 +718,26 @@ void geometry_information::procedural_shapes() {
vector<ld> equal_weights(1000, 1);
#if !(CAP_BT && MAXMDIM >= 4)
#if MAXMDIM < 4
void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector<ld> weights) { }
void geometry_information::reserve_wall3d(int i) { }
void geometry_information::create_wall3d() { }
void geometry_information::compute_cornerbonus() { }
#endif
#if CAP_BT && MAXMDIM >= 4
#if MAXMDIM >= 4
// Make a wall
hyperpoint ray_kleinize(hyperpoint h, int id, ld pz) {
if(geometry == gNil && among(id, 2, 5)) h[2] = 0;
#if CAP_BT
if(hyperbolic && bt::in()) {
// ld co = vid.binary_width / log(2) / 4;
// hyperpoint res = point31(h[2]*log(2)/2, h[0]*co, h[1]*co);
return deparabolic10(bt::parabolic3(h[0], h[1]) * xpush0(log(2)/2*h[2]));
}
#endif
if(prod) {
return point3(h[0]/h[2], h[1]/h[2], pz);
}
@ -756,7 +758,9 @@ void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector
reverse(vertices.begin(), vertices.end()),
reverse(weights.begin(), weights.end());
#if CAP_BT
ld yy = log(2) / 2;
#endif
bshape(shWall3D[id], PPR::WALL);
last->flags |= POLY_TRIANGLES | POLY_PRINTABLE;
@ -815,8 +819,13 @@ void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector
hpcpush(h); return;
}
if(sn::in() || !bt::in()) { hpcpush(ultra_normalize(h)); return; }
hyperpoint res = bt::parabolic3(h[0], h[1]) * xpush0(yy*h[2]);
hpcpush(res);
#if CAP_BT
if(bt::in()) {
hyperpoint res = bt::parabolic3(h[0], h[1]) * xpush0(yy*h[2]);
hpcpush(res);
}
#endif
hpcpush(h);
});
}
@ -833,8 +842,13 @@ void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector
if(nil)
h = nilv::on_geodesic(vertices[a], vertices[(a+1)%n], y * 1. / STEP);
if(sn::in() || !bt::in()) { hpcpush(ultra_normalize(h)); continue; }
hyperpoint res = bt::parabolic3(h[0], h[1]) * xpush0(yy*h[2]);
hpcpush(res);
#if CAP_BT
if(bt::in()) {
hyperpoint res = bt::parabolic3(h[0], h[1]) * xpush0(yy*h[2]);
hpcpush(res);
}
#endif
hpcpush(h);
}
hpcpush(hpc[last->s]);
}
@ -875,6 +889,8 @@ void geometry_information::reserve_wall3d(int i) {
void geometry_information::create_wall3d() {
if(WDIM == 2) return;
reserve_wall3d(kite::in() ? 22 : hybri ? 0 : S7);
#if CAP_BT
if(GDIM == 3 && bt::in() && geometry == gBinary3) {
hyperpoint h00 = point3(-1,-1,-1);
hyperpoint h01 = point3(-1,0,-1);
@ -970,6 +986,7 @@ void geometry_information::create_wall3d() {
make_wall(12, {point3(3*h,r3,z), point3(0,2*r3,z), point3(-3*h,r3,z)});
make_wall(13, {point3(3*h,r3,z), point3(3*h,-r3,z), point3(0,-2*r3,z), point3(-3*h,-r3,z), point3(-3*h,r3,z)});
}
#endif
if(prod) {
walloffsets.clear();
@ -1060,6 +1077,7 @@ void geometry_information::create_wall3d() {
}
}
#if CAP_BT
if(kite::in()) {
auto kv = kite::make_walls();
for(auto& v: kv.first) for(auto& h: v) {
@ -1068,6 +1086,7 @@ void geometry_information::create_wall3d() {
}
for(int i=0; i<isize(kv.first); i++) make_wall(i, kv.first[i], kv.second[i]);
}
#endif
wallstart.push_back(isize(raywall));
compute_cornerbonus();

View File

@ -321,7 +321,11 @@ EX void showMission() {
);
keyhandler = handleKeyQuit;
#if CAP_COMPLEX2
bool sweeper = mine::in_minesweeper();
#else
const bool sweeper = false;
#endif
if(!peace::on && !racing::on && !sweeper)
dialog::addInfo(XLAT("Your score: %1", its(gold())));
@ -335,6 +339,7 @@ EX void showMission() {
dialog::addInfo(XLAT("Orbs of Yendor found: %1", its(items[itOrbYendor])), iinf[itOrbYendor].color);
dialog::addInfo(XLAT("CONGRATULATIONS!"), iinf[itOrbYendor].color);
}
#if CAP_COMPLEX2
else if(mine::in_minesweeper()) {
int to_uncover = kills[moBomberbird];
if(to_uncover) {
@ -346,7 +351,8 @@ EX void showMission() {
dialog::addInfo(XLAT("You won in %1", getgametime_s(mine::victory_time)));
}
}
else {
#endif
else {
if(0)
;
#if CAP_TOUR

View File

@ -269,11 +269,13 @@ void enable_raycaster() {
int flat1 = 0, flat2 = deg;
if(prod || rotspace) flat2 -= 2;
#if CAP_BT
if(hyperbolic && bt::in()) {
fsh += "uniform mediump float uBLevel;\n";
flat1 = bt::dirs_outer();
flat2 -= bt::dirs_inner();
}
#endif
if(hyperbolic) fsh +=
@ -1533,8 +1535,11 @@ EX void cast() {
}
if(o->uPLevel != -1)
glUniform1f(o->uPLevel, cgi.plevel / 2);
#if CAP_BT
if(o->uBLevel != -1)
glUniform1f(o->uBLevel, log(bt::expansion()) / 2);
#endif
if(o->uLinearSightRange != -1)
glUniform1f(o->uLinearSightRange, sightranges[geometry]);

View File

@ -13,13 +13,6 @@
namespace hr {
#if MAXMDIM >= 4
namespace binary {
void build_tmatrix();
void virtualRebaseSimple(heptagon*& base, transmatrix& at);
int celldistance3(heptagon *c1, heptagon *c2);
hyperpoint deparabolic3(hyperpoint h);
}
/** \brief regular three-dimensional tessellations */
EX namespace reg3 {
@ -641,10 +634,13 @@ EX namespace reg3 {
quotient_map = nullptr;
#if CAP_FIELD
#if CAP_CRYSTAL
if(geometry == gSpace344) {
quotient_map = new hrmap_from_crystal;
}
else if(geometry == gSpace535) {
else
#endif
if(geometry == gSpace535) {
quotient_map = new seifert_weber::hrmap_seifert_cover;
}
else if(hyperbolic) {
@ -653,6 +649,7 @@ EX namespace reg3 {
#endif
h.zebraval = quotient_map ? quotient_map->allh[0]->zebraval : 0;
#if CAP_BT
if(hyperbolic) {
dynamicval<eGeometry> g(geometry, gBinary3);
bt::build_tmatrix();
@ -667,6 +664,7 @@ EX namespace reg3 {
binary_map = bt::new_alt_map(alt);
T = xpush(.01241) * spin(1.4117) * xpush(0.1241) * cspin(0, 2, 1.1249) * xpush(0.07) * Id;
}
#endif
reg_gmatrix[origin] = make_pair(alt, T);
altmap[alt].emplace_back(origin, T);
@ -730,12 +728,14 @@ EX namespace reg3 {
println(hlog, "FAIL");
exit(3);
}
#if CAP_BT
if(steps) {
dynamicval<eGeometry> g(geometry, gBinary3);
dynamicval<hrmap*> cm(currentmap, binary_map);
for(int i=0; i<alt->type; i++)
verify_neighbors(alt->cmove(i), steps-1, currentmap->iadj(alt, i) * hT);
}
#endif
}
heptagon *create_step(heptagon *parent, int d) override {
@ -748,11 +748,13 @@ EX namespace reg3 {
transmatrix T = p1.second * cgi.adjmoves[d];
#endif
transmatrix T1 = T;
#if CAP_BT
if(hyperbolic) {
dynamicval<eGeometry> g(geometry, gBinary3);
dynamicval<hrmap*> cm(currentmap, binary_map);
binary_map->virtualRebase(alt, T);
}
#endif
fixmatrix(T);
auto hT = tC0(T);
@ -852,10 +854,12 @@ EX namespace reg3 {
}
~hrmap_reg3() {
#if CAP_BT
if(binary_map) {
dynamicval<eGeometry> g(geometry, gBinary3);
delete binary_map;
}
#endif
if(quotient_map) delete quotient_map;
clearfrom(origin);
}
@ -901,12 +905,14 @@ EX namespace reg3 {
auto p1 = reg_gmatrix[h1];
auto p2 = reg_gmatrix[h2];
transmatrix T = Id;
#if CAP_BT
if(hyperbolic) {
dynamicval<eGeometry> g(geometry, gBinary3);
dynamicval<hrmap*> cm(currentmap, binary_map);
T = binary_map->relative_matrix(p2.first, p1.first, hint);
}
T = inverse(p1.second) * T * p2.second;
#endif
T = inverse(p1.second) * T * p2.second;
if(elliptic && T[LDIM][LDIM] < 0) T = centralsym * T;
return T;
}
@ -1343,7 +1349,11 @@ EX int celldistance(cell *c1, cell *c2) {
return clueless_celldistance(c1, c2);
dynamicval<eGeometry> g(geometry, gBinary3);
#if CAP_BT
return 20 + bt::celldistance3(r->reg_gmatrix[c1->master].first, r->reg_gmatrix[c2->master].first);
#else
return 20;
#endif
}
EX bool pseudohept(cell *c) {

View File

@ -1850,11 +1850,15 @@ EX namespace rug {
EX bool rugged = false;
EX bool renderonce = false;
EX bool rendernogl = true;
EX bool mouse_control_rug = false;
EX int texturesize = 512;
EX ld scale = 1.0f;
EX bool rug_control() { return false; }
EX bool in_crystal() { return false; }
EX void reset_view() { }
#if HDR
struct using_rugview {};
#endif
EX }
#endif

View File

@ -1589,12 +1589,14 @@ EX void show() {
animator(XLATN("Ocean"), env_ocean, 'o');
animator(XLATN("Volcanic Wasteland"), env_volcano, 'v');
if(shmup::on) dialog::addBoolItem_action(XLAT("shmup action"), env_shmup, 'T');
#if CAP_FILES && CAP_SHOT
if(cheater) {
dialog::addSelItem(XLAT("monster turns"), its(numturns), 'n');
dialog::add_action([] {
dialog::editNumber(numturns, 0, 100, 1, 0, XLAT("monster turns"), XLAT("Number of turns to pass. Useful when simulating butterflies or cellular automata."));
});
}
#endif
#if CAP_RUG
if(rug::rugged) {
@ -1813,6 +1815,7 @@ void no_init() { }
startanim null_animation { "", no_init, [] { gamescreen(2); }};
#if CAP_STARTANIM
startanim joukowsky { "Joukowsky transform", no_init, [] {
dynamicval<eModel> dm(pmodel, mdJoukowskyInverted);
dynamicval<ld> dt(pconf.model_orientation, ticks / 25.);
@ -1872,6 +1875,7 @@ startanim spin_around { "spinning around", no_init, [] {
dynamicval<transmatrix> dv(View, spin(-cos_auto(circle_radius)*alpha) * xpush(circle_radius) * spin(alpha) * View);
gamescreen(2);
}};
#endif
reaction_t add_to_frame;

View File

@ -1167,8 +1167,10 @@ void movePlayer(monster *m, int delta) {
cwt.at = c2; afterplayermoved();
if(c2->item && c2->land == laAlchemist) c2->wall = m->base->wall;
#if CAP_COMPLEX2
if(m->base->wall == waRoundTable)
camelot::roundTableMessage(c2);
#endif
if(c2->wall == waCloud || c2->wall == waMirror) {
visibleFor(500);
cellwalker cw(c2, 0, false);
@ -1189,7 +1191,9 @@ void movePlayer(monster *m, int delta) {
items[itOrbLife] = 0;
m->dead = true;
}
#if CAP_COMPLEX2
mine::uncover_full(c2);
#endif
if(isWatery(c2) && isWatery(m->base) && m->inBoat)
moveItem(m->base, c2, true);
@ -2635,7 +2639,9 @@ EX void turn(int delta) {
#if CAP_INV
if(inv::on) inv::compute();
#endif
#if CAP_COMPLEX2
terracotta::check();
#endif
heat::processfires();
if(havewhat&HF_WHIRLPOOL) whirlpool::move();
if(havewhat&HF_WHIRLWIND) whirlwind::move();

View File

@ -238,6 +238,7 @@ void celldrawer::draw_ceiling() {
break;
case laVariant: {
#if CAP_COMPLEX2
int b = getBits(c);
col = 0x404040;
for(int a=0; a<21; a++)
@ -245,6 +246,7 @@ void celldrawer::draw_ceiling() {
col += variant::features[a].color_change;
col = col & 0x00FF00;
skycol = col;
#endif
break;
}

View File

@ -161,7 +161,9 @@ struct hrmap_spherical : hrmap_standard {
transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& hint) {
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
#if !ISWEB
printf("building gmatrix0 (size=%d)\n", isize(gmatrix0));
#endif
#if CAP_GP
auto bak = gp::draw_li;
#endif

View File

@ -194,7 +194,9 @@ EX void initgame() {
cwt.at = currentmap->gamestart(); cwt.spin = 0; cwt.mirrored = false;
cwt.at->land = firstland;
#if CAP_COMPLEX2
if(firstland == laBrownian) brownian::init(cwt.at);
#endif
chaosAchieved = false;
@ -214,7 +216,9 @@ EX void initgame() {
}
if((tactic::on || yendor::on || peace::on) && isCyclic(firstland)) {
#if CAP_COMPLEX2
camelot::anthraxBonus = items[itHolyGrail];
#endif
cwt.at->move(0)->land = firstland;
if(firstland == laWhirlpool) cwt.at->move(0)->wall = waSea;
@ -366,7 +370,9 @@ EX void initgame() {
#if CAP_INV
if(inv::on) inv::init();
#endif
#if CAP_COMPLEX2
mine::auto_teleport_charges();
#endif
if(!use_special_land) {
if(firstland != (princess::challenge ? laPalace : laIce)) cheater++;
}
@ -1265,7 +1271,9 @@ EX void stop_game() {
princess::reviveAt = 0;
princess::forceVizier = false;
princess::forceMouse = false;
#if CAP_COMPLEX2
camelot::knighted = 0;
#endif
// items[itGreenStone] = 100;
clearMemory();
game_active = false;
@ -1495,7 +1503,9 @@ EX void start_game() {
ignored_memory_warning = false;
check_cgi();
cgi.require_basics();
#if CAP_ARCM
arcm::current.compute_geometry();
#endif
initcells();
expansion.reset();

View File

@ -7,6 +7,13 @@
#include "hyper.h"
namespace hr {
#if !CAP_TOUR
EX namespace tour {
EX always_false on;
EX }
#endif
#if CAP_TOUR
/** \brief Variables and function related to Guided Tour and other presentations. */

View File

@ -263,6 +263,7 @@ cld exp_parser::parse(int prio) {
force_eat(")");
res = edge_of_triangle_with_angles(M_PI/2, M_PI/a, M_PI/b);
}
#if CAP_ARCM
else if(eat("arcmedge(")) {
vector<int> vals;
vals.push_back(iparse(0));
@ -280,6 +281,7 @@ cld exp_parser::parse(int prio) {
if(extra_params.count("distunit"))
res /= extra_params["distunit"];
}
#endif
else if(eat("regangle(")) {
cld edgelen = parse(0);
if(extra_params.count("distunit")) {

View File

@ -1063,7 +1063,11 @@ void save_mode_data(hstream& f) {
f.write<char>(chaosmode);
f.write<char>(shmup::on);
f.write<char>(inv::on);
#if CAP_TOUR
f.write<char>(tour::on);
#else
f.write<char>(false);
#endif
f.write<char>(peace::on);
f.write<char>(peace::otherpuzzles);
f.write<char>(peace::explore_other);