mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-25 01:20:37 +00:00
Updated to 9.4f (tutorial)
This commit is contained in:
parent
38206e5149
commit
9c350ed761
@ -84,6 +84,7 @@ bool wrongMode(char flags) {
|
|||||||
if(randomPatternsMode) return true;
|
if(randomPatternsMode) return true;
|
||||||
if(yendor::on) return true;
|
if(yendor::on) return true;
|
||||||
if(tactic::on) return true;
|
if(tactic::on) return true;
|
||||||
|
if(tour::on) return true;
|
||||||
if(chaosmode != (flags == 'C')) return true;
|
if(chaosmode != (flags == 'C')) return true;
|
||||||
if((numplayers() > 1) != (flags == 'm')) return true;
|
if((numplayers() > 1) != (flags == 'm')) return true;
|
||||||
return false;
|
return false;
|
||||||
@ -516,8 +517,9 @@ void improveItemScores() {
|
|||||||
void achievement_final(bool really_final) {
|
void achievement_final(bool really_final) {
|
||||||
if(offlineMode) return;
|
if(offlineMode) return;
|
||||||
#ifdef HAVE_ACHIEVEMENTS
|
#ifdef HAVE_ACHIEVEMENTS
|
||||||
upload_score(LB_STATISTICS, time(NULL));
|
// upload_score(LB_STATISTICS, time(NULL));
|
||||||
if(cheater) return;
|
if(cheater) return;
|
||||||
|
if(tour::on) return;
|
||||||
|
|
||||||
if(sphere && euclidland == laHalloween) {
|
if(sphere && euclidland == laHalloween) {
|
||||||
if(shmup::on || chaosmode || purehepta || numplayers() > 1 || tactic::on || randomPatternsMode)
|
if(shmup::on || chaosmode || purehepta || numplayers() > 1 || tactic::on || randomPatternsMode)
|
||||||
|
47
cell.cpp
47
cell.cpp
@ -1324,39 +1324,60 @@ int celldistance(cell *c1, cell *c2) {
|
|||||||
if(quotient == 2)
|
if(quotient == 2)
|
||||||
return fp43.getdist(fieldpattern::fieldval(c1), fieldpattern::fieldval(c2));
|
return fp43.getdist(fieldpattern::fieldval(c1), fieldpattern::fieldval(c2));
|
||||||
|
|
||||||
|
int d1 = celldist(c1), d2 = celldist(c2);
|
||||||
|
|
||||||
cell *cl1=c1, *cr1=c1, *cl2=c2, *cr2=c2;
|
cell *cl1=c1, *cr1=c1, *cl2=c2, *cr2=c2;
|
||||||
while(true) {
|
while(true) {
|
||||||
if(cl1 == cl2) return d;
|
/* if(cl1 == cl2) return d;
|
||||||
if(cl1 == cr2) return d;
|
if(cl1 == cr2) return d;
|
||||||
if(cr1 == cl2) return d;
|
if(cr1 == cl2) return d;
|
||||||
if(cr1 == cr2) return d;
|
if(cr1 == cr2) return d; */
|
||||||
|
|
||||||
if(isNeighbor(cl1, cl2)) return d+1;
|
//if(isNeighbor(cl1, cl2)) return d+1;
|
||||||
if(isNeighbor(cl1, cr2)) return d+1;
|
//if(isNeighbor(cl1, cr2)) return d+1;
|
||||||
if(isNeighbor(cr1, cl2)) return d+1;
|
//if(isNeighbor(cr1, cl2)) return d+1;
|
||||||
if(isNeighbor(cr1, cr2)) return d+1;
|
//if(isNeighbor(cr1, cr2)) return d+1;
|
||||||
|
|
||||||
forCellEx(c, cl2) if(isNeighbor(c, cr1)) return d+2;
|
if(d1 == d2) for(int u=0; u<2; u++) {
|
||||||
|
cell *ac0 = u ? cr1 : cr2, *ac = ac0;
|
||||||
|
cell *tgt = u ? cl2 : cl1;
|
||||||
|
cell *xtgt = u ? cr2 : cr1;
|
||||||
|
if(ac == tgt) return d;
|
||||||
|
ac = chosenDown(ac, 1, 1, celldist);
|
||||||
|
if(ac == tgt) return d+1;
|
||||||
|
if(ac == xtgt) return d;
|
||||||
|
ac = chosenDown(ac, 1, 1, celldist);
|
||||||
|
if(ac == tgt) return d+2;
|
||||||
|
if(!purehepta) {
|
||||||
|
ac = chosenDown(ac, 1, 1, celldist);
|
||||||
|
if(ac == tgt) {
|
||||||
|
if(chosenDown(ac0, 1, 0, celldist) ==
|
||||||
|
chosenDown(tgt, -1, 0, celldist))
|
||||||
|
return d+2;
|
||||||
|
return d+3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* forCellEx(c, cl2) if(isNeighbor(c, cr1)) return d+2;
|
||||||
forCellEx(c, cl1) if(isNeighbor(c, cr2)) return d+2;
|
forCellEx(c, cl1) if(isNeighbor(c, cr2)) return d+2;
|
||||||
|
|
||||||
forCellEx(ca, cl2) forCellEx(cb, cr1) if(isNeighbor(ca, cb)) return d+3;
|
forCellEx(ca, cl2) forCellEx(cb, cr1) if(isNeighbor(ca, cb)) return d+3;
|
||||||
forCellEx(ca, cl1) forCellEx(cb, cr2) if(isNeighbor(ca, cb)) return d+3;
|
forCellEx(ca, cl1) forCellEx(cb, cr2) if(isNeighbor(ca, cb)) return d+3; */
|
||||||
|
|
||||||
int d1 = celldist(cl1), d2 = celldist(cl2);
|
|
||||||
|
|
||||||
if(d1 >= d2) {
|
if(d1 >= d2) {
|
||||||
cl1 = chosenDown(cl1, -1, 0, celldist);
|
cl1 = chosenDown(cl1, -1, 0, celldist);
|
||||||
// cl1->item = eItem(rand() % 10);
|
// cl1->item = eItem(rand() % 10);
|
||||||
cr1 = chosenDown(cr1, 1, 0, celldist);
|
cr1 = chosenDown(cr1, 1, 0, celldist);
|
||||||
// cr1->item = eItem(rand() % 10);
|
// cr1->item = eItem(rand() % 10);
|
||||||
d++;
|
d++; d1--;
|
||||||
}
|
}
|
||||||
if(d1 <= d2) {
|
if(d1 < d2) {
|
||||||
cl2 = chosenDown(cl2, -1, 0, celldist);
|
cl2 = chosenDown(cl2, -1, 0, celldist);
|
||||||
// cl2->item = eItem(rand() % 10);
|
// cl2->item = eItem(rand() % 10);
|
||||||
cr2 = chosenDown(cr2, 1, 0, celldist);
|
cr2 = chosenDown(cr2, 1, 0, celldist);
|
||||||
// cr2->item = eItem(rand() % 10);
|
// cr2->item = eItem(rand() % 10);
|
||||||
d++;
|
d++; d2--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
75
certify.cpp
Normal file
75
certify.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// PRIVATE
|
||||||
|
|
||||||
|
namespace anticheat {
|
||||||
|
|
||||||
|
bool tampered;
|
||||||
|
|
||||||
|
void save(FILE *f) {
|
||||||
|
int cert = 0x1234;
|
||||||
|
for(int i=0; i<boxid; i++)
|
||||||
|
cert = 3 * cert + (761349061 + 1463190*i) * savebox[i];
|
||||||
|
if(!tampered) fprintf(f, " C %d\n", cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool load(FILE *f, score& sc, string ver) {
|
||||||
|
int cert = 0x1234;
|
||||||
|
for(int i=0; i<boxid; i++)
|
||||||
|
cert = 3 * cert + (761349061 + 1463190*i) * sc.box[i];
|
||||||
|
char cr;
|
||||||
|
int scert;
|
||||||
|
int err = fscanf(f, "%c%d", &cr, &scert);
|
||||||
|
if(err != 2) return true;
|
||||||
|
// if(cr == 'C' && cert == scert) printf("Certificate OK\n");
|
||||||
|
return cert != scert;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vcertify(string ver, string ss, int a, int b, int c, int d) {
|
||||||
|
ss = ver + ss;
|
||||||
|
const char *s = ss.c_str();
|
||||||
|
if(tampered) return -1;
|
||||||
|
int cert = 0x5678;
|
||||||
|
while(*s) cert = cert * 37113 + (*s), s++;
|
||||||
|
cert = cert + a * 681491 + b * 681390411 + c * 581911 + d * 16406101;
|
||||||
|
return cert;
|
||||||
|
}
|
||||||
|
|
||||||
|
int certify(string ss, int a, int b, int c, int d) {
|
||||||
|
return vcertify(VER, ss, a, b, c, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int check(int cv, const string& ver, const string& s, int a, int b, int c, int d) {
|
||||||
|
if(ver < "8.0f" && cv == d) return true;
|
||||||
|
return cv == vcertify(ver, s, a, b, c, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nextid(int& tid, const string& ver, int cert) {
|
||||||
|
if(ver >= "8.0i") tid += 1 + cert + cert * cert / 7;
|
||||||
|
else tid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8.0i: ver included in achievements
|
||||||
|
// 8.0f: fixed in Windows
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef MOBILE
|
||||||
|
void SDL_Delay_anticheat(int i) {
|
||||||
|
saveBox();
|
||||||
|
int i0 = 0; savebox[1] = savebox[65] = anticheat::tampered; // do not consider Timer
|
||||||
|
for(int t=0; t<boxid; t++)
|
||||||
|
i0 = 73 * i0 + savebox[t] + savebox[t] * (savebox[t] + 7103);
|
||||||
|
for(int t=0; t<boxid; t++) savebox[t] = 0;
|
||||||
|
SDL_Delay(i);
|
||||||
|
|
||||||
|
saveBox();
|
||||||
|
int i1 = 0; savebox[1] = savebox[65] = anticheat::tampered; // do not consider Timer
|
||||||
|
for(int t=0; t<boxid; t++)
|
||||||
|
i1 = 73 * i1 + savebox[t] + savebox[t] * (savebox[t] + 7103);
|
||||||
|
|
||||||
|
if(i0 != i1) {
|
||||||
|
anticheat::tampered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SDL_Delay SDL_Delay_anticheat
|
||||||
|
|
@ -106,14 +106,24 @@ namespace spiral {
|
|||||||
|
|
||||||
int CX, CY, SX, SY, Yshift;
|
int CX, CY, SX, SY, Yshift;
|
||||||
|
|
||||||
SDL_Surface *band, *out;
|
vector<SDL_Surface*> band;
|
||||||
|
SDL_Surface *out;
|
||||||
|
|
||||||
bool displayhelp = true;
|
bool displayhelp = true;
|
||||||
|
|
||||||
|
int& bandpixel(int x, int y) {
|
||||||
|
int i = 0;
|
||||||
|
while(i < size(band) && x >= band[i]->w)
|
||||||
|
x -= band[i]->w, i++;
|
||||||
|
return qpixel(band[i], x, y);
|
||||||
|
}
|
||||||
|
|
||||||
void precompute() {
|
void precompute() {
|
||||||
|
|
||||||
CX = band->w;
|
CX = 0;
|
||||||
CY = band->h;
|
for(int i=0; i<size(band); i++) CX += band[i]->w;
|
||||||
|
if(CX == 0) { printf("ERROR: no CX\n"); return; }
|
||||||
|
CY = band[0]->h;
|
||||||
SX = out->w;
|
SX = out->w;
|
||||||
SY = out->h;
|
SY = out->h;
|
||||||
|
|
||||||
@ -151,11 +161,11 @@ namespace spiral {
|
|||||||
cy -= d * CY; cx -= d * Yshift;
|
cy -= d * CY; cx -= d * Yshift;
|
||||||
if(cy<0) cy += CY, cx += Yshift;
|
if(cy<0) cy += CY, cx += Yshift;
|
||||||
cx %= CX; if(cx<0) cx += CX;
|
cx %= CX; if(cx<0) cx += CX;
|
||||||
qpixel(out, x, y) = qpixel(band, cx, cy);
|
qpixel(out, x, y) = bandpixel(cx, cy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop(SDL_Surface *_band) {
|
void loop(vector<SDL_Surface*> _band) {
|
||||||
|
|
||||||
bool saveGL = vid.usingGL;
|
bool saveGL = vid.usingGL;
|
||||||
if(saveGL) { vid.usingGL = false; setvideomode(); }
|
if(saveGL) { vid.usingGL = false; setvideomode(); }
|
||||||
@ -163,6 +173,7 @@ namespace spiral {
|
|||||||
band = _band;
|
band = _band;
|
||||||
out = s;
|
out = s;
|
||||||
precompute();
|
precompute();
|
||||||
|
if(CX == 0) return;
|
||||||
shiftx = shifty = 0;
|
shiftx = shifty = 0;
|
||||||
velx=1; vely=1;
|
velx=1; vely=1;
|
||||||
bool dosave = false;
|
bool dosave = false;
|
||||||
@ -399,6 +410,8 @@ namespace conformal {
|
|||||||
|
|
||||||
int xpos = 0;
|
int xpos = 0;
|
||||||
|
|
||||||
|
vector<SDL_Surface*> bands;
|
||||||
|
|
||||||
SDL_Surface *band = SDL_CreateRGBSurface(SDL_SWSURFACE, min(len, bandsegment), bandfull,32,0,0,0,0);
|
SDL_Surface *band = SDL_CreateRGBSurface(SDL_SWSURFACE, min(len, bandsegment), bandfull,32,0,0,0,0);
|
||||||
|
|
||||||
if(!band) {
|
if(!band) {
|
||||||
@ -451,14 +464,13 @@ namespace conformal {
|
|||||||
char buf[128];
|
char buf[128];
|
||||||
sprintf(buf, "bandmodel-%s-%03d" IMAGEEXT, timebuf, segid++);
|
sprintf(buf, "bandmodel-%s-%03d" IMAGEEXT, timebuf, segid++);
|
||||||
|
|
||||||
if(dospiral) {
|
|
||||||
swap(vid.xres, vid2.xres); swap(vid.yres, vid2.yres); s = sav;
|
|
||||||
spiral::loop(band);
|
|
||||||
swap(vid.xres, vid2.xres); swap(vid.yres, vid2.yres); s = bbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
IMAGESAVE(band, buf);
|
IMAGESAVE(band, buf);
|
||||||
|
|
||||||
|
if(dospiral)
|
||||||
|
bands.push_back(band);
|
||||||
|
else
|
||||||
SDL_FreeSurface(band);
|
SDL_FreeSurface(band);
|
||||||
|
|
||||||
len -= bandsegment; xpos -= bandsegment;
|
len -= bandsegment; xpos -= bandsegment;
|
||||||
band = SDL_CreateRGBSurface(SDL_SWSURFACE, min(len, bandsegment), bandfull,32,0,0,0,0);
|
band = SDL_CreateRGBSurface(SDL_SWSURFACE, min(len, bandsegment), bandfull,32,0,0,0,0);
|
||||||
goto drawsegment;
|
goto drawsegment;
|
||||||
@ -470,12 +482,22 @@ namespace conformal {
|
|||||||
char buf[128];
|
char buf[128];
|
||||||
sprintf(buf, "bandmodel-%s-%03d" IMAGEEXT, timebuf, segid++);
|
sprintf(buf, "bandmodel-%s-%03d" IMAGEEXT, timebuf, segid++);
|
||||||
IMAGESAVE(band, buf);
|
IMAGESAVE(band, buf);
|
||||||
|
addMessage(XLAT("Saved the band image as: ") + buf);
|
||||||
|
|
||||||
|
if(dospiral)
|
||||||
|
bands.push_back(band);
|
||||||
|
else
|
||||||
|
SDL_FreeSurface(band);
|
||||||
|
|
||||||
SDL_FreeSurface(sav);
|
SDL_FreeSurface(sav);
|
||||||
s = sav; vid = vid2; sightrange = ssr; cheater = sch;
|
s = sav; vid = vid2; sightrange = ssr; cheater = sch;
|
||||||
if(includeHistory) restoreBack();
|
if(includeHistory) restoreBack();
|
||||||
if(dospiral) spiral::loop(band);
|
|
||||||
addMessage(XLAT("Saved the band image as: ") + buf);
|
if(dospiral) {
|
||||||
SDL_FreeSurface(band);
|
spiral::loop(bands);
|
||||||
|
for(int i=0; i<size(bands); i++) SDL_FreeSurface(bands[i]);
|
||||||
|
}
|
||||||
|
|
||||||
inHighQual = false;
|
inHighQual = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -58,6 +58,8 @@ namespace dialog {
|
|||||||
if(k == SDLK_F5) return "F5";
|
if(k == SDLK_F5) return "F5";
|
||||||
if(k == SDLK_F10) return "F10";
|
if(k == SDLK_F10) return "F10";
|
||||||
if(k == SDLK_HOME) return "Home";
|
if(k == SDLK_HOME) return "Home";
|
||||||
|
if(k == SDLK_BACKSPACE) return "Backspace";
|
||||||
|
if(k == SDLK_RETURN) return "Enter";
|
||||||
if(k == 32) return "space";
|
if(k == 32) return "space";
|
||||||
if(k >= 1 && k <= 26) { string s = "Ctrl+"; s += (k+64); return s; }
|
if(k >= 1 && k <= 26) { string s = "Ctrl+"; s += (k+64); return s; }
|
||||||
if(k < 128) { string s; s += k; return s; }
|
if(k < 128) { string s; s += k; return s; }
|
||||||
@ -178,7 +180,7 @@ namespace dialog {
|
|||||||
|
|
||||||
int xs, xo;
|
int xs, xo;
|
||||||
if(sidescreen)
|
if(sidescreen)
|
||||||
xs = dwidth - vid.fsize, xo = vid.xres + vid.fsize;
|
xs = dwidth - vid.fsize*2, xo = vid.yres + vid.fsize;
|
||||||
else
|
else
|
||||||
xs = vid.xres * 618/1000, xo = vid.xres * 186/1000;
|
xs = vid.xres * 618/1000, xo = vid.xres * 186/1000;
|
||||||
|
|
||||||
@ -252,7 +254,7 @@ namespace dialog {
|
|||||||
|
|
||||||
if(sidescreen) {
|
if(sidescreen) {
|
||||||
dwidth = vid.xres - vid.yres;
|
dwidth = vid.xres - vid.yres;
|
||||||
dcenter = (vid.xres + dwidth) / 2;
|
dcenter = vid.xres - dwidth / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(tothei > vid.yres - 5 * vid.fsize) {
|
while(tothei > vid.yres - 5 * vid.fsize) {
|
||||||
|
386
google-games.cpp
Normal file
386
google-games.cpp
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
// PRIVATE
|
||||||
|
|
||||||
|
void viewAchievements();
|
||||||
|
void viewLeaderboard(string id);
|
||||||
|
void switchGoogleConnection();
|
||||||
|
|
||||||
|
namespace leader {
|
||||||
|
|
||||||
|
bool currentlyConnecting();
|
||||||
|
bool currentlyConnected();
|
||||||
|
|
||||||
|
string leaderboardIDs[NUMLEADER] = {
|
||||||
|
"CgkIspzRq_8NEAIQAg",
|
||||||
|
"CgkIspzRq_8NEAIQKg",
|
||||||
|
"CgkIspzRq_8NEAIQLA",
|
||||||
|
"CgkIspzRq_8NEAIQKw",
|
||||||
|
"CgkIspzRq_8NEAIQLQ",
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQMA",
|
||||||
|
"CgkIspzRq_8NEAIQLg",
|
||||||
|
"CgkIspzRq_8NEAIQNQ",
|
||||||
|
"CgkIspzRq_8NEAIQNg",
|
||||||
|
"CgkIspzRq_8NEAIQMg",
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQLw",
|
||||||
|
"CgkIspzRq_8NEAIQOA",
|
||||||
|
"CgkIspzRq_8NEAIQOg",
|
||||||
|
"CgkIspzRq_8NEAIQPA",
|
||||||
|
"CgkIspzRq_8NEAIQOw",
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQPg", // 15
|
||||||
|
"CgkIspzRq_8NEAIQPQ",
|
||||||
|
"CgkIspzRq_8NEAIQUA",
|
||||||
|
"CgkIspzRq_8NEAIQMw",
|
||||||
|
"CgkIspzRq_8NEAIQUQ",
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQVA", // 20
|
||||||
|
"CgkIspzRq_8NEAIQUw",
|
||||||
|
"CgkIspzRq_8NEAIQVQ",
|
||||||
|
"CgkIspzRq_8NEAIQUg",
|
||||||
|
"CgkIspzRq_8NEAIQcQ", // Grimories
|
||||||
|
"CgkIspzRq_8NEAIQcg", // 25 Holy Grails
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQdA", // 26 Red Gems
|
||||||
|
"CgkIspzRq_8NEAIQcw", // 27 Pirate Treasures
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQ4QE", // 28 Shmup mode
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQ4gE", // 29 Shmup time to win
|
||||||
|
"CgkIspzRq_8NEAIQ4wE", // 30 Shmup knives to win
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQigE", // 31 bombeggs
|
||||||
|
"CgkIspzRq_8NEAIQiwE", // 32 ambers
|
||||||
|
"CgkIspzRq_8NEAIQjAE", // 33 pearls
|
||||||
|
"CgkIspzRq_8NEAIQjQE", // 34 hyperrugs
|
||||||
|
"CgkIspzRq_8NEAIQjgE", // 35 garnets
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQ5gE", // 36 princess challenge
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQnAE", // 37 Ivory Figurines
|
||||||
|
"CgkIspzRq_8NEAIQmgE", // 38 Elemental Gems
|
||||||
|
"CgkIspzRq_8NEAIQmwE", // 39 Onyxes
|
||||||
|
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQwAE", // 40 Yendor Challenge
|
||||||
|
"CgkIspzRq_8NEAIQ5AE", // 41 Pure Tactics Mode
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQpgE", // 42 Mutant Saplings
|
||||||
|
"CgkIspzRq_8NEAIQpQE", // 43 Fulgurites
|
||||||
|
|
||||||
|
"", // 44
|
||||||
|
"", // 45
|
||||||
|
"CgkIspzRq_8NEAIQswE", // 46 Black Lotuses
|
||||||
|
"CgkIspzRq_8NEAIQsgE", // 47 Mutant Fruits
|
||||||
|
"CgkIspzRq_8NEAIQsQE", // 48 White Dove
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQ5QE", // 49 PTM shmup
|
||||||
|
"", // 50
|
||||||
|
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQtQE", // 51 Corals
|
||||||
|
"CgkIspzRq_8NEAIQtgE", // 52 Thornless Roses
|
||||||
|
"CgkIspzRq_8NEAIQtwE", // 53 Chaos Mode
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQwwE", // 54 Tortoise Points
|
||||||
|
"CgkIspzRq_8NEAIQwgE", // 55 Dragon Scales
|
||||||
|
"CgkIspzRq_8NEAIQwQE", // 56 Apples
|
||||||
|
"CgkIspzRq_8NEAIQ4AE", // 57 Heptagonal mode
|
||||||
|
"CgkIspzRq_8NEAIQ3gE", // 58 Sunken treasures
|
||||||
|
"CgkIspzRq_8NEAIQ3QE", // 59 Ancient Jewelry
|
||||||
|
"CgkIspzRq_8NEAIQ3wE", // 60 Golden Eggs
|
||||||
|
|
||||||
|
"", // 61 multiplayer
|
||||||
|
"", // 62 statistics
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQ6gE", // 63 Halloween
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQ9AE", // 64 Amethyst
|
||||||
|
"CgkIspzRq_8NEAIQ9QE", // 65 Slime Molds
|
||||||
|
"CgkIspzRq_8NEAIQ9gE", // 66 Dodecahedra
|
||||||
|
|
||||||
|
"CgkIspzRq_8NEAIQ_gE", // 67 Green Grass
|
||||||
|
"CgkIspzRq_8NEAIQ_QE", // 68 Spinels
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* achievementIDs[] = {
|
||||||
|
"DIAMOND2", "CgkIspzRq_8NEAIQAw",
|
||||||
|
"SPICE2", "CgkIspzRq_8NEAIQBA",
|
||||||
|
"GOLD2", "CgkIspzRq_8NEAIQBQ",
|
||||||
|
"RUBY2", "CgkIspzRq_8NEAIQCQ",
|
||||||
|
"MIRROR2", "CgkIspzRq_8NEAIQBw",
|
||||||
|
"FEATHER2", "CgkIspzRq_8NEAIQDA",
|
||||||
|
"ELIXIR2", "CgkIspzRq_8NEAIQDQ",
|
||||||
|
"STATUE2", "CgkIspzRq_8NEAIQBg",
|
||||||
|
"FERN2", "CgkIspzRq_8NEAIQDg",
|
||||||
|
"TOTEM2", "CgkIspzRq_8NEAIQCA",
|
||||||
|
"DAISY2", "CgkIspzRq_8NEAIQCw",
|
||||||
|
"SAPPHIRE2", "CgkIspzRq_8NEAIQDw",
|
||||||
|
"HYPER2", "CgkIspzRq_8NEAIQCg",
|
||||||
|
"DIAMOND3", "CgkIspzRq_8NEAIQEA",
|
||||||
|
"SPICE3", "CgkIspzRq_8NEAIQEQ",
|
||||||
|
"GOLD3", "CgkIspzRq_8NEAIQEg",
|
||||||
|
"RUBY3", "CgkIspzRq_8NEAIQEw",
|
||||||
|
"MIRROR3", "CgkIspzRq_8NEAIQFA",
|
||||||
|
"FEATHER3", "CgkIspzRq_8NEAIQFQ",
|
||||||
|
"ELIXIR3", "CgkIspzRq_8NEAIQFg",
|
||||||
|
"STATUE3", "CgkIspzRq_8NEAIQFw",
|
||||||
|
"FERN3", "CgkIspzRq_8NEAIQGA",
|
||||||
|
"TOTEM3", "CgkIspzRq_8NEAIQGQ",
|
||||||
|
"DAISY3", "CgkIspzRq_8NEAIQGg",
|
||||||
|
"SAPPHIRE3", "CgkIspzRq_8NEAIQGw",
|
||||||
|
"HYPER3", "CgkIspzRq_8NEAIQHA",
|
||||||
|
"DIAMOND4", "CgkIspzRq_8NEAIQHQ",
|
||||||
|
"SPICE4", "CgkIspzRq_8NEAIQHg",
|
||||||
|
"GOLD4", "CgkIspzRq_8NEAIQHw",
|
||||||
|
"RUBY4", "CgkIspzRq_8NEAIQIA",
|
||||||
|
"MIRROR4", "CgkIspzRq_8NEAIQIQ",
|
||||||
|
"FEATHER4", "CgkIspzRq_8NEAIQIg",
|
||||||
|
"ELIXIR4", "CgkIspzRq_8NEAIQIw",
|
||||||
|
"STATUE4", "CgkIspzRq_8NEAIQJA",
|
||||||
|
"FERN4", "CgkIspzRq_8NEAIQJQ",
|
||||||
|
"TOTEM4", "CgkIspzRq_8NEAIQJg",
|
||||||
|
"DAISY4", "CgkIspzRq_8NEAIQJw",
|
||||||
|
"SAPPHIRE4", "CgkIspzRq_8NEAIQKA",
|
||||||
|
"HYPER4", "CgkIspzRq_8NEAIQKQ",
|
||||||
|
"STABBER2", "CgkIspzRq_8NEAIQPw",
|
||||||
|
"STABBER3", "CgkIspzRq_8NEAIQQA",
|
||||||
|
"FLASH2", "CgkIspzRq_8NEAIQQQ",
|
||||||
|
"FLASH3", "CgkIspzRq_8NEAIQQg",
|
||||||
|
"LIGHTNING2", "CgkIspzRq_8NEAIQQw",
|
||||||
|
"LIGHTNING3", "CgkIspzRq_8NEAIQRA",
|
||||||
|
"FALLDEATH1", "CgkIspzRq_8NEAIQRQ",
|
||||||
|
"GOLEM2", "CgkIspzRq_8NEAIQRg",
|
||||||
|
"GOLEM3", "CgkIspzRq_8NEAIQRw",
|
||||||
|
"MIRAGE", "CgkIspzRq_8NEAIQSA",
|
||||||
|
"MIRRORKILL2", "CgkIspzRq_8NEAIQSQ",
|
||||||
|
"MIRRORKILL3", "CgkIspzRq_8NEAIQSg",
|
||||||
|
"IVYSLAYER", "CgkIspzRq_8NEAIQSw",
|
||||||
|
"DEMONSLAYER", "CgkIspzRq_8NEAIQTA",
|
||||||
|
"YENDOR1", "CgkIspzRq_8NEAIQTQ",
|
||||||
|
"YENDOR2", "CgkIspzRq_8NEAIQTg",
|
||||||
|
|
||||||
|
"WINE2", "CgkIspzRq_8NEAIQVg",
|
||||||
|
"EMERALD2", "CgkIspzRq_8NEAIQVw",
|
||||||
|
"SILVER2", "CgkIspzRq_8NEAIQWA",
|
||||||
|
"JELLY2", "CgkIspzRq_8NEAIQWQ",
|
||||||
|
"POWER2", "CgkIspzRq_8NEAIQWg",
|
||||||
|
|
||||||
|
"WINE3", "CgkIspzRq_8NEAIQWw",
|
||||||
|
"EMERALD3", "CgkIspzRq_8NEAIQXQ",
|
||||||
|
"SILVER3", "CgkIspzRq_8NEAIQXA",
|
||||||
|
"JELLY3", "CgkIspzRq_8NEAIQXg",
|
||||||
|
"POWER3 ", "CgkIspzRq_8NEAIQXw",
|
||||||
|
|
||||||
|
"WINE4", "CgkIspzRq_8NEAIQYA",
|
||||||
|
"EMERALD4", "CgkIspzRq_8NEAIQYQ",
|
||||||
|
"SILVER4", "CgkIspzRq_8NEAIQYg",
|
||||||
|
"JELLY4", "CgkIspzRq_8NEAIQYw",
|
||||||
|
"POWER4", "CgkIspzRq_8NEAIQZA",
|
||||||
|
|
||||||
|
"ORB3", "CgkIspzRq_8NEAIQZQ",
|
||||||
|
"BUG3", "CgkIspzRq_8NEAIQZg",
|
||||||
|
"LIFEBRINGER", "CgkIspzRq_8NEAIQZw",
|
||||||
|
"GARDENER ", "CgkIspzRq_8NEAIQaA",
|
||||||
|
"MELEE3", "CgkIspzRq_8NEAIQaQ",
|
||||||
|
"MELEE5", "CgkIspzRq_8NEAIQag",
|
||||||
|
|
||||||
|
"GRIMOIRE2", "CgkIspzRq_8NEAIQaw",
|
||||||
|
"GRIMOIRE3", "CgkIspzRq_8NEAIQbA",
|
||||||
|
"GRIMOIRE4", "CgkIspzRq_8NEAIQbQ",
|
||||||
|
|
||||||
|
"GRAIL2", "CgkIspzRq_8NEAIQbg",
|
||||||
|
"GRAIL3", "CgkIspzRq_8NEAIQbw",
|
||||||
|
"GRAIL4", "CgkIspzRq_8NEAIQcA",
|
||||||
|
|
||||||
|
"PIRATE2", "CgkIspzRq_8NEAIQdQ",
|
||||||
|
"PIRATE3", "CgkIspzRq_8NEAIQdg",
|
||||||
|
"PIRATE4", "CgkIspzRq_8NEAIQdw",
|
||||||
|
|
||||||
|
"REDGEM2", "CgkIspzRq_8NEAIQeA",
|
||||||
|
"REDGEM3", "CgkIspzRq_8NEAIQeQ",
|
||||||
|
"REDGEM4", "CgkIspzRq_8NEAIQeg",
|
||||||
|
|
||||||
|
"COAST2", "CgkIspzRq_8NEAIQew",
|
||||||
|
"COAST3", "CgkIspzRq_8NEAIQfA",
|
||||||
|
"COAST4", "CgkIspzRq_8NEAIQfQ",
|
||||||
|
|
||||||
|
"WHIRL2", "CgkIspzRq_8NEAIQfg",
|
||||||
|
"WHIRL3", "CgkIspzRq_8NEAIQfw",
|
||||||
|
"WHIRL4", "CgkIspzRq_8NEAIQgAE",
|
||||||
|
|
||||||
|
"MINE2", "CgkIspzRq_8NEAIQgQE",
|
||||||
|
"MINE3", "CgkIspzRq_8NEAIQggE",
|
||||||
|
"MINE4", "CgkIspzRq_8NEAIQgwE",
|
||||||
|
|
||||||
|
"RUG2", "CgkIspzRq_8NEAIQhAE",
|
||||||
|
"RUG3", "CgkIspzRq_8NEAIQhQE",
|
||||||
|
"RUG4", "CgkIspzRq_8NEAIQhgE",
|
||||||
|
|
||||||
|
"GARNET2", "CgkIspzRq_8NEAIQhwE",
|
||||||
|
"GARNET3", "CgkIspzRq_8NEAIQiAE",
|
||||||
|
"GARNET4", "CgkIspzRq_8NEAIQiQE",
|
||||||
|
|
||||||
|
"ZEBRA2", "CgkIspzRq_8NEAIQkQE",
|
||||||
|
"ZEBRA3", "CgkIspzRq_8NEAIQkgE",
|
||||||
|
"ZEBRA4", "CgkIspzRq_8NEAIQkwE",
|
||||||
|
"ELEMENT2", "CgkIspzRq_8NEAIQlAE",
|
||||||
|
"ELEMENT3", "CgkIspzRq_8NEAIQlQE",
|
||||||
|
"ELEMENT4", "CgkIspzRq_8NEAIQlgE",
|
||||||
|
"TOWER2", "CgkIspzRq_8NEAIQlwE",
|
||||||
|
"TOWER3", "CgkIspzRq_8NEAIQmAE",
|
||||||
|
"TOWER4", "CgkIspzRq_8NEAIQmQE",
|
||||||
|
|
||||||
|
"PRINCESS1", "CgkIspzRq_8NEAIQjwE",
|
||||||
|
"PRINCESS_PACIFIST", "CgkIspzRq_8NEAIQkAE",
|
||||||
|
// Achievements.unlock(mGoogleApiClient, "CgkIspzRq_8NEAIQAw"),
|
||||||
|
|
||||||
|
"FULGUR2", "CgkIspzRq_8NEAIQoAE",
|
||||||
|
"FULGUR3", "CgkIspzRq_8NEAIQoQE",
|
||||||
|
"FULGUR4", "CgkIspzRq_8NEAIQogE",
|
||||||
|
"HARDMETAL", "CgkIspzRq_8NEAIQpAE",
|
||||||
|
"ELEC3", "CgkIspzRq_8NEAIQowE",
|
||||||
|
"MUTANT2", "CgkIspzRq_8NEAIQnQE",
|
||||||
|
"MUTANT3", "CgkIspzRq_8NEAIQngE",
|
||||||
|
"MUTANT4", "CgkIspzRq_8NEAIQnwE",
|
||||||
|
|
||||||
|
"DOVE2", "CgkIspzRq_8NEAIQqwE",
|
||||||
|
"DOVE3", "CgkIspzRq_8NEAIQrAE",
|
||||||
|
"DOVE4", "CgkIspzRq_8NEAIQrQE",
|
||||||
|
"LOTUS2", "CgkIspzRq_8NEAIQpwE",
|
||||||
|
"LOTUS3", "CgkIspzRq_8NEAIQqAE",
|
||||||
|
"LOTUS4", "CgkIspzRq_8NEAIQqQE",
|
||||||
|
"FRUIT2", "CgkIspzRq_8NEAIQrgE",
|
||||||
|
"FRUIT3", "CgkIspzRq_8NEAIQrwE",
|
||||||
|
"FRUIT4", "CgkIspzRq_8NEAIQsAE",
|
||||||
|
"COMEBACK", "CgkIspzRq_8NEAIQtAE",
|
||||||
|
"SURVIVAL", "CgkIspzRq_8NEAIQqgE",
|
||||||
|
|
||||||
|
"CORAL2", "CgkIspzRq_8NEAIQuAE",
|
||||||
|
"CORAL3", "CgkIspzRq_8NEAIQuQE",
|
||||||
|
"CORAL4", "CgkIspzRq_8NEAIQugE",
|
||||||
|
"ROSE2", "CgkIspzRq_8NEAIQuwE",
|
||||||
|
"ROSE3", "CgkIspzRq_8NEAIQvAE",
|
||||||
|
"ROSE4", "CgkIspzRq_8NEAIQvQE",
|
||||||
|
"CR4", "CgkIspzRq_8NEAIQvgE",
|
||||||
|
"CHAOS", "CgkIspzRq_8NEAIQvwE",
|
||||||
|
|
||||||
|
"APPLE2", "CgkIspzRq_8NEAIQxAE",
|
||||||
|
"APPLE3", "CgkIspzRq_8NEAIQxQE",
|
||||||
|
"APPLE4", "CgkIspzRq_8NEAIQxgE",
|
||||||
|
"DRAGON2", "CgkIspzRq_8NEAIQxwE",
|
||||||
|
"DRAGON3", "CgkIspzRq_8NEAIQyAE",
|
||||||
|
"DRAGON4", "CgkIspzRq_8NEAIQyQE",
|
||||||
|
"TORTOISE2", "CgkIspzRq_8NEAIQygE",
|
||||||
|
"TORTOISE3", "CgkIspzRq_8NEAIQywE",
|
||||||
|
"TORTOISE4", "CgkIspzRq_8NEAIQzAE",
|
||||||
|
|
||||||
|
"KRAKEN2", "CgkIspzRq_8NEAIQ0QE",
|
||||||
|
"KRAKEN3", "CgkIspzRq_8NEAIQ0gE",
|
||||||
|
"KRAKEN4", "CgkIspzRq_8NEAIQ0wE",
|
||||||
|
"BARROW2", "CgkIspzRq_8NEAIQ1AE",
|
||||||
|
"BARROW3", "CgkIspzRq_8NEAIQ1QE",
|
||||||
|
"BARROW4", "CgkIspzRq_8NEAIQ1gE",
|
||||||
|
"TROLL2", "CgkIspzRq_8NEAIQ1wE",
|
||||||
|
"TROLL3", "CgkIspzRq_8NEAIQ2AE",
|
||||||
|
"TROLL4", "CgkIspzRq_8NEAIQ2QE",
|
||||||
|
"GRAILH", "CgkIspzRq_8NEAIQ2gE",
|
||||||
|
"HARDCORE", "CgkIspzRq_8NEAIQ3AE",
|
||||||
|
"SHMUP", "CgkIspzRq_8NEAIQ2wE",
|
||||||
|
"SLASH2", "CgkIspzRq_8NEAIQzwE",
|
||||||
|
"GOSWORD", "CgkIspzRq_8NEAIQ0AE",
|
||||||
|
|
||||||
|
"HALLOWEEN1", "CgkIspzRq_8NEAIQ5wE",
|
||||||
|
"HALLOWEEN2", "CgkIspzRq_8NEAIQ6AE",
|
||||||
|
"GOBLINSWORD", "CgkIspzRq_8NEAIQ6QE",
|
||||||
|
|
||||||
|
"DOD2", "CgkIspzRq_8NEAIQ6wE",
|
||||||
|
"DOD3", "CgkIspzRq_8NEAIQ7AE",
|
||||||
|
"DOD4", "CgkIspzRq_8NEAIQ7QE",
|
||||||
|
"DUNG2", "CgkIspzRq_8NEAIQ7gE",
|
||||||
|
"DUNG3", "CgkIspzRq_8NEAIQ7wE",
|
||||||
|
"DUNG4", "CgkIspzRq_8NEAIQ8AE",
|
||||||
|
"MOUNT2", "CgkIspzRq_8NEAIQ8QE",
|
||||||
|
"MOUNT3", "CgkIspzRq_8NEAIQ8gE",
|
||||||
|
"MOUNT4", "CgkIspzRq_8NEAIQ8wE",
|
||||||
|
|
||||||
|
"PRAIR2", "CgkIspzRq_8NEAIQ9wE",
|
||||||
|
"PRAIR3", "CgkIspzRq_8NEAIQ-AE",
|
||||||
|
"PRAIR4", "CgkIspzRq_8NEAIQ-QE",
|
||||||
|
"BULL2", "CgkIspzRq_8NEAIQ-gE",
|
||||||
|
"BULL3", "CgkIspzRq_8NEAIQ-wE",
|
||||||
|
"BULL4", "CgkIspzRq_8NEAIQ_AE",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *getGoogleAchievementID(const string& s) {
|
||||||
|
const char** a = achievementIDs;
|
||||||
|
while(*a && **a) {
|
||||||
|
if(a[0] == s) return a[1];
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qleader, leaders[NUMLEADER];
|
||||||
|
|
||||||
|
int pshift;
|
||||||
|
|
||||||
|
void showMenu() {
|
||||||
|
dialog::init();
|
||||||
|
dialog::addItem(XLAT("return to the game"), ' ');
|
||||||
|
if(!currentlyConnecting())
|
||||||
|
dialog::addBoolItem(XLAT("connected to Google Games"), currentlyConnected(), '1');
|
||||||
|
else
|
||||||
|
dialog::addBreak(100);
|
||||||
|
dialog::addItem(XLAT("view your achievements"), '2');
|
||||||
|
dialog::addItem(XLAT("next page"), '3');
|
||||||
|
|
||||||
|
qleader = 0;
|
||||||
|
for(int i=0; i<NUMLEADER; i++) if(leaderboardIDs[i] != "")
|
||||||
|
leaders[qleader++] = i;
|
||||||
|
|
||||||
|
dialog::addBreak(50);
|
||||||
|
|
||||||
|
for(int i=0; i<10; i++) {
|
||||||
|
int ip = i + pshift;
|
||||||
|
if(ip < qleader) {
|
||||||
|
int id = leaders[ip];
|
||||||
|
int sco = currentscore[id];
|
||||||
|
string ss = sco >= 0 ? its(sco) : SCORE_UNKNOWN ? "?" : "-";
|
||||||
|
dialog::addSelItem(leadernames[id], ss, 'a' + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dialog::display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleKey(int sym, int uni) {
|
||||||
|
dialog::handleNavigation(sym, uni);
|
||||||
|
if(uni == '1')
|
||||||
|
switchGoogleConnection();
|
||||||
|
else if(uni == '2')
|
||||||
|
viewAchievements();
|
||||||
|
else if(uni == '3') {
|
||||||
|
pshift += 10;
|
||||||
|
if(pshift >= qleader) pshift = 0;
|
||||||
|
}
|
||||||
|
else if(uni >= 'a' && uni <= 'a' + 10) {
|
||||||
|
int id = (uni - 'a') + pshift;
|
||||||
|
if(id >= qleader) return;
|
||||||
|
viewLeaderboard(leaderboardIDs[leaders[id]]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cmode = emNormal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ccon = false;
|
||||||
|
bool incon = false;
|
||||||
|
|
||||||
|
bool currentlyConnected() { return ccon; }
|
||||||
|
bool currentlyConnecting() { return incon; }
|
||||||
|
|
||||||
|
int scale(int i) { if(i == 13 || i == 15 || i == 29 || i == 45) return 1000; else return 1; }
|
||||||
|
|
||||||
|
bool isDescending(int i) { return !isAscending(i); }
|
||||||
|
|
||||||
|
}
|
76
graph.cpp
76
graph.cpp
@ -94,6 +94,8 @@ charstyle& getcs() {
|
|||||||
return vid.cs;
|
return vid.cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool camelotcheat;
|
||||||
|
|
||||||
int playergender() {
|
int playergender() {
|
||||||
return (getcs().charid&1) ? GEN_F : GEN_M;
|
return (getcs().charid&1) ? GEN_F : GEN_M;
|
||||||
}
|
}
|
||||||
@ -3263,8 +3265,15 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
|||||||
|
|
||||||
if(c->land == laCamelot) {
|
if(c->land == laCamelot) {
|
||||||
int d = showoff ? 0 : ((euclid||c->master->alt) ? celldistAltRelative(c) : 0);
|
int d = showoff ? 0 : ((euclid||c->master->alt) ? celldistAltRelative(c) : 0);
|
||||||
if(d < 0)
|
#ifdef TOUR
|
||||||
|
if(!tour::on) camelotcheat = false;
|
||||||
|
if(camelotcheat)
|
||||||
|
fcol = (d&1) ? 0xC0C0C0 : 0x606060;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if(d < 0) {
|
||||||
fcol = 0xA0A0A0;
|
fcol = 0xA0A0A0;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// a nice floor pattern
|
// a nice floor pattern
|
||||||
int v = emeraldval(c);
|
int v = emeraldval(c);
|
||||||
@ -4336,7 +4345,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
|||||||
|
|
||||||
#ifndef NOEDIT
|
#ifndef NOEDIT
|
||||||
|
|
||||||
if(cmode == emMapEditor && mapeditor::displaycodes) {
|
if(mapeditor::displaycodes) {
|
||||||
|
|
||||||
int labeli = mapeditor::displaycodes == 1 ? mapeditor::realpattern(c) : mapeditor::subpattern(c);
|
int labeli = mapeditor::displaycodes == 1 ? mapeditor::realpattern(c) : mapeditor::subpattern(c);
|
||||||
|
|
||||||
@ -5417,6 +5426,10 @@ string buildHelpText() {
|
|||||||
h += XLAT("See more on the website: ")
|
h += XLAT("See more on the website: ")
|
||||||
+ "http//roguetemple.com/z/hyper/\n\n";
|
+ "http//roguetemple.com/z/hyper/\n\n";
|
||||||
|
|
||||||
|
#ifdef TOUR
|
||||||
|
h += XLAT("Try the Tutorial to help with understanding the "
|
||||||
|
"geometry of HyperRogue (menu -> special modes).\n\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
h += XLAT("Still confused? Read the FAQ on the HyperRogue website!\n\n");
|
h += XLAT("Still confused? Read the FAQ on the HyperRogue website!\n\n");
|
||||||
|
|
||||||
@ -6249,6 +6262,9 @@ void drawthemap() {
|
|||||||
mouseovers = XLAT("Press F1 or right click for help");
|
mouseovers = XLAT("Press F1 or right click for help");
|
||||||
#ifdef ROGUEVIZ
|
#ifdef ROGUEVIZ
|
||||||
if(rogueviz::on) mouseovers = " ";
|
if(rogueviz::on) mouseovers = " ";
|
||||||
|
#endif
|
||||||
|
#ifdef TOUR
|
||||||
|
if(tour::on) mouseovers = tour::tourhelp;
|
||||||
#endif
|
#endif
|
||||||
centdist = 1e20; centerover = NULL;
|
centdist = 1e20; centerover = NULL;
|
||||||
|
|
||||||
@ -6284,6 +6300,10 @@ void drawthemap() {
|
|||||||
rogueviz::drawExtra();
|
rogueviz::drawExtra();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TOUR
|
||||||
|
if(tour::on) tour::presentation(2);
|
||||||
|
#endif
|
||||||
|
|
||||||
profile_stop(1);
|
profile_stop(1);
|
||||||
profile_start(4);
|
profile_start(4);
|
||||||
drawMarkers();
|
drawMarkers();
|
||||||
@ -6612,9 +6632,9 @@ void calcparam() {
|
|||||||
vid.ycenter = vid.yres - realradius - vid.fsize - (ISIOS ? 10 : 0);
|
vid.ycenter = vid.yres - realradius - vid.fsize - (ISIOS ? 10 : 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(vid.xres >= vid.yres * 4/3 && dialog::sidedialog && cmode == emNumber)
|
if(vid.xres >= vid.yres * 5/4-16 && dialog::sidedialog && cmode == emNumber)
|
||||||
sidescreen = true;
|
sidescreen = true;
|
||||||
if(viewdists && cmode == emNormal && vid.xres >= vid.yres * 4/3) sidescreen = true;
|
if(viewdists && cmode == emNormal && vid.xres > vid.yres) sidescreen = true;
|
||||||
if(sidescreen) vid.xcenter = vid.yres/2;
|
if(sidescreen) vid.xcenter = vid.yres/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6689,6 +6709,9 @@ string timeline() {
|
|||||||
void showGameover() {
|
void showGameover() {
|
||||||
|
|
||||||
dialog::init(
|
dialog::init(
|
||||||
|
#ifdef TOUR
|
||||||
|
tour::on ? (canmove ? XLAT("Tutorial") : XLAT("GAME OVER")) :
|
||||||
|
#endif
|
||||||
cheater ? XLAT("It is a shame to cheat!") :
|
cheater ? XLAT("It is a shame to cheat!") :
|
||||||
showoff ? XLAT("Showoff mode") :
|
showoff ? XLAT("Showoff mode") :
|
||||||
canmove && princess::challenge ? XLAT("%1 Challenge", moPrincess) :
|
canmove && princess::challenge ? XLAT("%1 Challenge", moPrincess) :
|
||||||
@ -6699,7 +6722,8 @@ void showGameover() {
|
|||||||
dialog::addInfo(XLAT("Your score: %1", its(gold())));
|
dialog::addInfo(XLAT("Your score: %1", its(gold())));
|
||||||
dialog::addInfo(XLAT("Enemies killed: %1", its(tkills())));
|
dialog::addInfo(XLAT("Enemies killed: %1", its(tkills())));
|
||||||
|
|
||||||
if(items[itOrbYendor]) {
|
if(tour::on) ;
|
||||||
|
else if(items[itOrbYendor]) {
|
||||||
dialog::addInfo(XLAT("Orbs of Yendor found: %1", its(items[itOrbYendor])), iinf[itOrbYendor].color);
|
dialog::addInfo(XLAT("Orbs of Yendor found: %1", its(items[itOrbYendor])), iinf[itOrbYendor].color);
|
||||||
dialog::addInfo(XLAT("CONGRATULATIONS!"), iinf[itOrbYendor].color);
|
dialog::addInfo(XLAT("CONGRATULATIONS!"), iinf[itOrbYendor].color);
|
||||||
}
|
}
|
||||||
@ -6728,6 +6752,9 @@ void showGameover() {
|
|||||||
timerstart = time(NULL);
|
timerstart = time(NULL);
|
||||||
|
|
||||||
if(princess::challenge) ;
|
if(princess::challenge) ;
|
||||||
|
#ifdef TOUR
|
||||||
|
else if(tour::on) ;
|
||||||
|
#endif
|
||||||
else if(tkills() < 100)
|
else if(tkills() < 100)
|
||||||
dialog::addInfo(XLAT("Defeat 100 enemies to access the Graveyard"));
|
dialog::addInfo(XLAT("Defeat 100 enemies to access the Graveyard"));
|
||||||
else if(kills[moVizier] == 0 && (items[itFernFlower] < 5 || items[itGold] < 5))
|
else if(kills[moVizier] == 0 && (items[itFernFlower] < 5 || items[itGold] < 5))
|
||||||
@ -6773,6 +6800,30 @@ void showGameover() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
|
|
||||||
|
bool intour = false;
|
||||||
|
|
||||||
|
#ifdef TOUR
|
||||||
|
intour = tour::on;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(intour) {
|
||||||
|
if(canmove) {
|
||||||
|
dialog::addItem("spherical geometry", '1');
|
||||||
|
dialog::addItem("Euclidean geometry", '2');
|
||||||
|
dialog::addItem("more curved hyperbolic geometry", '3');
|
||||||
|
}
|
||||||
|
dialog::addItem("teleport away", '4');
|
||||||
|
if(canmove) {
|
||||||
|
dialog::addItem("slide-specific command", '5');
|
||||||
|
dialog::addItem("static mode", '6');
|
||||||
|
dialog::addItem("enable/disable texts", '7');
|
||||||
|
dialog::addItem("next slide", SDLK_RETURN);
|
||||||
|
dialog::addItem("previous slide", SDLK_BACKSPACE);
|
||||||
|
}
|
||||||
|
dialog::addItem("main menu", 'v');
|
||||||
|
}
|
||||||
|
else {
|
||||||
dialog::addItem(canmove ? "continue" : "see how it ended", SDLK_ESCAPE);
|
dialog::addItem(canmove ? "continue" : "see how it ended", SDLK_ESCAPE);
|
||||||
dialog::addItem("main menu", 'v');
|
dialog::addItem("main menu", 'v');
|
||||||
dialog::addItem("restart", SDLK_F5);
|
dialog::addItem("restart", SDLK_F5);
|
||||||
@ -6782,6 +6833,7 @@ void showGameover() {
|
|||||||
#ifdef ANDROIDSHARE
|
#ifdef ANDROIDSHARE
|
||||||
dialog::addItem("SHARE", 's'-96);
|
dialog::addItem("SHARE", 's'-96);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
dialog::display();
|
dialog::display();
|
||||||
|
|
||||||
@ -7118,12 +7170,12 @@ void drawStats() {
|
|||||||
dialog::addInfo(its(qty[i]), distcolors[i&7]);
|
dialog::addInfo(its(qty[i]), distcolors[i&7]);
|
||||||
if(geometry == gNormal && !purehepta) {
|
if(geometry == gNormal && !purehepta) {
|
||||||
dialog::addBreak(200);
|
dialog::addBreak(200);
|
||||||
dialog::addInfo("a(d+4) = a(d+3) + a(d+2) + a(d+1) - a(d)", 0xFFFFFF);
|
dialog::addHelp("a(d+4) = a(d+3) + a(d+2) + a(d+1) - a(d)");
|
||||||
dialog::addInfo("a(d) ~ 1.72208^d", 0xFFFFFF);
|
dialog::addInfo("a(d) ~ 1.72208^d", 0xFFFFFF);
|
||||||
}
|
}
|
||||||
if(geometry == gNormal && purehepta) {
|
if(geometry == gNormal && purehepta) {
|
||||||
dialog::addBreak(200);
|
dialog::addBreak(200);
|
||||||
dialog::addInfo("a(d+2) = 3a(d+1) - a(d+2)", 0xFFFFFF);
|
dialog::addHelp("a(d+2) = 3a(d+1) - a(d+2)");
|
||||||
dialog::addInfo("a(d) ~ 2.61803^d", 0xFFFFFF);
|
dialog::addInfo("a(d) ~ 2.61803^d", 0xFFFFFF);
|
||||||
}
|
}
|
||||||
if(geometry == gEuclid) {
|
if(geometry == gEuclid) {
|
||||||
@ -7572,8 +7624,12 @@ void drawscreen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MOBILE
|
#ifndef MOBILE
|
||||||
if(cmode == emNormal || cmode == emVisual1 || cmode == emVisual2 || cmode == emChangeMode )
|
if(cmode == emNormal || cmode == emVisual1 || cmode == emVisual2 || cmode == emChangeMode ) {
|
||||||
|
if(tour::on)
|
||||||
|
displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(ESC) tour menu"), SDLK_ESCAPE, 16);
|
||||||
|
else
|
||||||
displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(v) menu"), 'v', 16);
|
displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(v) menu"), 'v', 16);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(cmode == emQuit) {
|
if(cmode == emQuit) {
|
||||||
@ -8321,6 +8377,10 @@ void handleKeyNormal(int sym, int uni, extra& ev) {
|
|||||||
|
|
||||||
void handlekey(int sym, int uni, extra& ev) {
|
void handlekey(int sym, int uni, extra& ev) {
|
||||||
|
|
||||||
|
#ifdef TOUR
|
||||||
|
if(tour::on && tour::handleKeyTour(sym, uni)) return;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(((cmode == emNormal && canmove) || (cmode == emQuit && !canmove) || cmode == emDraw || cmode == emMapEditor) && DEFAULTCONTROL && !rug::rugged) {
|
if(((cmode == emNormal && canmove) || (cmode == emQuit && !canmove) || cmode == emDraw || cmode == emMapEditor) && DEFAULTCONTROL && !rug::rugged) {
|
||||||
#ifndef PANDORA
|
#ifndef PANDORA
|
||||||
if(sym == SDLK_RIGHT)
|
if(sym == SDLK_RIGHT)
|
||||||
|
@ -241,6 +241,15 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { PHASE(2); para
|
|||||||
else if(argis("--run")) {
|
else if(argis("--run")) {
|
||||||
PHASE(3); mainloop(); quitmainloop = false;
|
PHASE(3); mainloop(); quitmainloop = false;
|
||||||
}
|
}
|
||||||
|
#ifdef TOUR
|
||||||
|
else if(argis("--tour")) {
|
||||||
|
PHASE(3); tour::start();
|
||||||
|
}
|
||||||
|
else if(argis("--presentation")) {
|
||||||
|
PHASE(3); tour::texts = false;
|
||||||
|
tour::start();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if(argis("--draw")) {
|
else if(argis("--draw")) {
|
||||||
PHASE(3); drawscreen();
|
PHASE(3); drawscreen();
|
||||||
}
|
}
|
||||||
|
21
hyper.h
21
hyper.h
@ -1127,3 +1127,24 @@ void clearHexes(heptagon *at);
|
|||||||
void verifycells(heptagon *at);
|
void verifycells(heptagon *at);
|
||||||
int zebra40(cell *c);
|
int zebra40(cell *c);
|
||||||
cell *createMov(cell *c, int d);
|
cell *createMov(cell *c, int d);
|
||||||
|
|
||||||
|
#ifndef MOBWEB
|
||||||
|
#ifndef TOUR
|
||||||
|
#define TOUR
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TOUR
|
||||||
|
namespace tour {
|
||||||
|
extern bool on;
|
||||||
|
extern string tourhelp;
|
||||||
|
|
||||||
|
bool handleKeyTour(int sym, int uni);
|
||||||
|
void presentation(int mode);
|
||||||
|
int getid();
|
||||||
|
|
||||||
|
eLand getNext(eLand old);
|
||||||
|
bool quickfind(eLand next);
|
||||||
|
void start();
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
9
init.cpp
9
init.cpp
@ -1,6 +1,6 @@
|
|||||||
#define VER "9.4e"
|
#define VER "9.4f"
|
||||||
#define VERNUM 9405
|
#define VERNUM 9406
|
||||||
#define VERNUM_HEX 0x9405
|
#define VERNUM_HEX 0x9406
|
||||||
|
|
||||||
#define GEN_M 0
|
#define GEN_M 0
|
||||||
#define GEN_F 1
|
#define GEN_F 1
|
||||||
@ -162,6 +162,9 @@ const char *loadlevel = NULL;
|
|||||||
#include "graph.cpp"
|
#include "graph.cpp"
|
||||||
#include "sound.cpp"
|
#include "sound.cpp"
|
||||||
#include "achievement.cpp"
|
#include "achievement.cpp"
|
||||||
|
#ifdef TOUR
|
||||||
|
#include "tour.cpp"
|
||||||
|
#endif
|
||||||
#ifndef MOBILE
|
#ifndef MOBILE
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
33
landgen.cpp
33
landgen.cpp
@ -1582,6 +1582,13 @@ eLand getNewLand(eLand old) {
|
|||||||
// return landtab[items[itStrongWind]++ % 10];
|
// return landtab[items[itStrongWind]++ % 10];
|
||||||
// if(old != laPrairie) return laRiver;
|
// if(old != laPrairie) return laRiver;
|
||||||
|
|
||||||
|
#ifdef TOUR
|
||||||
|
if(tour::on) {
|
||||||
|
eLand l = tour::getNext(old);
|
||||||
|
if(l) return l;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LOCAL
|
#ifdef LOCAL
|
||||||
extern bool doAutoplay;
|
extern bool doAutoplay;
|
||||||
if(doAutoplay)
|
if(doAutoplay)
|
||||||
@ -2680,6 +2687,14 @@ void setLandQuotient(cell *c) {
|
|||||||
setland(c, eLand(laEFire + (fv%4)));
|
setland(c, eLand(laEFire + (fv%4)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool quickfind(eLand l) {
|
||||||
|
if(l == cheatdest) return true;
|
||||||
|
#ifdef TOUR
|
||||||
|
if(tour::on && tour::quickfind(l)) return true;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void setLandSphere(cell *c) {
|
void setLandSphere(cell *c) {
|
||||||
if(euclidland == laWarpCoast)
|
if(euclidland == laWarpCoast)
|
||||||
setland(c, getHemisphere(c, 0) > 0 ? laWarpCoast : laWarpSea);
|
setland(c, getHemisphere(c, 0) > 0 ? laWarpCoast : laWarpSea);
|
||||||
@ -2908,7 +2923,7 @@ void buildBigStuff(cell *c, cell *from) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((!chaosmode) && bearsCamelot(c->land) && c->type == 7 &&
|
if((!chaosmode) && bearsCamelot(c->land) && c->type == 7 &&
|
||||||
(cheatdest == laCamelot || (hrand(2000) < 200 &&
|
(quickfind(laCamelot) || (hrand(2000) < 200 &&
|
||||||
items[itEmerald] >= 5 && !tactic::on))) {
|
items[itEmerald] >= 5 && !tactic::on))) {
|
||||||
int rtr = newRoundTableRadius();
|
int rtr = newRoundTableRadius();
|
||||||
heptagon *alt = createAlternateMap(c, rtr+14, hsOrigin);
|
heptagon *alt = createAlternateMap(c, rtr+14, hsOrigin);
|
||||||
@ -2923,18 +2938,18 @@ void buildBigStuff(cell *c, cell *from) {
|
|||||||
// buildbigstuff
|
// buildbigstuff
|
||||||
|
|
||||||
if(c->land == laRlyeh && c->type == 7 &&
|
if(c->land == laRlyeh && c->type == 7 &&
|
||||||
(cheatdest == laTemple || (hrand(2000) < 100 &&
|
(quickfind(laTemple) || (hrand(2000) < 100 &&
|
||||||
items[itStatue] >= 5 && !randomPatternsMode &&
|
items[itStatue] >= 5 && !randomPatternsMode &&
|
||||||
!tactic::on && !yendor::on)))
|
!tactic::on && !yendor::on)))
|
||||||
createAlternateMap(c, 2, hsA);
|
createAlternateMap(c, 2, hsA);
|
||||||
|
|
||||||
if(c->land == laJungle && c->type == 7 &&
|
if(c->land == laJungle && c->type == 7 &&
|
||||||
(cheatdest == laMountain || (hrand(2000) < 100 &&
|
(quickfind(laMountain) || (hrand(2000) < 100 &&
|
||||||
!randomPatternsMode && !tactic::on && !yendor::on && landUnlocked(laMountain))))
|
!randomPatternsMode && !tactic::on && !yendor::on && landUnlocked(laMountain))))
|
||||||
createAlternateMap(c, 2, hsA);
|
createAlternateMap(c, 2, hsA);
|
||||||
|
|
||||||
if(c->land == laOvergrown && c->type == 7 &&
|
if(c->land == laOvergrown && c->type == 7 &&
|
||||||
(cheatdest == laClearing || (hrand(2000) < 25 &&
|
(quickfind(laClearing) || (hrand(2000) < 25 &&
|
||||||
!randomPatternsMode && items[itMutant] >= 5 &&
|
!randomPatternsMode && items[itMutant] >= 5 &&
|
||||||
!tactic::on && !yendor::on))) {
|
!tactic::on && !yendor::on))) {
|
||||||
heptagon *h = createAlternateMap(c, 2, hsA);
|
heptagon *h = createAlternateMap(c, 2, hsA);
|
||||||
@ -2947,7 +2962,7 @@ void buildBigStuff(cell *c, cell *from) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(c->land == laOcean && c->type == 7 && deepOcean && !generatingEquidistant &&
|
if(c->land == laOcean && c->type == 7 && deepOcean && !generatingEquidistant &&
|
||||||
(cheatdest == laWhirlpool || (
|
(quickfind(laWhirlpool) || (
|
||||||
hrand(2000) < (purehepta ? 500 : 1000) && !tactic::on && !yendor::on)))
|
hrand(2000) < (purehepta ? 500 : 1000) && !tactic::on && !yendor::on)))
|
||||||
createAlternateMap(c, 2, hsA);
|
createAlternateMap(c, 2, hsA);
|
||||||
|
|
||||||
@ -3555,6 +3570,7 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
}
|
}
|
||||||
c->wparam = 1 + hrand(reptilemax());
|
c->wparam = 1 + hrand(reptilemax());
|
||||||
}
|
}
|
||||||
|
// c->wall = waReptile; c->wparam = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(c->land == laBurial) {
|
if(c->land == laBurial) {
|
||||||
@ -4659,7 +4675,10 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
c->monst = moTortoise;
|
c->monst = moTortoise;
|
||||||
c->hitpoints = 3;
|
c->hitpoints = 3;
|
||||||
}
|
}
|
||||||
if((tactic::on || euclid) && hrand(4000) < 50 + items[itBabyTortoise]*2 && !safety) {
|
|
||||||
|
int chance = 50 + items[itBabyTortoise]*2;
|
||||||
|
if(quickfind(laTortoise)) chance += 150;
|
||||||
|
if((tactic::on || euclid) && hrand(4000) < chance && !safety) {
|
||||||
c->item = itBabyTortoise;
|
c->item = itBabyTortoise;
|
||||||
tortoise::babymap[c] = getBits(c) ^ tortoise::getRandomBits();
|
tortoise::babymap[c] = getBits(c) ^ tortoise::getRandomBits();
|
||||||
}
|
}
|
||||||
@ -4885,7 +4904,7 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
if(c->land == laBurial && !safety) {
|
if(c->land == laBurial && !safety) {
|
||||||
if(hrand(15000) < 5 + 3 * items[itBarrow] + 4 * hard)
|
if(hrand(15000) < 5 + 3 * items[itBarrow] + 4 * hard)
|
||||||
c->monst = moDraugr;
|
c->monst = moDraugr;
|
||||||
else if(hrand(5000) < 20)
|
else if(hrand(5000) < 20 + (quickfind(laBurial) ? 40 : 0))
|
||||||
c->item = itOrbSword;
|
c->item = itOrbSword;
|
||||||
}
|
}
|
||||||
if(c->land == laJungle) {
|
if(c->land == laJungle) {
|
||||||
|
12
menus.cpp
12
menus.cpp
@ -819,6 +819,10 @@ void showChangeMode() {
|
|||||||
|
|
||||||
// gameplay modes
|
// gameplay modes
|
||||||
|
|
||||||
|
#ifdef TOUR
|
||||||
|
dialog::addBoolItem(XLAT("tutorial"), tour::on, 'T');
|
||||||
|
#endif
|
||||||
|
|
||||||
dialog::addBoolItem(XLAT("Euclidean/elliptic mode"), (euclid || sphere), 'e');
|
dialog::addBoolItem(XLAT("Euclidean/elliptic mode"), (euclid || sphere), 'e');
|
||||||
dialog::addBoolItem(XLAT(SHMUPTITLE), (shmup::on || multi::players > 1), 's');
|
dialog::addBoolItem(XLAT(SHMUPTITLE), (shmup::on || multi::players > 1), 's');
|
||||||
if(!shmup::on) dialog::addSelItem(XLAT("hardcore mode"),
|
if(!shmup::on) dialog::addSelItem(XLAT("hardcore mode"),
|
||||||
@ -863,8 +867,6 @@ void handleChangeMode(int sym, int uni) {
|
|||||||
dialog::handleNavigation(sym, uni);
|
dialog::handleNavigation(sym, uni);
|
||||||
char xuni = uni;
|
char xuni = uni;
|
||||||
|
|
||||||
if((uni >= 'A' && uni <= 'Z') || (uni >= 1 && uni <= 26)) xuni |= 96;
|
|
||||||
|
|
||||||
if(xuni == 'v' || sym == SDLK_F2 || sym == SDLK_ESCAPE) cmode = emNormal;
|
if(xuni == 'v' || sym == SDLK_F2 || sym == SDLK_ESCAPE) cmode = emNormal;
|
||||||
|
|
||||||
else if(uni == 'c') {
|
else if(uni == 'c') {
|
||||||
@ -923,6 +925,12 @@ void handleChangeMode(int sym, int uni) {
|
|||||||
restartGame('7');
|
restartGame('7');
|
||||||
else if(uni == 'a')
|
else if(uni == 'a')
|
||||||
cmode = emConformal;
|
cmode = emConformal;
|
||||||
|
#ifdef TOUR
|
||||||
|
else if(uni == 'T') {
|
||||||
|
cmode = emNormal;
|
||||||
|
tour::start();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if(uni == 'C') {
|
else if(uni == 'C') {
|
||||||
if(!chaosmode) {
|
if(!chaosmode) {
|
||||||
cmode = emHelp;
|
cmode = emHelp;
|
||||||
|
@ -1194,6 +1194,7 @@ void readcolor(const char *cfname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
|
if(on) return;
|
||||||
on = autocheat = true;
|
on = autocheat = true;
|
||||||
#ifndef WEB
|
#ifndef WEB
|
||||||
mapeditor::drawplayer = false;
|
mapeditor::drawplayer = false;
|
||||||
@ -1216,6 +1217,7 @@ void close() {
|
|||||||
vdata.clear();
|
vdata.clear();
|
||||||
labeler.clear();
|
labeler.clear();
|
||||||
legend.clear();
|
legend.clear();
|
||||||
|
on = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void turn(int delta) {
|
void turn(int delta) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# set the version numbers in hyper.rc automatically
|
# set the version numbers in hyper.rc automatically
|
||||||
export VER=`grep "#define VER " hyper.cpp | sed "s/#define VER \"//" | sed "s/\"//"`
|
export VER=`grep "#define VER " hyper.cpp | sed "s/#define VER \"//" | sed "s/\"//"`
|
||||||
#export VERNUM=`grep "#define VERNUM " hyper.cpp | sed "s/#define VERNUM //" | sed "s/^\(.\)\(.\)\(.\)\(.\)$/\1.\2.\4.\3/"`
|
#export VERNUM=`grep "#define VERNUM " hyper.cpp | sed "s/#define VERNUM //" | sed "s/^\(.\)\(.\)\(.\)\(.\)$/\1.\2.\4.\3/"`
|
||||||
VERNUM=9,4,0,4
|
VERNUM=9,4,0,6
|
||||||
#VERNUM=8.1.7.0
|
#VERNUM=8.1.7.0
|
||||||
#echo $VERNUM
|
#echo $VERNUM
|
||||||
sed "s/\"ProductVersion\", \"\(.*\)\"/\"ProductVersion\", \"$VER\"/" -i hyper.rc
|
sed "s/\"ProductVersion\", \"\(.*\)\"/\"ProductVersion\", \"$VER\"/" -i hyper.rc
|
||||||
|
54
steamvisualinterface.cpp
Normal file
54
steamvisualinterface.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// PRIVATE
|
||||||
|
|
||||||
|
#include "sdk/public/steam/steam_api.h"
|
||||||
|
#include "steamvisualinterface.h"
|
||||||
|
|
||||||
|
class SteamContact {
|
||||||
|
public:
|
||||||
|
|
||||||
|
STEAM_CALLBACK( SteamContact, OnUserStatsReceived, UserStatsReceived_t, m_CallbackStatsReceived );
|
||||||
|
SteamContact ();
|
||||||
|
|
||||||
|
void OnFindLeaderboard( LeaderboardFindResult_t *pFindLearderboardResult, bool bIOFailure );
|
||||||
|
void OnDownloadScores( LeaderboardScoresDownloaded_t *pLeaderboardScoresDownloaded, bool bIOFailure );
|
||||||
|
CCallResult<SteamContact, LeaderboardFindResult_t> m_SteamCallResultCreateLeaderboard;
|
||||||
|
CCallResult<SteamContact, LeaderboardScoresDownloaded_t> m_SteamCallResultScoresDownloaded;
|
||||||
|
};
|
||||||
|
|
||||||
|
SteamContact :: SteamContact()
|
||||||
|
: m_CallbackStatsReceived(this, &SteamContact::OnUserStatsReceived)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
static SteamContact *steam;
|
||||||
|
|
||||||
|
callback_statsreceived sr;
|
||||||
|
callback_findleaderboard fl;
|
||||||
|
callback_scoresdownload sdl;
|
||||||
|
|
||||||
|
void init_steamvisualinterface(callback_statsreceived _sr, callback_findleaderboard _fl, callback_scoresdownload _sdl) {
|
||||||
|
sr = _sr;
|
||||||
|
fl = _fl;
|
||||||
|
sdl = _sdl;
|
||||||
|
steam = new SteamContact;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_callback(SteamAPICall_t handle) {
|
||||||
|
steam->m_SteamCallResultCreateLeaderboard.Set( handle, steam, &SteamContact::OnFindLeaderboard );
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_callback_download(SteamAPICall_t handle) {
|
||||||
|
steam->m_SteamCallResultScoresDownloaded.Set( handle, steam, &SteamContact::OnDownloadScores );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SteamContact::OnFindLeaderboard( LeaderboardFindResult_t *pFindLeaderboardResult, bool bIOFailure ) {
|
||||||
|
fl(pFindLeaderboardResult, bIOFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SteamContact::OnDownloadScores( LeaderboardScoresDownloaded_t *pLeaderboardScoresDownloaded, bool bIOFailure ) {
|
||||||
|
sdl(pLeaderboardScoresDownloaded, bIOFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SteamContact::OnUserStatsReceived( UserStatsReceived_t *pCallback ) {
|
||||||
|
sr(pCallback);
|
||||||
|
}
|
||||||
|
|
26
system.cpp
26
system.cpp
@ -141,6 +141,9 @@ void initgame() {
|
|||||||
|
|
||||||
yendor::init(3);
|
yendor::init(3);
|
||||||
multi::revive_queue.clear();
|
multi::revive_queue.clear();
|
||||||
|
#ifdef TOUR
|
||||||
|
if(tour::on) tour::presentation(5);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(multi::players > 1 && !shmup::on) {
|
if(multi::players > 1 && !shmup::on) {
|
||||||
for(int i=0; i<numplayers(); i++)
|
for(int i=0; i<numplayers(); i++)
|
||||||
@ -170,6 +173,9 @@ void initgame() {
|
|||||||
if(firstland != (princess::challenge ? laPalace : laIce)) cheater++;
|
if(firstland != (princess::challenge ? laPalace : laIce)) cheater++;
|
||||||
}
|
}
|
||||||
if(tactic::trailer) ;
|
if(tactic::trailer) ;
|
||||||
|
#ifdef TOUR
|
||||||
|
else if(tour::on) ; // displayed by tour
|
||||||
|
#endif
|
||||||
else if(princess::challenge) {
|
else if(princess::challenge) {
|
||||||
kills[moVizier] = 1;
|
kills[moVizier] = 1;
|
||||||
princess::forceMouse = true;
|
princess::forceMouse = true;
|
||||||
@ -617,6 +623,9 @@ void saveStats(bool emergency = false) {
|
|||||||
DEBB(DF_INIT, (debugfile,"saveStats [%s]\n", scorefile));
|
DEBB(DF_INIT, (debugfile,"saveStats [%s]\n", scorefile));
|
||||||
|
|
||||||
if(autocheat) return;
|
if(autocheat) return;
|
||||||
|
#ifdef TOUR
|
||||||
|
if(tour::on) return;
|
||||||
|
#endif
|
||||||
if(randomPatternsMode) return;
|
if(randomPatternsMode) return;
|
||||||
|
|
||||||
remove_emergency_save();
|
remove_emergency_save();
|
||||||
@ -738,6 +747,10 @@ void saveStats(bool emergency = false) {
|
|||||||
|
|
||||||
// load the save
|
// load the save
|
||||||
void loadsave() {
|
void loadsave() {
|
||||||
|
if(autocheat) return;
|
||||||
|
#ifdef TOUR
|
||||||
|
if(tour::on) return;
|
||||||
|
#endif
|
||||||
DEBB(DF_INIT, (debugfile,"loadSave\n"));
|
DEBB(DF_INIT, (debugfile,"loadSave\n"));
|
||||||
|
|
||||||
for(int xc=0; xc<MODECODES; xc++)
|
for(int xc=0; xc<MODECODES; xc++)
|
||||||
@ -851,6 +864,7 @@ namespace gamestack {
|
|||||||
heptspin viewctr;
|
heptspin viewctr;
|
||||||
transmatrix View;
|
transmatrix View;
|
||||||
eGeometry geometry;
|
eGeometry geometry;
|
||||||
|
bool hepta;
|
||||||
};
|
};
|
||||||
|
|
||||||
vector<gamedata> gd;
|
vector<gamedata> gd;
|
||||||
@ -868,6 +882,7 @@ namespace gamestack {
|
|||||||
gdn.viewctr = viewctr;
|
gdn.viewctr = viewctr;
|
||||||
gdn.View = View;
|
gdn.View = View;
|
||||||
gdn.geometry = geometry;
|
gdn.geometry = geometry;
|
||||||
|
gdn.hepta = purehepta;
|
||||||
gd.push_back(gdn);
|
gd.push_back(gdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -878,6 +893,7 @@ namespace gamestack {
|
|||||||
viewctr = gdn.viewctr;
|
viewctr = gdn.viewctr;
|
||||||
View = gdn.View;
|
View = gdn.View;
|
||||||
geometry = gdn.geometry;
|
geometry = gdn.geometry;
|
||||||
|
purehepta = gdn.hepta;
|
||||||
resetGeometry();
|
resetGeometry();
|
||||||
gd.pop_back();
|
gd.pop_back();
|
||||||
bfs();
|
bfs();
|
||||||
@ -928,6 +944,16 @@ void restartGame(char switchWhat, bool push) {
|
|||||||
resetGeometry();
|
resetGeometry();
|
||||||
chaosmode = !chaosmode;
|
chaosmode = !chaosmode;
|
||||||
}
|
}
|
||||||
|
#ifdef TOUR
|
||||||
|
if(switchWhat == 'T') {
|
||||||
|
geometry = gNormal;
|
||||||
|
yendor::on = tactic::on = princess::challenge = false;
|
||||||
|
chaosmode = purehepta = randomPatternsMode = false;
|
||||||
|
shmup::on = false;
|
||||||
|
resetGeometry();
|
||||||
|
tour::on = !tour::on;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if(switchWhat == '7') {
|
if(switchWhat == '7') {
|
||||||
if(euclid) geometry = gNormal;
|
if(euclid) geometry = gNormal;
|
||||||
purehepta = !purehepta;
|
purehepta = !purehepta;
|
||||||
|
571
tour.cpp
Normal file
571
tour.cpp
Normal file
@ -0,0 +1,571 @@
|
|||||||
|
// work in progress
|
||||||
|
|
||||||
|
namespace tour {
|
||||||
|
|
||||||
|
bool on;
|
||||||
|
|
||||||
|
bool texts = true;
|
||||||
|
|
||||||
|
string tourhelp;
|
||||||
|
|
||||||
|
int currentslide;
|
||||||
|
|
||||||
|
static struct { const char *name; int id; const char *help; } slides[] = {
|
||||||
|
{"Introduction", 10,
|
||||||
|
"This tutorial is mostly aimed to show what is "
|
||||||
|
"special about the geometry used by HyperRogue. "
|
||||||
|
"It also shows the basics of gameplay, and "
|
||||||
|
"how is it affected by geometry.\n\n"
|
||||||
|
"Press Enter to go to the next slide, or ESC to see a "
|
||||||
|
"menu with other options."
|
||||||
|
},
|
||||||
|
{"Basics of gameplay", 11,
|
||||||
|
"The game starts in the Icy Lands. Collect the Ice Diamonds "
|
||||||
|
"(press F1 if you do not know how to move). "
|
||||||
|
"After you collect many of them, monsters will start to pose a challenge.\n"
|
||||||
|
"As is typical in roguelikes and other games based on tactical skill rather "
|
||||||
|
"than story, if you lose, you have to start a new one from the start. "
|
||||||
|
"However, in this tutorial, you can simply press '4' "
|
||||||
|
"to teleport away from a bad situation."
|
||||||
|
"In general, the tutorial is rigged to show you what it "
|
||||||
|
"wants -- for example, in this slide, you can press '5' to get "
|
||||||
|
"lots of Ice Diamonds quickly."
|
||||||
|
},
|
||||||
|
{"Hypersian Rug model", 21,
|
||||||
|
"New players think that the action of HyperRogue takes place on a sphere. "
|
||||||
|
"This is not true -- the next slide will show the surface HyperRogue "
|
||||||
|
"actually takes place on.\n\n"
|
||||||
|
"Use arrow keys to rotate the model, and Page Up/Down to zoom.\n\n"
|
||||||
|
"If you do not see anything, press '5' to try a safer renderer."
|
||||||
|
},
|
||||||
|
{"Expansion", 22,
|
||||||
|
"The next slide shows the number of cells in distance 1, 2, 3, ... from you. "
|
||||||
|
"It grows exponentially: there are more than 10^100 cells "
|
||||||
|
"in radius 1000 around you, and you will move further away during the game!\n\n"
|
||||||
|
"This is extremely important in the design of HyperRogue. "
|
||||||
|
"HyperRogue has many navigational puzzles -- what would be simple in Euclidean world "
|
||||||
|
"is extremely tricky "
|
||||||
|
"in hyperbolic geometry (you want to reach a specific location 20 cells away, "
|
||||||
|
"which of the thousands of possible directions should you take?); however, other things virtually impossible in Euclidean "
|
||||||
|
"world become easy in HyperRogue. "
|
||||||
|
"HyperRogue had to be specially designed so that it is impossible to grind the "
|
||||||
|
"infinite world. There are almost no permanent upgrades; collecting treasures "
|
||||||
|
"brings you benefits, but trying to get too many of the same kind is extremely dangerous."
|
||||||
|
},
|
||||||
|
{"Tiling and Tactics", 23,
|
||||||
|
"The tactics of fighting simple monsters, such as the Yetis from the Icy Lands, "
|
||||||
|
"might appear shallow, but hyperbolic geometry is essential even there. "
|
||||||
|
"In the next slide, you are attacked by two monsters at once. "
|
||||||
|
"You can make them line up simply by "
|
||||||
|
"running away in a straight line. "
|
||||||
|
"Press '2' to try the same in the Euclidean world -- it is impossible."
|
||||||
|
},
|
||||||
|
{"Straight Lines", 24,
|
||||||
|
"Hyperbolic geometry has been created by 19th century mathematicians who "
|
||||||
|
"wondered about the nature of paralellness. Take a line L and a point A. "
|
||||||
|
"Can a world exist where there is more than one line passing through A "
|
||||||
|
"which does not cross L?\n\n"
|
||||||
|
"Wander further, and you should find Crossroads quickly -- "
|
||||||
|
"the Great Walls are straight lines, and indeed, they work differently than in "
|
||||||
|
"Euclidean. On the other side of Great Walls, you see other lands -- "
|
||||||
|
"there are about 50 lands in HyperRogue, based "
|
||||||
|
"on different mechanics and aspects of hyperbolic geometry."
|
||||||
|
},
|
||||||
|
{"Running Dogs", 25,
|
||||||
|
"To learn more about straight lines, "
|
||||||
|
"wander further, and you should find the Land of Eternal Motion. "
|
||||||
|
"Try to run in a straight line, with a Running Dog next to you. "
|
||||||
|
"Even though the Running Dog runs at the same speed as you, "
|
||||||
|
"it will appear to go slower -- this is because you are running "
|
||||||
|
"in a straight line, and the Running Dog has to run in a curve "
|
||||||
|
"called an equidistant."
|
||||||
|
},
|
||||||
|
{"Equidistants", 27,
|
||||||
|
"Equidistants are curves which are at some fixed distance from a "
|
||||||
|
"straight line. Some lands in HyperRogue are based on equidistants; "
|
||||||
|
"you should see them after wandering a bit more.\n\n"
|
||||||
|
"This tutorial gives you freedom to go wherever you choose, "
|
||||||
|
"but we do not recommend going deep into the Dungeon or the Ocean -- "
|
||||||
|
"getting back might be difficult."
|
||||||
|
},
|
||||||
|
{"Circles", 26,
|
||||||
|
"Circles are strange in hyperbolic geometry too. "
|
||||||
|
"Look for the Castle of Camelot in the Crossroads; "
|
||||||
|
"the Round Table inside is a circle of radius 28. "
|
||||||
|
"Finding its center is a difficult challenge.\n\n"
|
||||||
|
"Press '5' to cheat by seeing the smaller circles too."
|
||||||
|
},
|
||||||
|
{"Horocycles", 28,
|
||||||
|
"Horocycles are similar to circles, but you cannot reach their center at all -- "
|
||||||
|
"they can be understood as limit circles of infinite radius centered in some point "
|
||||||
|
"in infinity (also called an ideal point).\n\n"
|
||||||
|
"Go to R'Lyeh, and you should quickly find a Temple of Cthulhu there. "
|
||||||
|
"Each circle of columns is actually a horocycle. Horocycles in a given "
|
||||||
|
"temple are concentric, and there is an infinite number of them."
|
||||||
|
},
|
||||||
|
{"Half-plane model", 47,
|
||||||
|
"The game is normally displayed in the so called Poincaré disk model, "
|
||||||
|
"which is a kind of a map of the infinite hyperbolic world. "
|
||||||
|
"There are many projections of Earth, but since Earth is curved, "
|
||||||
|
"all of them have to distort distances or angles in some way -- "
|
||||||
|
"the same is true in hyperbolic geometry. "
|
||||||
|
"The next slide shows another model, called the Poincaré upper half-plane model. In this model, "
|
||||||
|
"horocycles centered at one specific ideal point are drawn as straight lines."
|
||||||
|
},
|
||||||
|
{"Curvature", 29,
|
||||||
|
"Now, go to the Burial Grounds and find an Orb of the Sword. The Sword appears to "
|
||||||
|
"always be facing in the same direction whatever you do, and it appears that "
|
||||||
|
"you have to rotate the sword to excavate the treasures; "
|
||||||
|
"yet, it is possible to excavate them! You migth have already noticed "
|
||||||
|
"that the world rotates after you move around a loop and return to an old "
|
||||||
|
"place.\n\n"
|
||||||
|
"This is related to the fact that the world of HyperRogue is curved, and "
|
||||||
|
"the sum of angles in a triangle is not equal to 180 degrees."
|
||||||
|
},
|
||||||
|
{"Periodic patterns", 30,
|
||||||
|
"Hyperbolic geometry yields much more interesting periodic patterns "
|
||||||
|
"than Euclidean."
|
||||||
|
},
|
||||||
|
{"Periodic patterns: application", 31,
|
||||||
|
"Many lands in HyperRogue are based around periodic patterns. "
|
||||||
|
"For example, both Zebra and Windy Plains are based on the pattern "
|
||||||
|
"shown in the previous slide. "
|
||||||
|
"Such lands often have tree-like nature."
|
||||||
|
},
|
||||||
|
{"Fractal landscapes", 32,
|
||||||
|
"On the following slide, the colors change smoothly in the whole infinite world. "
|
||||||
|
"Again, this works better than in Euclidean geometry."
|
||||||
|
},
|
||||||
|
{"Fractal landscapes: application", 33,
|
||||||
|
"This is applied in HyperRogue to create landscapes, such as the chasms in the "
|
||||||
|
"land of Reptiles or the Dragon Chasms, which you should find quickly. "
|
||||||
|
"Also in the Dragon Chasms, you can find a Baby Tortoise, and try to find "
|
||||||
|
"a matching adult tortoise in the Galápagos. "
|
||||||
|
"There are over two millions of species, but since there is so much space in "
|
||||||
|
"hyperbolic geometry, finding a matching tortoise is possible. The brighter "
|
||||||
|
"the color in Galápagos is, the more aspects of the tortoises in the given "
|
||||||
|
"area are matching."
|
||||||
|
},
|
||||||
|
{"Poincaré Ball model", 41,
|
||||||
|
"The Poincaré disk model is a model of a hyperbolic *plane* -- you "
|
||||||
|
"might wonder why are the walls rendered in 3D then.\n\n"
|
||||||
|
"HyperRogue actually assumes that the floor level is an equidistant surface "
|
||||||
|
"in a three-dimensional hyperbolic world, and the camera is placed above the "
|
||||||
|
"plane that the surface is equidistant to (which boils down to showing "
|
||||||
|
"the floor level in Poincaré disk model).\n\n"
|
||||||
|
"This is shown on the next slide, in the Poincaré ball model, which is "
|
||||||
|
"the 3D analog of the Poincaré disk model."
|
||||||
|
},
|
||||||
|
{"Hyperboloid model", 42,
|
||||||
|
"Let's see more models of the hyperbolic plane. "
|
||||||
|
"This model uses a hyperboloid in the Minkowski geometry; "
|
||||||
|
"it is used internally by HyperRogue."
|
||||||
|
},
|
||||||
|
{"Beltrami-Klein model", 43,
|
||||||
|
"This model renders straight lines as straight, but it distorts angles."
|
||||||
|
},
|
||||||
|
{"Gans model", 44,
|
||||||
|
"Yet another model, which corresponds to orthographic projection of the "
|
||||||
|
"sphere. Poincaré disk model, Beltrami-Klein model, and the Gans "
|
||||||
|
"model are all obtained by looking at either the hyperboloid model or an "
|
||||||
|
"equidistant surface from various distances."
|
||||||
|
},
|
||||||
|
{"Band model", 45,
|
||||||
|
"The band model is the hyperbolic analog of the Mercator projection of the sphere: "
|
||||||
|
"a given straight line is rendered as a straight line, and the rest of the "
|
||||||
|
"world is mapped conformally, that is, angles are not distorted. "
|
||||||
|
"Here, we take the straight line connecting your starting point and your "
|
||||||
|
"current position -- usually the path taken by the player is surprisingly "
|
||||||
|
"close to a straight line. Press '8' to see this path.\n\n"
|
||||||
|
"If you want, press '5' to see it rendered as a spiral, although it takes lots of time and "
|
||||||
|
"memory."
|
||||||
|
},
|
||||||
|
{"Conformal square model", 46,
|
||||||
|
"The world can be mapped conformally to a square too."
|
||||||
|
},
|
||||||
|
#ifdef ROGUEVIZ
|
||||||
|
{"Collatz conjecture", 51,
|
||||||
|
"Your version of HyperRogue includes RogueViz, which "
|
||||||
|
"is an adaptation of HyperRogue as a visualization tool "
|
||||||
|
"rather than a game. Hyperbolic space is great "
|
||||||
|
"for visualizing some kinds of data because of the vast amount "
|
||||||
|
"of space.\n\n"
|
||||||
|
"The following slide is a visualization of the Collatz conjecture. "
|
||||||
|
"Press '5' for a spiral rendering of the Collatz conjecture visualization."},
|
||||||
|
#endif
|
||||||
|
{"THE END", 99,
|
||||||
|
"This is not everything you can see in HyperRogue. For example, "
|
||||||
|
"hyperbolic mazes are much fun than their Euclidean counterparts. "
|
||||||
|
"Have fun exploring!\n\n"
|
||||||
|
"Press '5' to leave the tutorial mode."
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int getid() {
|
||||||
|
if(!on) return 0;
|
||||||
|
return slides[currentslide].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// modes:
|
||||||
|
// 1 - enter the slide
|
||||||
|
// 2 - each frame
|
||||||
|
// 3 - leave the slide
|
||||||
|
// 4 - quicken or modify the slide
|
||||||
|
// 5 - on initgame
|
||||||
|
|
||||||
|
void setCanvas(int mode, char canv) {
|
||||||
|
static char wc;
|
||||||
|
static eLand ld;
|
||||||
|
if(mode == 1) {
|
||||||
|
wc = mapeditor::whichCanvas;
|
||||||
|
mapeditor::whichCanvas = canv;
|
||||||
|
ld = firstland;
|
||||||
|
firstland = laCanvas;
|
||||||
|
restartGame(0, true);
|
||||||
|
}
|
||||||
|
if(mode == 3) {
|
||||||
|
mapeditor::whichCanvas = wc;
|
||||||
|
firstland = ld;
|
||||||
|
restartGame(0, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sickmode;
|
||||||
|
|
||||||
|
void presentation(int mode) {
|
||||||
|
|
||||||
|
int id = getid();
|
||||||
|
cheater = 0;
|
||||||
|
|
||||||
|
if(id && mode == 1) tourhelp = slides[currentslide].name;
|
||||||
|
|
||||||
|
if(sickmode && !items[itOrbTeleport]) items[itOrbTeleport] = 1;
|
||||||
|
|
||||||
|
if(id == 10 && mode == 1) {
|
||||||
|
if(tour::texts) addMessage(XLAT("Welcome to the HyperRogue tutorial!"));
|
||||||
|
else clearMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 11 && mode == 4)
|
||||||
|
forCellEx(c2, cwt.c)
|
||||||
|
forCellEx(c3, c2)
|
||||||
|
if(c3->wall == waNone && c3->item == itNone && c3->monst == moNone && c3 != cwt.c)
|
||||||
|
c3->item = itDiamond;
|
||||||
|
|
||||||
|
// Hypersian Rug
|
||||||
|
if(id == 21) {
|
||||||
|
static int wm, mm;
|
||||||
|
if(mode == 1) {
|
||||||
|
rug::init();
|
||||||
|
wm = vid.wallmode;
|
||||||
|
mm = vid.monmode;
|
||||||
|
vid.wallmode = 3;
|
||||||
|
vid.monmode = 2;
|
||||||
|
}
|
||||||
|
if(mode == 3) {
|
||||||
|
rug::close();
|
||||||
|
vid.wallmode = wm;
|
||||||
|
vid.monmode = mm;
|
||||||
|
}
|
||||||
|
if(mode == 4) {
|
||||||
|
rug::close();
|
||||||
|
rug::rendernogl = !rug::rendernogl;
|
||||||
|
rug::init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expansion
|
||||||
|
|
||||||
|
if(id == 22) {
|
||||||
|
if(mode == 1) viewdists = true;
|
||||||
|
if(mode == 3) viewdists = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tiling and Tactics
|
||||||
|
|
||||||
|
if(id == 23) {
|
||||||
|
setCanvas(mode, 'F');
|
||||||
|
if(mode == 5) {
|
||||||
|
cwt.c->mov[0]->monst = moRunDog;
|
||||||
|
cwt.c->mov[1]->monst = moGoblin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 26 && mode == 4)
|
||||||
|
camelotcheat = !camelotcheat;
|
||||||
|
|
||||||
|
// Curvature
|
||||||
|
if(id == 29) {
|
||||||
|
if(mode == 4)
|
||||||
|
items[itOrbSword] = 90;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 30) {
|
||||||
|
setCanvas(mode, 't');
|
||||||
|
if(mode == 1)
|
||||||
|
mapeditor::displaycodes = 2,
|
||||||
|
mapeditor::whichPattern = 'z';
|
||||||
|
if(mode == 3)
|
||||||
|
mapeditor::displaycodes = 0,
|
||||||
|
mapeditor::whichPattern = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 32)
|
||||||
|
setCanvas(mode, 'l');
|
||||||
|
|
||||||
|
if(id == 33) {
|
||||||
|
if(mode == 4) {
|
||||||
|
cell *c = cwt.c->mov[0];
|
||||||
|
c->item = itBabyTortoise;
|
||||||
|
tortoise::babymap[c] = getBits(c) ^ tortoise::getRandomBits();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 41) {
|
||||||
|
if(mode == 1) pmodel = mdBall;
|
||||||
|
if(mode == 3) pmodel = mdDisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 42) {
|
||||||
|
if(mode == 1) pmodel = mdHyperboloid;
|
||||||
|
if(mode == 3) pmodel = mdDisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 43) {
|
||||||
|
if(mode == 1) vid.alpha = 0;
|
||||||
|
if(mode == 3) vid.alpha = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 44) {
|
||||||
|
if(mode == 1) vid.alpha = 400, vid.scale = 150;
|
||||||
|
if(mode == 3) vid.alpha = vid.scale = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 45) {
|
||||||
|
if(mode == 1) pmodel = mdBand, conformal::create(), conformal::rotation = 0;
|
||||||
|
if(mode == 3) {
|
||||||
|
conformal::clear(), pmodel = mdDisk;
|
||||||
|
resetview();
|
||||||
|
drawthemap();
|
||||||
|
centerpc(INF);
|
||||||
|
}
|
||||||
|
if(mode == 4) conformal::createImage(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 46) {
|
||||||
|
if(mode == 1) pmodel = mdPolygonal, polygonal::solve();
|
||||||
|
if(mode == 3) pmodel = mdDisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == 47) {
|
||||||
|
if(mode == 1)
|
||||||
|
pmodel = mdHalfplane;
|
||||||
|
if(mode == 2)
|
||||||
|
conformal::rotation = cwt.c->land == laDungeon ? 0 : 2;
|
||||||
|
if(mode == 3) pmodel = mdDisk, conformal::rotation = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ROGUEVIZ
|
||||||
|
if(id == 51) {
|
||||||
|
setCanvas(mode, 'd');
|
||||||
|
if(mode == 1) {
|
||||||
|
rogueviz::dftcolor = 0x206020FF;
|
||||||
|
|
||||||
|
rogueviz::collatz::s2 = .3;
|
||||||
|
rogueviz::collatz::p2 = .5;
|
||||||
|
rogueviz::collatz::s3 = -.4;
|
||||||
|
rogueviz::collatz::p3 = .4;
|
||||||
|
|
||||||
|
rogueviz::showlabels = true;
|
||||||
|
|
||||||
|
rogueviz::on = true;
|
||||||
|
gmatrix.clear();
|
||||||
|
drawthemap();
|
||||||
|
gmatrix0 = gmatrix;
|
||||||
|
|
||||||
|
rogueviz::collatz::start();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mode == 4)
|
||||||
|
pmodel = mdBand, conformal::create(), conformal::rotation = 0,
|
||||||
|
conformal::createImage(true),
|
||||||
|
conformal::clear(), pmodel = mdDisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(id == 99 && mode == 4)
|
||||||
|
restartGame('T');
|
||||||
|
}
|
||||||
|
|
||||||
|
eLand getNext(eLand old) {
|
||||||
|
|
||||||
|
// Straight Lines
|
||||||
|
|
||||||
|
int id = getid();
|
||||||
|
if(id == 24) {
|
||||||
|
if(isCrossroads(old))
|
||||||
|
return pick(
|
||||||
|
pick(laRedRock, laWarpCoast, laMirror),
|
||||||
|
pick(laLivefjord, laAlchemist, laHell),
|
||||||
|
pick(laJungle, laDesert, laRose),
|
||||||
|
pick(laGraveyard, laMotion, laDryForest)
|
||||||
|
);
|
||||||
|
else return laCrossroads;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Running Dogs
|
||||||
|
|
||||||
|
if(id == 25) {
|
||||||
|
if(isCrossroads(old)) return pick(laMotion, laNone);
|
||||||
|
else if(old == laMotion) return laCrossroads;
|
||||||
|
else return laMotion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Circles
|
||||||
|
|
||||||
|
if(id == 26) {
|
||||||
|
if(!isCrossroads(old)) return laCrossroads;
|
||||||
|
// Camelot is a circle
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equidistants
|
||||||
|
|
||||||
|
if(id == 27) {
|
||||||
|
if(isCrossroads(old))
|
||||||
|
return hrand(100) < 20 ? laNone :
|
||||||
|
pick(laOcean, laIvoryTower, laDungeon, laEndorian);
|
||||||
|
else return laCrossroads;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horocycles
|
||||||
|
if(id == 28) {
|
||||||
|
if(isCrossroads(old))
|
||||||
|
return pick(laRlyeh, laNone, laNone);
|
||||||
|
else return pick(laCrossroads, old == laRlyeh ? laNone : laRlyeh);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Curvature
|
||||||
|
if(id == 29) {
|
||||||
|
if(isCrossroads(old))
|
||||||
|
return pick(laBurial, laNone, laNone);
|
||||||
|
else return pick(laCrossroads, old == laBurial ? laNone : laBurial);
|
||||||
|
}
|
||||||
|
|
||||||
|
// periodic patterns application
|
||||||
|
if(id == 31) {
|
||||||
|
if(isCrossroads(old))
|
||||||
|
return pick(
|
||||||
|
pick(laWineyard, laEmerald, laPower),
|
||||||
|
pick(laZebra, laWhirlwind),
|
||||||
|
laPalace, laNone
|
||||||
|
);
|
||||||
|
else return laCrossroads;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fractal landscapes application
|
||||||
|
if(id == 33) {
|
||||||
|
if(old == laDragon) return pick(laTortoise, laTortoise, laCrossroads);
|
||||||
|
else if(isCrossroads(old))
|
||||||
|
return pick(laDragon, laReptile, laNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
return laNone;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void slidehelp() {
|
||||||
|
if(texts) {
|
||||||
|
help =
|
||||||
|
helptitle(slides[currentslide].name, 0xFF8000) +
|
||||||
|
slides[currentslide].help;
|
||||||
|
if(cmode != emHelp)
|
||||||
|
lastmode = cmode;
|
||||||
|
cmode = emHelp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handleKeyTour(int sym, int uni) {
|
||||||
|
if(sym == SDLK_RETURN && (cmode != emHelp || getid() == 10)) {
|
||||||
|
if(geometry) { restartGame(0, false); return true; }
|
||||||
|
if(getid() == 99) return true;
|
||||||
|
presentation(3);
|
||||||
|
currentslide++;
|
||||||
|
slidehelp();
|
||||||
|
presentation(1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(sym == SDLK_BACKSPACE) {
|
||||||
|
if(geometry) { restartGame(0, false); return true; }
|
||||||
|
if(currentslide == 0) { slidehelp(); return true; }
|
||||||
|
presentation(3);
|
||||||
|
currentslide--;
|
||||||
|
presentation(1);
|
||||||
|
if(cmode == emHelp) slidehelp();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(sym == '1' || sym == '2' || sym == '3') {
|
||||||
|
if(geometry) {
|
||||||
|
restartGame(0, false); return true;
|
||||||
|
}
|
||||||
|
if(sym == '1') targetgeometry = gSphere;
|
||||||
|
if(sym == '2') targetgeometry = gEuclid;
|
||||||
|
firstland = euclidland = cwt.c->land;
|
||||||
|
restartGame(sym == '3' ? '7' : 'g', true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(sym == '4') {
|
||||||
|
items[itOrbTeleport] = 1;
|
||||||
|
canmove = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(sym == '5') {
|
||||||
|
presentation(4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(sym == '6') {
|
||||||
|
sickmode = !sickmode;
|
||||||
|
static ld spd;
|
||||||
|
if(sickmode == true) {
|
||||||
|
spd = vid.sspeed, vid.sspeed = 5;
|
||||||
|
addMessage("Static mode enabled.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vid.sspeed = spd;
|
||||||
|
addMessage("Static mode disabled.");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(sym == '7') {
|
||||||
|
texts = !texts;
|
||||||
|
if(texts) slidehelp();
|
||||||
|
else addMessage("Help texts disabled.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(sym == '8')
|
||||||
|
conformal::includeHistory = !conformal::includeHistory;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool quickfind(eLand l) {
|
||||||
|
int id = getid();
|
||||||
|
if(id == 26 && l == laCamelot) return true;
|
||||||
|
if(id == 28 && l == laTemple) return true;
|
||||||
|
if(id == 29 && l == laBurial && !items[itOrbSword]) return true;
|
||||||
|
if(id == 33 && l == laTortoise && !items[itBabyTortoise]) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
currentslide = 0;
|
||||||
|
vid.scale = 1;
|
||||||
|
vid.alpha = 1;
|
||||||
|
pmodel = mdDisk;
|
||||||
|
restartGame('T');
|
||||||
|
if(tour::on) {
|
||||||
|
presentation(1);
|
||||||
|
slidehelp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user