// E3 -> H2xE -> Solv: // -run -debug-portal -1 -canvas-random 100 -geo beti -intra-add -intra-bxe 4 4 3 -intra-sol 4 4 3 -ray-do -noplayer // S2xE->S3: // -debug-portal -1 -run -canvas-random 0 -intra-120 -intra-add -intra-1440 -intra-start -ray-do #include "../rogueviz/rogueviz.h" namespace hr { namespace intraf { using namespace intra; void set_wall(cell *c, color_t col) { c->wall = waWaxWall; c->landparam = col; } map plane; cellwalker flatspin(cellwalker cw, int i) { if(hybri && cw.spin < cw.at->type - 2) cw.spin = gmod(cw.spin + (cw.mirrored ? -i : i), cw.at->type - 2); return cw; } cellwalker gstrafe(cellwalker cw, int i) { if(reg3::in()) return currentmap->strafe(cw, i); if(prod) { if(i == cw.at->type-2 || i == cw.at->type-1) return cellwalker(cw.at->move(i), cw.spin); else for(int k: {-1, 1}) if(i == flatspin(cw, k).spin) return cellwalker(cw.at->move(i), flatspin(flatspin(cw, k) + wstep, +k).spin); } if(euc::in()) return cellwalker(cw.at->move(i), cw.spin); throw hr_exception("unknown gstrafe"); } void make_plane(cellwalker cw, int d) { if(plane.count(cw)) return; plane[cw] = d; auto& ss = currentmap->get_cellshape(cw.at); for(int i=0; itype; i++) if(ss.dirdist[i][cw.spin] == 1) make_plane(gstrafe(cw, i), d+1); } void build_wall(cellwalker cw, color_t a, color_t b) { println(hlog, "trying to build wall in ", full_geometry_name()); cw += wstep; plane.clear(); make_plane(cw, 0); for(auto p: plane) set_wall(p.first.at, p. second & 1 ? a : b); println(hlog, "success, ", isize(plane)); } void check_shape() { start_game(); auto sh = currentmap->get_cellshape(cwt.at); int j = 0; for(auto f: sh.faces) { j++; for(int i=0; iallcells()) { println(hlog, currentmap->full_shvid(c), " : ", currentmap->get_corner(c, 0), currentmap->get_corner(c, 1), currentmap->get_corner(c, 2)); } hybrid::csteps = 10; set_geometry(gProduct); start_game(); vector bound; PIU( [&] { cell *s = currentmap->gamestart(); hyperpoint h = currentmap->get_corner(s, 1); for(cell *c: currentmap->allcells()) { hyperpoint j = currentmap->relative_matrix(c, s, C0) * C0; if(hdist(h, j) > M_PI/2) c->wall = waPalace; } for(cell *c: currentmap->allcells()) if(c->wall == waPalace) { int nei = 0; forCellCM(c1, c) if(c1->wall != waPalace) nei++; if(nei == 1) bound.push_back(c); } auto ang = [&] (cell *c) { hyperpoint j = currentmap->relative_matrix(c, s, C0) * C0; j = gpushxto0(h) * j; return atan2(j[0], j[1]); }; for(cell *c: bound) println(hlog, "j= ", ang(c)); sort(bound.begin(), bound.end(), [&] (cell *a, cell *b) { return ang(a) < ang(b); }); int id = 0; for(auto b: bound) set_wall(b, ((id++)&1) ? 0xFFFFFF : 0x202020); } ()); for(int i=0; igamestart(); auto vs = currentmap->get_cellshape(s).vertices_only_local; println(hlog, vs); hyperpoint h = vs[1]; for(cell *c: currentmap->allcells()) { hyperpoint j = currentmap->relative_matrix(c, s, C0) * C0; // hyperpoint j = inverse(currentmap->relative_matrix(cwt.at, c, C0)) * C0; if(hdist(h, j) > M_PI/2) set_wall(c, (celldistance(c, s)&1) ? 0xFF80FF : 0xFF00FF); } } void recurse(int r, cell *c, int i, int j) { setdist(c, 7, nullptr); forCellCM(c1, c) setdist(c1, 7, nullptr); c->wall = waNone; if(r == 1) { if(sol) { int flip = (j&2)>>1; set_wall(c->cmove(6^flip), 0xC000C0); set_wall(c->cmove(7^flip), 0x800080); } else { set_wall(c->cmove((j&1)), 0x64BF95); set_wall(c->cmove(1-(j&1)), 0x449F75); } } else { if(sol) { recurse(r-1, c->cmove(6), 2*i, j>>1); recurse(r-1, c->cmove(7), 2*i+1, j>>1); } else { recurse(r-1, c->cmove(0), i, j); recurse(r-1, c->cmove(1), i, j); } } } void connect_portal_x(cellwalker cw1, cellwalker cw2, int spin) { setdist(cw1.cpeek(), 7, nullptr); setdist(cw2.cpeek(), 7, nullptr); set_wall(cw1.cpeek(), 0xFF0000); set_wall(cw2.cpeek(), 0xFF0000); connect_portal(cw1, cw2, spin); } void recurse_portal(int r, cell *cl, cell *cr) { connect_portal_x(cellwalker(cl, 6), cellwalker(cr, 5), 3); if(r > 1) { recurse_portal(r-1, cl->cmove(0), cr->cmove(0)); recurse_portal(r-1, cl->cmove(1), cr->cmove(1)); } } vector portals; void create_intra_bxe() { println(hlog, "called create_intra_bxe"); patterns::whichCanvas = 'r'; patterns::rwalls = 100; if(intra::in) intra::become(); else stop_game(); hybrid::csteps = 0; arg::shift(); int x = arg::argi(); arg::shift(); int y = arg::argi(); arg::shift(); int z = arg::argi(); vector > h(y); for(int i=0; icmove(2); for(int i=0; icmove(5); println(hlog, h); for(int i=0; icmove(3), ((j+(i>>1))&1) ? 0xA4FFD5 : 0x64BF95); recurse(z, h[i][j], i, j); } become(); start(isize(intra::data)-1); for(int i=0; imove(0); cr = cr->move(1); } } } void recurse_portal_solv1(int r, cell *cl, cell *cr) { connect_portal_x(cellwalker(cl, 0), cellwalker(cr, 4), 0); if(r > 1) { recurse_portal_solv1(r-1, cl->cmove(6), cr->cmove(6)); recurse_portal_solv1(r-1, cl->cmove(7), cr->cmove(7)); } } void recurse_portal_solv2(int r, cell *cl, cell *cr) { connect_portal_x(cellwalker(cl, 1), cellwalker(cr, 5), 0); if(r > 1) { recurse_portal_solv2(r-1, cl->cmove(7), cr->cmove(6)); } } void create_intra_sol() { println(hlog, "called create_intra_sol"); patterns::whichCanvas = 'r'; patterns::rwalls = 100; if(intra::in) intra::become(); else stop_game(); arg::shift(); int x = arg::argi(); arg::shift(); int y = arg::argi(); arg::shift(); int z = arg::argi(); vector > h(y); for(int i=0; icmove(0); for(int i=0; icmove(1); for(int i=1; icmove(5); for(int i=0; icmove(4); for(int i=0; icmove(2^((i>>1)&1)), 0xFFFDD0); set_wall(h[i][j]->cmove(3^((i>>1)&1)), 0xFFE080); recurse(z, h[i][j], i, j); } become(); start(isize(intra::data)-1); for(int i=0; i& v) { if(s != "mixed") return; v.push_back(tour::slide{ "inter-geometric portals", 10, tour::LEGAL::NONE | tour::QUICKSKIP | tour::QUICKGEO, "Portals between different geometries.\n" "These levels take some time to load, so you need to load them using the buttons below." , [] (tour::presmode mode) { setCanvas(mode, '0'); slide_url(mode, 'y', "portals (YouTube)", "https://youtu.be/yqUv2JO2BCs"); slide_url(mode, 't', "portals (Twitter)", "https://twitter.com/ZenoRogue/status/1496867204419452935"); using namespace tour; auto load = [&] (string s, ld x) { return [s, x] { slide_backup(vid.cells_drawn_limit, 100); slide_backup(smooth_scrolling, true); slide_backup(ray::max_cells, 999999); slide_backup(walking::on, true); slide_backup(walking::eye_level, x); mapstream::loadMap(s); }; }; slide_action(mode, 'p', "load portals", load("portalscene3.lev", 0.2174492)); slide_url(mode, 'C', "curved landscape (Twitter)", "https://twitter.com/ZenoRogue/status/1446127100516130826"); slide_action(mode, 'c', "load curved landscape", load("solv-h3-scene.lev", 0.05)); } }); }); } }