mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 01:00:25 +00:00
Hypersian Rug for the torus
This commit is contained in:
parent
bcd8e8bc56
commit
a14cced41d
9
cell.cpp
9
cell.cpp
@ -214,8 +214,13 @@ namespace torusconfig {
|
||||
// the configuration of the torus topology.
|
||||
// torus cells are indexed [0..qty),
|
||||
// where the cell to the right from i is indexed i+dx,
|
||||
// and the cell to the down-rightis numbered i+dy
|
||||
// changed with command line option: -tpar <qty>,<dx>,<dy>
|
||||
// and the cell to the down-right is numbered i+dy
|
||||
|
||||
// Changed with command line option: -tpar <qty>,<dx>,<dy>
|
||||
// Ideally, qty, dx, and dy should have the same "modulo 3"
|
||||
// values as the default -- otherwise the three-color
|
||||
// pattern breaks. Also, they should have no common
|
||||
// prime divisor.
|
||||
int qty = 127*3, dx = -1, dy = 11*2;
|
||||
}
|
||||
|
||||
|
@ -1910,7 +1910,7 @@
|
||||
- fixed the checkmate rule not taking the mirrored mimics into account
|
||||
- fixed some bugs with the activation of Orb of Yendor
|
||||
|
||||
2019.10.14 19:50 version 10.1
|
||||
2017.10.14 19:50 version 10.1
|
||||
|
||||
* four new lands
|
||||
- Terracotta Army
|
||||
@ -1954,12 +1954,12 @@
|
||||
- some new command line options
|
||||
- 'shame to cheat' is no longer displayed when autocheating is on
|
||||
|
||||
2019.10.14 19:50 version 10.1a
|
||||
2017.10.14 19:50 version 10.1a
|
||||
- fixed the missing leaderboards
|
||||
- fixed the typos in the description of Lava Wolf
|
||||
- fixed the ordering of lands in the Overview
|
||||
|
||||
2019.10.15 01:06 version 10.1b
|
||||
2017.10.15 01:06 version 10.1b
|
||||
- added wandering monsters to the new lands
|
||||
- no longer highlight blizzard particles
|
||||
- flash/lightning destroys terracotta warriors
|
||||
@ -1968,7 +1968,7 @@
|
||||
- slime visible in Volcanic Wasteland (but destroyed by lava)
|
||||
- living monsters awaken Terracotta Warriors
|
||||
|
||||
2019.10.16 00:43 version 10.1c
|
||||
2017.10.16 00:43 version 10.1c
|
||||
- changes to the Hunting Ground:
|
||||
- - a new pattern at 0 treasures
|
||||
- - guards now always appear in pairs (not larger groups)
|
||||
@ -1987,14 +1987,14 @@
|
||||
- fixed two more graphical glitches in Halloween
|
||||
- fixed the joystick support
|
||||
|
||||
2019.10.17 01:50 version 10.1d
|
||||
2017.10.17 01:50 version 10.1d
|
||||
- updated the translations
|
||||
- made the dogs give up to 'regroup' when you have escaped
|
||||
- you can now melt ice through great wall into the Blizzard
|
||||
- if the sight range option is lowered below 7, ambushes temporarily increase it (as the land makes no sense otherwise)
|
||||
- ancient weapon icon in the inventory
|
||||
|
||||
2019.10.17 23:41 version 10.1e
|
||||
2017.10.17 23:41 version 10.1e
|
||||
- added an option to disable background particles (for lower end platforms and for easier reading)
|
||||
- added an option to change the font size on desktop
|
||||
- the wind icon in Windy Plains is clickable now
|
||||
@ -2008,21 +2008,21 @@
|
||||
- warriors awakening takes Orb of Speed into account now
|
||||
- land connection likelihoods adjusted for the new lands
|
||||
|
||||
2019.10.25 23:17 version 10.1f
|
||||
2017.10.25 23:17 version 10.1f
|
||||
- fixed the Halloween in main menu
|
||||
- fixed Zebra unlocking
|
||||
|
||||
2019.10.26 22:00 version 10.1g
|
||||
2017.10.26 22:00 version 10.1g
|
||||
- fixed floating-point values sometimes saving incorrectly on Windows
|
||||
- fixed 's'ave the config also toggling the 's'team leaderboards
|
||||
- fixed the 'wm' and 'mm' commandline options
|
||||
- added the Octagonal geometry (work in progress)
|
||||
|
||||
2019.10.26 22:39 version 10.1h
|
||||
2017.10.26 22:39 version 10.1h
|
||||
- fixed some graphical glitches introduced by 10.1g
|
||||
- fixed some graphical glitches in Halloween
|
||||
|
||||
2019.10.31 00:31 version 10.2
|
||||
2017.10.31 00:31 version 10.2
|
||||
- added Crystal World
|
||||
- reworked the geometry experiment menu
|
||||
- changed the Hunting Ground music to Graveyard
|
||||
@ -2035,7 +2035,7 @@
|
||||
- fontscale is now saved
|
||||
- fixed CR4 appearing inside mirror reflections
|
||||
|
||||
2019.11.01 00:48 version 10.2a
|
||||
2017.11.01 00:48 version 10.2a
|
||||
- improved the texts in geometry experiment menu
|
||||
- translation updates (to Polish)
|
||||
- the "expansion" screen has moved to the geometry experiment menu (click world size)
|
||||
@ -2045,3 +2045,30 @@
|
||||
- added 'alpha' commandline parameter
|
||||
- fixed some polygons which did not end in the start point
|
||||
- Hunting Ground no longer hangs in some geometries
|
||||
|
||||
2017.11.03 22:56 version 10.2b
|
||||
General:
|
||||
- marked Orb of Earth as useful in Hunting Ground
|
||||
- Rose Garden needs 90 treasure now
|
||||
- the order of lands is now the same in all listings
|
||||
- translations updated
|
||||
- Glowing Crystals no longer required for the Hyperstone Quest
|
||||
|
||||
Geometry experiment improvements:
|
||||
- Crystal World now generated in weird hyperbolic chaos mode
|
||||
- no Dead Orb generation in the smallworld Graveyard
|
||||
- Power works correctly on big spheres (randomly on other weird geometries)
|
||||
- adjusted the hive radii in weird hyperbolic geometries
|
||||
- fixed the Field Quotient Prairie
|
||||
- improved the Land of Storms
|
||||
- made ambushes work on the sphere
|
||||
- added Mercury Rivers to Euclidean and spherical Terracotta Army
|
||||
- improved Windy Plains on smaller spheres
|
||||
- Zebra patterns for some of the new geometries
|
||||
- Halloween on a Torus
|
||||
- 'strong wind' was not allowed in Euclidean for some reason
|
||||
some fixes in validity
|
||||
validity appears in better place, lands colored
|
||||
don't display 'bad end'
|
||||
translations updated
|
||||
unified the land lists
|
||||
|
@ -3065,6 +3065,8 @@ bool dodrawcell(cell *c) {
|
||||
if(!buggyGeneration && !debugmode && c->land != laCanvas && sightrange < 10) {
|
||||
// not yet created
|
||||
if(c->mpdist > 7 && !cheater) return false;
|
||||
// always show on the torus rug
|
||||
if(rug::rugged && torus) return true;
|
||||
// in the Yendor Challenge, scrolling back is forbidden
|
||||
if(c->cpdist > 7 && (yendor::on && !cheater)) return false;
|
||||
// (incorrect comment) too far, no bugs nearby
|
||||
@ -5138,9 +5140,6 @@ void drawfullmap() {
|
||||
else
|
||||
drawmovestar(0, 0);
|
||||
}
|
||||
#if CAP_RUG
|
||||
if(rug::rugged && !rug::renderonce) queueline(C0, mouseh, 0xFF00FFFF, 5);
|
||||
#endif
|
||||
#if CAP_EDIT
|
||||
if(cmode & sm::DRAW) mapeditor::drawGrid();
|
||||
#endif
|
||||
@ -5238,6 +5237,7 @@ void drawscreen() {
|
||||
DEBB(DF_GRAPH, (debugfile,"drawscreen\n"));
|
||||
|
||||
calcparam();
|
||||
// rug::setVidParam();
|
||||
#if CAP_ROGUEVIZ
|
||||
rogueviz::fixparam();
|
||||
#endif
|
||||
|
181
rug.cpp
181
rug.cpp
@ -3,6 +3,7 @@
|
||||
|
||||
// implementation of the Hypersian Rug mode
|
||||
|
||||
|
||||
#if CAP_RUG
|
||||
|
||||
#define TEXTURESIZE (texturesize)
|
||||
@ -32,6 +33,8 @@ GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers)
|
||||
|
||||
namespace rug {
|
||||
|
||||
double rugzoom = .3;
|
||||
|
||||
// hypersian rug datatypes and globals
|
||||
//-------------------------------------
|
||||
|
||||
@ -134,8 +137,131 @@ void calcLengths() {
|
||||
points[i]->edges[j].len = hdist(points[i]->h, points[i]->edges[j].target->h);
|
||||
}
|
||||
|
||||
void setVidParam() {
|
||||
vid.xres = vid.yres = TEXTURESIZE; vid.scale = 1;
|
||||
vid.radius = HTEXTURESIZE; vid.xcenter = HTEXTURESIZE; vid.ycenter = HTEXTURESIZE;
|
||||
vid.beta = 2; vid.alphax = 1; vid.eye = 0; vid.goteyes = false;
|
||||
if(torus) vid.radius *= rugzoom;
|
||||
}
|
||||
|
||||
void buildTorusRug() {
|
||||
using namespace torusconfig;
|
||||
|
||||
dynamicval<videopar> d(vid, vid);
|
||||
rugzoom = 1;
|
||||
setVidParam();
|
||||
|
||||
struct toruspoint {
|
||||
int x,y;
|
||||
toruspoint() { x=qty; y=qty; }
|
||||
toruspoint(int _x, int _y) : x(_x), y(_y) {}
|
||||
int d2() {
|
||||
return x*x+x*y+y*y;
|
||||
}
|
||||
};
|
||||
|
||||
vector<toruspoint> zeropoints;
|
||||
vector<toruspoint> tps(qty);
|
||||
|
||||
for(int ax=-qty; ax<qty; ax++)
|
||||
for(int ay=-qty; ay<qty; ay++) {
|
||||
int v = (ax*dx + ay*dy) % qty;
|
||||
if(v<0) v += qty;
|
||||
toruspoint tp(ax, ay);
|
||||
if(tps[v].d2() > tp.d2()) tps[v] = tp;
|
||||
if(v == 0)
|
||||
zeropoints.emplace_back(ax, ay);
|
||||
}
|
||||
|
||||
pair<toruspoint, toruspoint> solution;
|
||||
ld bestsol = 1e12;
|
||||
|
||||
for(auto p1: zeropoints)
|
||||
for(auto p2: zeropoints) {
|
||||
int det = p1.x * p2.y - p2.x * p1.y;
|
||||
if(det < 0) continue;
|
||||
if(det != qty && det != -qty) continue;
|
||||
ld quality = ld(p1.d2()) * p2.d2();
|
||||
if(quality < bestsol * 3)
|
||||
if(quality < bestsol)
|
||||
bestsol = quality, solution.first = p1, solution.second = p2;
|
||||
}
|
||||
|
||||
if(solution.first.d2() > solution.second.d2())
|
||||
swap(solution.first, solution.second);
|
||||
|
||||
ld factor = sqrt(ld(solution.second.d2()) / solution.first.d2());
|
||||
|
||||
printf("factor = %lf\n", factor);
|
||||
if(factor < 2) factor = 2.2;
|
||||
factor -= 1;
|
||||
|
||||
// 22,1
|
||||
// 7,-17
|
||||
|
||||
// transmatrix z1 = {{{22,7,0}, {1,-17,0}, {0,0,1}}};
|
||||
transmatrix z1 = {{{(ld)solution.first.x,(ld)solution.second.x,0}, {(ld)solution.first.y,(ld)solution.second.y,0}, {0,0,1}}};
|
||||
transmatrix z2 = inverse(z1);
|
||||
printf("h1 = %s\n", display(z2 * hyperpoint {22,1,0}));
|
||||
|
||||
auto addToruspoint = [&] (int x, int y) {
|
||||
auto r = addRugpoint(C0, 0);
|
||||
hyperpoint onscreen;
|
||||
applymodel(tC0(eumove(x, y)), onscreen);
|
||||
// take point (1,0)
|
||||
// apply eumove(1,0)
|
||||
// divide by EUCSCALE
|
||||
// multiply by vid.radius (= HTEXTURESIZE * rugzoom)
|
||||
// add 1, divide by texturesize
|
||||
r->x1 = onscreen[0];
|
||||
r->y1 = onscreen[1];
|
||||
// r->y1 = (1 + onscreen[1] * rugzoom / EUCSCALE)/2;
|
||||
hyperpoint h1 = hpxyz(x, y, 0);
|
||||
hyperpoint h2 = z2 * h1;
|
||||
double alpha = -h2[0] * 2 * M_PI;
|
||||
double beta = -h2[1] * 2 * M_PI;
|
||||
// r->flat = {alpha, beta, 0};
|
||||
double sc = (factor+1)/4;
|
||||
r->flat = {(factor+cos(alpha)) * cos(beta) * sc, (factor+cos(alpha)) * sin(beta) * sc, -sin(alpha) * sc};
|
||||
r->valid = true;
|
||||
return r;
|
||||
};
|
||||
|
||||
for(int i=0; i<qty; i++) {
|
||||
int x = tps[i].x, y = tps[i].y;
|
||||
auto r00 = addToruspoint(x, y);
|
||||
auto r10 = addToruspoint(x+1, y);
|
||||
auto r01 = addToruspoint(x, y+1);
|
||||
auto rn1 = addToruspoint(x-1, y+1);
|
||||
addTriangle(r00, r10, r01);
|
||||
addTriangle(r00, r01, rn1);
|
||||
}
|
||||
|
||||
double maxz = 0;
|
||||
|
||||
for(auto p: points)
|
||||
maxz = max(maxz, max(abs(p->x1), abs(p->y1)));
|
||||
|
||||
// maxz * rugzoom * vid.radius == vid.radius
|
||||
|
||||
rugzoom = 1 / maxz;
|
||||
printf("rugzoom = %lf\n", rugzoom);
|
||||
|
||||
for(auto p: points)
|
||||
p->x1 = (vid.xcenter + vid.radius * rugzoom * p->x1)/ vid.xres,
|
||||
p->y1 = (vid.ycenter - vid.radius * rugzoom * p->y1)/ vid.yres;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void buildRug() {
|
||||
|
||||
if(torus) {
|
||||
buildTorusRug();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
map<cell*, rugpoint *> vptr;
|
||||
|
||||
for(int i=0; i<size(dcal); i++)
|
||||
@ -305,6 +431,7 @@ void addNewPoints() {
|
||||
|
||||
void physics() {
|
||||
|
||||
if(torus) return;
|
||||
for(int it=0; it<10000 && !stop; it++)
|
||||
if(pqueue.empty()) addNewPoints();
|
||||
else {
|
||||
@ -364,12 +491,6 @@ void drawTriangle(triangle& t) {
|
||||
glVertex3f(x3, y3, z3);
|
||||
}
|
||||
|
||||
void setVidParam() {
|
||||
vid.xres = vid.yres = TEXTURESIZE; vid.scale = 1;
|
||||
vid.radius = HTEXTURESIZE; vid.xcenter = HTEXTURESIZE; vid.ycenter = HTEXTURESIZE;
|
||||
vid.beta = 2; vid.alphax = 1; vid.eye = 0; vid.goteyes = false;
|
||||
}
|
||||
|
||||
GLuint FramebufferName = 0;
|
||||
GLuint renderedTexture = 0;
|
||||
GLuint depth_stencil_rb = 0;
|
||||
@ -447,7 +568,10 @@ void prepareTexture() {
|
||||
setGLProjection();
|
||||
ptds.clear();
|
||||
drawthemap();
|
||||
if(!renderonce) queueline(C0, mouseh, 0xFF00FF);
|
||||
if(!renderonce) {
|
||||
for(int i=0; i<numplayers(); i++) if(multi::playerActive(i))
|
||||
queueline(tC0(shmup::ggmatrix(playerpos(i))), mouseh, 0xFF00FF, 8);
|
||||
}
|
||||
drawqueue();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
#endif
|
||||
@ -639,15 +763,42 @@ hyperpoint gethyper(ld x, ld y) {
|
||||
double mx = ((x*2 / vid.xres)-1) * xview;
|
||||
double my = (1-(y*2 / vid.yres)) * yview;
|
||||
double bdist = 1e12;
|
||||
besti = 0;
|
||||
|
||||
for(int i=0; i<size(points); i++) {
|
||||
rugpoint& m = *points[i];
|
||||
double dist = hypot(m.flat[0]-mx, m.flat[1]-my);
|
||||
if(dist < bdist) bdist = dist, besti = i;
|
||||
double rx1, ry1;
|
||||
|
||||
bool found = false;
|
||||
|
||||
for(int i=0; i<size(triangles); i++) {
|
||||
auto r0 = triangles[i].m[0];
|
||||
auto r1 = triangles[i].m[1];
|
||||
auto r2 = triangles[i].m[2];
|
||||
double dx1 = r1->flat[0] - r0->flat[0];
|
||||
double dy1 = r1->flat[1] - r0->flat[1];
|
||||
double dx2 = r2->flat[0] - r0->flat[0];
|
||||
double dy2 = r2->flat[1] - r0->flat[1];
|
||||
double dxm = mx - r0->flat[0];
|
||||
double dym = my - r0->flat[1];
|
||||
// A (dx1,dy1) = (1,0)
|
||||
// B (dx2,dy2) = (0,1)
|
||||
double det = dx1*dy2 - dy1*dx2;
|
||||
double tx = dxm * dy2 - dym * dx2;
|
||||
double ty = -(dxm * dy1 - dym * dx1);
|
||||
tx /= det; ty /= det;
|
||||
if(tx >= 0 && ty >= 0 && tx+ty <= 1) {
|
||||
double rz1 = r0->flat[2] * (1-tx-ty) + r1->flat[2] * tx + r2->flat[2] * ty;
|
||||
rz1 = -rz1;
|
||||
if(rz1 < bdist) {
|
||||
bdist = rz1;
|
||||
rx1 = r0->x1 + (r1->x1 - r0->x1) * tx + (r2->x1 - r0->x1) * ty;
|
||||
ry1 = r0->y1 + (r1->y1 - r0->y1) * tx + (r2->y1 - r0->y1) * ty;
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
double px = points[besti]->x1 * TEXTURESIZE, py = (1-points[besti]->y1) * TEXTURESIZE;
|
||||
if(!found) return hpxy(0,0);
|
||||
|
||||
double px = rx1 * TEXTURESIZE, py = (1-ry1) * TEXTURESIZE;
|
||||
|
||||
videopar svid = vid;
|
||||
setVidParam();
|
||||
@ -660,7 +811,7 @@ hyperpoint gethyper(ld x, ld y) {
|
||||
void show() {
|
||||
dialog::init(XLAT("hypersian rug mode"), iinf[itPalace].color, 150, 100);
|
||||
|
||||
if(euclid || sphere) {
|
||||
if((euclid || sphere) && !torus) {
|
||||
dialog::addInfo("This makes sense only in hyperbolic geometry.");
|
||||
dialog::addBreak(50);
|
||||
}
|
||||
@ -690,7 +841,7 @@ void show() {
|
||||
"Use arrow keys to rotate, Page Up/Down to zoom."
|
||||
);
|
||||
else if(uni == 'u') {
|
||||
if(euclid || sphere)
|
||||
if((euclid || sphere) && !torus)
|
||||
addMessage("This makes sense only in hyperbolic geometry.");
|
||||
else {
|
||||
rug::init();
|
||||
|
Loading…
Reference in New Issue
Block a user