1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-25 01:20:37 +00:00

work in progress for 10.0

This commit is contained in:
Zeno Rogue 2017-07-04 15:38:33 +02:00
parent 13043dc417
commit 22c9217219
34 changed files with 2051 additions and 1290 deletions

View File

@ -83,6 +83,7 @@ bool wrongMode(char flags) {
if(shmup::on != (flags == 's')) return true; if(shmup::on != (flags == 's')) return true;
if(randomPatternsMode) return true; if(randomPatternsMode) return true;
if(yendor::on) return true; if(yendor::on) return true;
if(peace::on) return true;
if(tactic::on) return true; if(tactic::on) return true;
#ifdef TOUR #ifdef TOUR
if(tour::on) return true; if(tour::on) return true;
@ -94,7 +95,7 @@ bool wrongMode(char flags) {
void achievement_log(const char* s, char flags) { void achievement_log(const char* s, char flags) {
#ifdef LOCAL #ifdef PRINT_ACHIEVEMENTS
printf("achievement = %s [%d]\n", s, wrongMode(flags)); printf("achievement = %s [%d]\n", s, wrongMode(flags));
#endif #endif
@ -124,7 +125,7 @@ void achievement_log(const char* s, char flags) {
#ifdef STEAM #ifdef STEAM
void improveItemScores(); void improveItemScores();
#include "hypersteam.cpp" #include "private/hypersteam.cpp"
#else #else
#ifndef ANDROID #ifndef ANDROID
#ifndef IOS #ifndef IOS
@ -525,6 +526,17 @@ void achievement_final(bool really_final) {
if(tour::on) return; if(tour::on) return;
#endif #endif
if(randomPatternsMode) return;
if(peace::on) return;
if(yendor::on) return;
if(tactic::on) {
tactic::record();
tactic::unrecord();
tactic::uploadScore();
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)
return; return;
@ -534,16 +546,7 @@ void achievement_final(bool really_final) {
if(euclid) return; if(euclid) return;
if(sphere) return; if(sphere) return;
if(elliptic) return; if(elliptic) return;
if(randomPatternsMode) return;
if(tactic::on) {
tactic::record();
tactic::unrecord();
tactic::uploadScore();
return;
}
if(yendor::on) return;
// no leaderboards for two special modes at once // no leaderboards for two special modes at once
int specials = 0; int specials = 0;
@ -610,6 +613,7 @@ void achievement_victory(bool hyper) {
if(randomPatternsMode) return; if(randomPatternsMode) return;
if(hyper && shmup::on) return; if(hyper && shmup::on) return;
if(yendor::on) return; if(yendor::on) return;
if(peace::on) return;
if(tactic::on) return; if(tactic::on) return;
if(chaosmode) return; if(chaosmode) return;
DEBB(DF_STEAM, (debugfile,"after checks\n")) DEBB(DF_STEAM, (debugfile,"after checks\n"))

View File

@ -72,20 +72,14 @@ struct celllister {
vector<int> tmps; vector<int> tmps;
vector<int> dists; vector<int> dists;
bool listed(cell *c) {
return c->aitmp >= 0 && c->aitmp < size(lst) && lst[c->aitmp] == c;
}
void add(cell *c, int d) { void add(cell *c, int d) {
if(listed(c)) return; if(eq(c->aitmp, sval)) return;
c->aitmp = size(lst); c->aitmp = sval;
tmps.push_back(c->aitmp); tmps.push_back(c->aitmp);
lst.push_back(c); lst.push_back(c);
dists.push_back(d); dists.push_back(d);
} }
int getdist(cell *c) { return dists[c->aitmp]; }
~celllister() { ~celllister() {
for(int i=0; i<size(lst); i++) lst[i]->aitmp = tmps[i]; for(int i=0; i<size(lst); i++) lst[i]->aitmp = tmps[i];
} }
@ -94,6 +88,7 @@ struct celllister {
lst.clear(); lst.clear();
tmps.clear(); tmps.clear();
dists.clear(); dists.clear();
sval++;
add(orig, 0); add(orig, 0);
cell *last = orig; cell *last = orig;
for(int i=0; i<size(lst); i++) { for(int i=0; i<size(lst); i++) {
@ -108,6 +103,17 @@ struct celllister {
} }
} }
} }
void prepare() {
for(int i=0; i<size(lst); i++) lst[i]->aitmp = i;
}
int getdist(cell *c) { return dists[c->aitmp]; }
bool listed(cell *c) {
return c->aitmp >= 0 && c->aitmp < size(lst) && lst[c->aitmp] == c;
}
}; };
// -- hrmap --- // -- hrmap ---

View File

@ -767,7 +767,7 @@ genderswitch_t genderswitch[NUM_GS] = {
// --- items --- // --- items ---
const int ittypes = 110; const int ittypes = 111;
struct itemtype { struct itemtype {
char glyph; char glyph;
@ -1152,6 +1152,7 @@ itemtype iinf[ittypes] = {
"You get the powers of Shield, Horns, and Thorns after you move two moves in a straight line " "You get the powers of Shield, Horns, and Thorns after you move two moves in a straight line "
"with this Orb." }, "with this Orb." },
{ '$', 0xC060C0, "Spinel", bulldashdesc }, { '$', 0xC060C0, "Spinel", bulldashdesc },
{ 'o', 0xC0C0FF, "Orb of the Mirror", NODESCYET },
}; };
enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBone, itHell, itStatue, enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBone, itHell, itStatue,
@ -1181,22 +1182,15 @@ enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBo
itWindstone, itOrbEmpathy, itStrongWind, itBuggy, itBuggy2, itWindstone, itOrbEmpathy, itStrongWind, itBuggy, itBuggy2,
itRose, itCoral, itOrbBeauty, itOrb37, itOrbEnergy, itRose, itCoral, itOrbBeauty, itOrb37, itOrbEnergy,
itBabyTortoise, itOrbShell, itApple, itDragon, itOrbDomination, itBabyTortoise, itOrbShell, itApple, itDragon, itOrbDomination,
itOrbSword, itOrbSword, itKraken, itOrbSword2, itBarrow,
itKraken, itOrbSword2, itBarrow, itTrollEgg, itWarning, itOrbStone, itOrbNature, itTreat,
itTrollEgg, itWarning, itSlime, itAmethyst, itOrbRecall, itDodeca, itOrbDash, itGreenGrass, itOrbHorns,
itOrbStone, itOrbNature, itTreat, itOrbBull, itBull, itOrbMirror
itSlime, itAmethyst,
itOrbRecall, itDodeca,
itOrbDash,
itGreenGrass,
itOrbHorns,
itOrbBull,
itBull
}; };
// --- wall types --- // --- wall types ---
const int walltypes = 96; const int walltypes = 97;
struct walltype { struct walltype {
char glyph; char glyph;
@ -1375,6 +1369,7 @@ walltype winf[walltypes] = {
"Bushes block the movement of birds."}, "Bushes block the movement of birds."},
{ '.', 0xFFFF00, "Reptile floor", reptiledesc}, { '.', 0xFFFF00, "Reptile floor", reptiledesc},
{ '.', 0xFFFF00, "Reptile bridge", reptiledesc}, { '.', 0xFFFF00, "Reptile bridge", reptiledesc},
{ '.', 0xFFFF00, "invisible floor", NODESCYET},
}; };
enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCavefloor, waDeadTroll, waDune, enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCavefloor, waDeadTroll, waDune,
@ -1402,7 +1397,8 @@ enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCav
waBarrowWall, waBarrowDig, waBarrowWall, waBarrowDig,
waPetrified, waTower, waPetrified, waTower,
waBigBush, waSmallBush, waBigBush, waSmallBush,
waReptile, waReptileBridge waReptile, waReptileBridge,
waInvisibleFloor
}; };
// --- land types --- // --- land types ---
@ -1782,3 +1778,24 @@ eLand randlands[RANDLANDS] = {
laOvergrown, laWildWest, laWarpCoast laOvergrown, laWildWest, laWarpCoast
}; };
// land completion for shared unlocking
#define U5 (inv::on ? 10 : 5)
// land completion for advanced unlocking
#define U10 (inv::on ? 25 : 10)
// land completion
#define R10 (inv::on ? 50 : 10)
// intermediate lands
#define R30 (inv::on ? 100 : 30)
// advanced lands
#define R60 (inv::on ? 200 : 60)
// advanced lands II
#define R90 (inv::on ? 300 : 90)
// Crossroads IV
#define R200 (inv::on ? 800 : 200)
// Crossroads V
#define R300 (inv::on ? 1200 : 300)
// kill types for Dragon Chasms
#define R20 (inv::on ? 30 : 20)
// kill count for Graveyard/Hive
#define R100 (inv::on ? 500 : 100)

View File

@ -1853,7 +1853,7 @@ void livecaves() {
if(c->mov[j]->wall == waThumperOn) c->aitmp+=100; if(c->mov[j]->wall == waThumperOn) c->aitmp+=100;
if(c->mov[j]->wall == waFire) c->aitmp+=100; if(c->mov[j]->wall == waFire) c->aitmp+=100;
if(c->mov[j]->wall == waBigStatue) c->aitmp-=100; if(c->mov[j]->wall == waBigStatue) c->aitmp-=100;
if(c->mov[j]->item) c->aitmp+=2; if(c->mov[j]->item && !peace::on) c->aitmp+=2;
if(c->mov[j]->monst == moZombie) c->aitmp += 10; if(c->mov[j]->monst == moZombie) c->aitmp += 10;
if(c->mov[j]->monst == moGhost) c->aitmp += 10; if(c->mov[j]->monst == moGhost) c->aitmp += 10;
if(c->mov[j]->monst == moTentacleGhost) c->aitmp += 10; if(c->mov[j]->monst == moTentacleGhost) c->aitmp += 10;
@ -2024,7 +2024,7 @@ namespace tortoise {
void updateVals(int delta) { void updateVals(int delta) {
int currbits = getBits(cwt.c); int currbits = getBits(cwt.c);
for(int i=0; i<numbits; i++) for(int i=0; i<numbits; i++)
update(seekval[i], seek() ? getBit(seekbits, i) : .5, delta); update(seekval[i], seek() && !(peace::on && !peace::hint) ? getBit(seekbits, i) : .5, delta);
for(int i=0; i<numbits; i++) for(int i=0; i<numbits; i++)
update(currval[i], getBit(currbits, i), delta); update(currval[i], getBit(currbits, i), delta);
} }

View File

@ -190,8 +190,8 @@ namespace spiral {
if(dosave) { dosave = false; IMAGESAVE(s, buf); } if(dosave) { dosave = false; IMAGESAVE(s, buf); }
SDL_UnlockSurface(s); SDL_UnlockSurface(s);
if(displayhelp) { if(displayhelp) {
displaystr(SX/2, vid.fsize*2, 0, vid.fsize, "arrows = navigate, ESC = return, h = hide help", 0xFFFFFF, 8); displaystr(SX/2, vid.fsize*2, 0, vid.fsize, "arrows = navigate, ESC = return, h = hide help", forecolor, 8);
displaystr(SX/2, SY - vid.fsize*2, 0, vid.fsize, XLAT("s = save to " IMAGEEXT, buf), 0xFFFFFF, 8); displaystr(SX/2, SY - vid.fsize*2, 0, vid.fsize, XLAT("s = save to " IMAGEEXT, buf), forecolor, 8);
} }
SDL_UpdateRect(s, 0, 0, 0, 0); SDL_UpdateRect(s, 0, 0, 0, 0);
shiftx += velx; shifty += vely; shiftx += velx; shifty += vely;

View File

@ -86,7 +86,6 @@ namespace dialog {
it.color = 0xC0C0C0; it.color = 0xC0C0C0;
it.colork = 0x808080; it.colork = 0x808080;
it.colorv = 0x80A040; it.colorv = 0x80A040;
it.colors = 0xFFD500;
it.colorc = 0xFFD500; it.colorc = 0xFFD500;
it.colors = 0xFF8000; it.colors = 0xFF8000;
if(value == ONOFF(true)) it.colorv = 0x40FF40; if(value == ONOFF(true)) it.colorv = 0x40FF40;
@ -148,11 +147,12 @@ namespace dialog {
items.push_back(it); items.push_back(it);
} }
void addBreak(int val) { int addBreak(int val) {
item it; item it;
it.type = diBreak; it.type = diBreak;
it.scale = val; it.scale = val;
items.push_back(it); items.push_back(it);
return items.size()-1;
} }
void addTitle(string body, int color, int scale) { void addTitle(string body, int color, int scale) {
@ -285,6 +285,7 @@ namespace dialog {
int top = tothei; int top = tothei;
tothei += dfspace * I.scale / 100; tothei += dfspace * I.scale / 100;
int mid = (top + tothei) / 2; int mid = (top + tothei) / 2;
I.position = mid;
if(I.type == diTitle || I.type == diInfo) { if(I.type == diTitle || I.type == diInfo) {
displayfr(dcenter, mid, 2, dfsize * I.scale/100, I.body, I.color, 8); displayfr(dcenter, mid, 2, dfsize * I.scale/100, I.body, I.color, 8);
} }
@ -414,7 +415,7 @@ namespace dialog {
for(int i=0; i<4; i++) { for(int i=0; i<4; i++) {
int y = vid.yres / 2 + (2-i) * vid.fsize * 2; int y = vid.yres / 2 + (2-i) * vid.fsize * 2;
int col = ((i==colorp) && !mousing) ? 0xFFD500 : 0xFFFFFF; int col = ((i==colorp) && !mousing) ? 0xFFD500 : forecolor;
displayColorButton(vid.xres / 4, y, "(", 0, 16, 0, col); displayColorButton(vid.xres / 4, y, "(", 0, 16, 0, col);
string rgt = ") "; rgt += "ABGR" [i]; string rgt = ") "; rgt += "ABGR" [i];
@ -622,7 +623,10 @@ namespace dialog {
if(ne.editwhat == &geom3::middetail && geom3::highdetail > geom3::middetail) if(ne.editwhat == &geom3::middetail && geom3::highdetail > geom3::middetail)
geom3::highdetail = geom3::middetail; geom3::highdetail = geom3::middetail;
if(lastmode == em3D) buildpolys(), resetGL(); if(lastmode == em3D) buildpolys();
#ifdef GL
if(lastmode == em3D) resetGL();
#endif
} }
void drawNumberDialog() { void drawNumberDialog() {
@ -663,6 +667,9 @@ namespace dialog {
if(ne.editwhat == &ne.intbuf && ne.intval == &sightrange && cheater) if(ne.editwhat == &ne.intbuf && ne.intval == &sightrange && cheater)
addBoolItem("overgenerate", overgenerate, 'o'); addBoolItem("overgenerate", overgenerate, 'o');
if(ne.editwhat == &vid.linewidth)
addBoolItem("finer lines at the boundary", vid.antialias & AA_LINEWIDTH, 'o');
display(); display();
} }
@ -710,6 +717,8 @@ namespace dialog {
} }
else if(uni == 'o' && ne.editwhat == &ne.intbuf && ne.intval == &sightrange && cheater) else if(uni == 'o' && ne.editwhat == &ne.intbuf && ne.intval == &sightrange && cheater)
overgenerate = !overgenerate; overgenerate = !overgenerate;
else if(uni == 'o' && ne.editwhat == &vid.linewidth)
vid.antialias ^= AA_LINEWIDTH;
else if(uni == 'p' && ne.editwhat == &vid.alpha) { else if(uni == 'p' && ne.editwhat == &vid.alpha) {
*ne.editwhat = 1; vid.scale = 1; ne.s = "1"; *ne.editwhat = 1; vid.scale = 1; ne.s = "1";
} }

View File

@ -213,7 +213,7 @@ int main(int argc, char **argv) {
items[itGreenStone] = 100; items[itGreenStone] = 100;
} }
action = sym; */ action = sym; */
extra ex; eventtype ex;
mousing = false; mousing = false;
handlekey(sym, sym, ex); handlekey(sym, sym, ex);
} }

View File

@ -314,7 +314,7 @@ bool isWall(cell *w) {
w->wall == waLadder || w->wall == waTrunk || w->wall == waSolidBranch || w->wall == waLadder || w->wall == waTrunk || w->wall == waSolidBranch ||
w->wall == waWeakBranch || w->wall == waCanopy || w->wall == waTower || w->wall == waWeakBranch || w->wall == waCanopy || w->wall == waTower ||
w->wall == waSmallBush || w->wall == waBigBush || w->wall == waSmallBush || w->wall == waBigBush ||
w->wall == waReptile || w->wall == waReptileBridge) w->wall == waReptile || w->wall == waReptileBridge || w->wall == waInvisibleFloor)
return false; return false;
if(isWatery(w) || isChasmy(w) || isFire(w)) return false; if(isWatery(w) || isChasmy(w) || isFire(w)) return false;
return true; return true;
@ -641,7 +641,7 @@ bool highwall(cell *c) {
} }
int chasmgraph(cell *c) { int chasmgraph(cell *c) {
if(c->wall == waChasm) return 2; if(c->wall == waChasm || c->wall == waInvisibleFloor) return 2;
if(isChasmy(c)) return 1; if(isChasmy(c)) return 1;
if(isWateryOrBoat(c)) return 1; if(isWateryOrBoat(c)) return 1;
if(wmescher && c->wall == waBarrier && c->land == laOceanWall) return 1; if(wmescher && c->wall == waBarrier && c->land == laOceanWall) return 1;

123
game.cpp
View File

@ -687,7 +687,7 @@ bool sharkpassable(cell *w, cell *c) {
bool canPushStatueOn(cell *c) { bool canPushStatueOn(cell *c) {
return passable(c, NULL, P_MONSTER) && c->wall != waBoat && !snakelevel(c) && return passable(c, NULL, P_MONSTER) && c->wall != waBoat && !snakelevel(c) &&
!isWorm(c->monst) && !isReptile(c->wall); !isWorm(c->monst) && !isReptile(c->wall) && !peace::on;
} }
void moveBoat(cell *to, cell *from) { void moveBoat(cell *to, cell *from) {
@ -844,6 +844,8 @@ bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags) {
if(!m2) return false; if(!m2) return false;
if(m2 == moPlayer && peace::on) return false;
if((flags & AF_ONLY_FRIEND) && m2 != moPlayer && !isFriendly(c2)) return false; if((flags & AF_ONLY_FRIEND) && m2 != moPlayer && !isFriendly(c2)) return false;
if((flags & AF_ONLY_FBUG) && m2 != moPlayer && !isFriendlyOrBug(c2)) return false; if((flags & AF_ONLY_FBUG) && m2 != moPlayer && !isFriendlyOrBug(c2)) return false;
if((flags & AF_ONLY_ENEMY) && (m2 == moPlayer || isFriendlyOrBug(c2))) return false; if((flags & AF_ONLY_ENEMY) && (m2 == moPlayer || isFriendlyOrBug(c2))) return false;
@ -1215,6 +1217,8 @@ int monstersnear2() {
int monstersnear(cell *c, cell *nocount, eMonster who, cell *pushto, cell *comefrom) { int monstersnear(cell *c, cell *nocount, eMonster who, cell *pushto, cell *comefrom) {
if(peace::on) return 0; // you are safe
stalemate1 sm(who, c, nocount, pushto, comefrom); stalemate1 sm(who, c, nocount, pushto, comefrom);
if(who == moPlayer) for(int b=0; b<2; b++) sm.swordlast[b] = sword::pos(multi::cpid, b); if(who == moPlayer) for(int b=0; b<2; b++) sm.swordlast[b] = sword::pos(multi::cpid, b);
@ -2055,7 +2059,7 @@ void fightmessage(eMonster victim, eMonster attacker, bool stun, int flags) {
else else
addMessage(XLAT("You pierce %the1.", victim)); // normal addMessage(XLAT("You pierce %the1.", victim)); // normal
} }
else { else if(!peace::on) {
playSound(NULL, "hit-sword"+pick123()); playSound(NULL, "hit-sword"+pick123());
addMessage(XLAT("You kill %the1.", victim)); // normal addMessage(XLAT("You kill %the1.", victim)); // normal
} }
@ -2133,6 +2137,8 @@ bool attackMonster(cell *c, flagtype flags, eMonster killer) {
else else
killMonster(c, killer, flags); killMonster(c, killer, flags);
if(peace::on) return false;
int ntk = tkills(); int ntk = tkills();
int ntkt = killtypes(); int ntkt = killtypes();
@ -2318,6 +2324,8 @@ void calcTidalPhase() {
tidalphase = tide[ tidalphase = tide[
(shmup::on ? shmup::curtime/600 : turncount) (shmup::on ? shmup::curtime/600 : turncount)
% tidalsize]; % tidalsize];
if(peace::on)
tidalphase = 5 + tidalphase / 6;
} }
int tidespeed() { int tidespeed() {
@ -2587,7 +2595,7 @@ void bfs() {
c2->cpdist = d+1; c2->cpdist = d+1;
// remove treasures // remove treasures
if(c2->item && c2->cpdist == distlimit && itemclass(c2->item) == IC_TREASURE && if(!peace::on && c2->item && c2->cpdist == distlimit && itemclass(c2->item) == IC_TREASURE &&
c2->item != itBabyTortoise && c2->item != itBabyTortoise &&
(items[c2->item] >= (chaosmode?10:20) + currentLocalTreasure || getGhostcount() >= 2)) { (items[c2->item] >= (chaosmode?10:20) + currentLocalTreasure || getGhostcount() >= 2)) {
c2->item = itNone; c2->item = itNone;
@ -2916,6 +2924,8 @@ void gainShard(cell *c2, const char *msg) {
void playerMoveEffects(cell *c1, cell *c2) { void playerMoveEffects(cell *c1, cell *c2) {
if(peace::on) items[itOrbSword] = c2->land == laBurial ? 100 : 0;
sword::angle[multi::cpid] = sword::shift(c1, c2, sword::angle[multi::cpid]); sword::angle[multi::cpid] = sword::shift(c1, c2, sword::angle[multi::cpid]);
destroyWeakBranch(c1, c2, moPlayer); destroyWeakBranch(c1, c2, moPlayer);
@ -3276,7 +3286,7 @@ int moveval(cell *c1, cell *c2, int d, int mf) {
else if(isFriendlyOrBug(c2)) return 500; else if(isFriendlyOrBug(c2)) return 500;
else return 2000; else return 2000;
} }
if(isPlayerOn(c2)) return 2500; if(isPlayerOn(c2)) return peace::on ? -1700 : 2500;
else if(isFriendlyOrBug(c2)) return 2000; else if(isFriendlyOrBug(c2)) return 2000;
else return 500; else return 500;
} }
@ -3338,7 +3348,7 @@ int moveval(cell *c1, cell *c2, int d, int mf) {
if(m == moRagingBull && c1->mondir != NODIR) if(m == moRagingBull && c1->mondir != NODIR)
return 1500 - bulldist(c2); return 1500 - bulldist(c2);
if((mf & MF_PATHDIST) && c2->pathdist < c1->pathdist) return 1500; // good move if((mf & MF_PATHDIST) && c2->pathdist < c1->pathdist && !peace::on) return 1500; // good move
// prefer straight direction when wandering // prefer straight direction when wandering
int dd = angledist(c1, c1->mondir, d); int dd = angledist(c1, c1->mondir, d);
@ -3369,6 +3379,8 @@ int stayval(cell *c, flagtype mf) {
// Vikings move in a roughly straight line even if they cannot detect you // Vikings move in a roughly straight line even if they cannot detect you
if(c->monst == moViking && c->wall == waBoat) if(c->monst == moViking && c->wall == waBoat)
return 750; return 750;
// in peaceful, all monsters are wandering
if(peace::on && c->monst != moTortoise) return 750;
if(isWorm(c->monst)) return 550; if(isWorm(c->monst)) return 550;
if(c->monst == moRagingBull) return -1690; // worse than to stay in place if(c->monst == moRagingBull) return -1690; // worse than to stay in place
if(c->monst == moBat && batsAfraid(c)) return 575; if(c->monst == moBat && batsAfraid(c)) return 575;
@ -4033,7 +4045,7 @@ void groupmove(eMonster movtype, flagtype mf) {
} }
} }
else { else {
for(int i=0; i<size(targets); i++) gendfs.push_back(targets[i]); if(!peace::on) for(int i=0; i<size(targets); i++) gendfs.push_back(targets[i]);
if(invisfish && (movtype == moSlime || movtype == moShark || movtype == moKrakenH)) for(int i=0; i<numplayers(); i++) { if(invisfish && (movtype == moSlime || movtype == moShark || movtype == moKrakenH)) for(int i=0; i<numplayers(); i++) {
cell *c = playerpos(i); cell *c = playerpos(i);
@ -4387,6 +4399,7 @@ void swordAttackStatic() {
} }
void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) { void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) {
if(peace::on) return;
int numsh = 0, numflail = 0, numlance = 0, numslash = 0; int numsh = 0, numflail = 0, numlance = 0, numslash = 0;
int backdir = neighborId(mt, mf); int backdir = neighborId(mt, mf);
@ -4727,7 +4740,7 @@ void specialMoves() {
eMonster m = c->monst; eMonster m = c->monst;
if(m == moSleepBull) { if(m == moSleepBull && !peace::on) {
bool wakeup = false; bool wakeup = false;
forCellEx(c2, c) if(c2->monst == moGadfly) { forCellEx(c2, c) if(c2->monst == moGadfly) {
addMessage(XLAT("%The1 wakes up %the2.", c2->monst, m)); addMessage(XLAT("%The1 wakes up %the2.", c2->monst, m));
@ -4957,6 +4970,17 @@ void moverefresh(bool turn = true) {
c->monst = moReptile; c->monst = moReptile;
c->hitpoints = 3; c->hitpoints = 3;
c->stuntime = 0; c->stuntime = 0;
int gooddirs[7], qdirs = 0;
// in the peace mode, a reptile will
// prefer to walk on the ground, rather than the chasm
for(int i=0; i<c->type; i++) {
int i0 = (i+3) % c->type;
int i1 = (i+c->type-3) % c->type;
if(c->mov[i0] && passable(c->mov[i0], c, 0))
if(c->mov[i1] && passable(c->mov[i1], c, 0))
gooddirs[qdirs++] = i;
}
if(qdirs) c->mondir = gooddirs[hrand(qdirs)];
playSound(c, "click"); playSound(c, "click");
} }
} }
@ -5522,6 +5546,7 @@ void collectMessage(cell *c2, eItem which) {
bool specialmode = bool specialmode =
yendor::on || tactic::on || princess::challenge || euclid || sphere; yendor::on || tactic::on || princess::challenge || euclid || sphere;
if(which == itDodeca && peace::on) return;
if(which == itTreat) ; if(which == itTreat) ;
else if(isElementalShard(which)) { else if(isElementalShard(which)) {
int tsh = int tsh =
@ -5536,8 +5561,9 @@ void collectMessage(cell *c2, eItem which) {
addMessage(t); addMessage(t);
} }
} }
else if(which == itKey) else if(which == itKey) {
addMessage(XLAT("You have found the Key! Now unlock this Orb of Yendor!")); addMessage(XLAT("You have found the Key! Now unlock this Orb of Yendor!"));
}
else if(which == itGreenStone && !items[itGreenStone]) else if(which == itGreenStone && !items[itGreenStone])
addMessage(XLAT("This orb is dead...")); addMessage(XLAT("This orb is dead..."));
else if(which == itGreenStone) else if(which == itGreenStone)
@ -5632,6 +5658,7 @@ bool collectItem(cell *c2, bool telekinesis) {
princess::forceVizier = true; princess::forceVizier = true;
if(!cantGetGrimoire(c2, false)) collectMessage(c2, c2->item); if(!cantGetGrimoire(c2, false)) collectMessage(c2, c2->item);
if(c2->item == itDodeca) peace::simon::extend();
} }
if(isRevivalOrb(c2->item) && multi::revive_queue.size()) { if(isRevivalOrb(c2->item) && multi::revive_queue.size()) {
@ -5861,47 +5888,21 @@ bool collectItem(cell *c2, bool telekinesis) {
playSound(c2, "pickup-orb"); playSound(c2, "pickup-orb");
items[c2->item] += 78; items[c2->item] += 78;
} }
else if(c2->item == itOrbYendor && peace::on) {
if(!items[itDodeca]) {
addMessage(XLAT("Collect as many Dodecahedra as you can, then return here!"));
}
else {
addMessage(XLAT("Your score: %1", its(items[itDodeca])));
peace::simon::restore();
}
dopickup = false;
}
else if(c2->item == itOrbYendor && yendor::state(c2) != yendor::ysUnlocked) { else if(c2->item == itOrbYendor && yendor::state(c2) != yendor::ysUnlocked) {
dopickup = false; dopickup = false;
} }
else if(c2->item == itOrbYendor) { else if(c2->item == itOrbYendor)
playSound(c2, "tada"); yendor::collected(c2);
items[itOrbShield] += 31;
for(int i=0; i<size(yendor::yi); i++)
if(yendor::yi[i].path[0] == c2)
yendor::yi[i].foundOrb = true;
// Shielding always, so that we know that it protects!
for(int i=0; i<4; i++) switch(hrand(13)) {
case 0: items[itOrbSpeed] += 31; break;
case 1: items[itOrbLightning] += 78; break;
case 2: items[itOrbFlash] += 78; break;
case 3: items[itOrbTime] += 78; break;
case 4: items[itOrbWinter] += 151; break;
case 5: items[itOrbDigging] += 151; break;
case 6: items[itOrbTeleport] += 151; break;
case 7: items[itOrbThorns] += 151; break;
case 8: items[itOrbInvis] += 151; break;
case 9: items[itOrbPsi] += 151; break;
case 10: items[itOrbAether] += 151; break;
case 11: items[itOrbFire] += 151; break;
case 12: items[itOrbSpace] += 78; break;
}
items[itOrbYendor]++;
items[itKey]--;
yendor::everwon = true;
if(yendor::on) {
yendor::won = true;
if(!cheater) {
dynamicval<bool> c(chaosmode, false);
yendor::bestscore[modecode()][yendor::challenge] =
max(yendor::bestscore[modecode()][yendor::challenge], items[itOrbYendor]);
yendor::uploadScore();
}
}
addMessage(XLAT("CONGRATULATIONS!"));
achievement_collection(itOrbYendor, pg, gold());
achievement_victory(false);
}
else if(c2->item == itHolyGrail) { else if(c2->item == itHolyGrail) {
playSound(c2, "tada"); playSound(c2, "tada");
int v = newRoundTableRadius() + 12; int v = newRoundTableRadius() + 12;
@ -5993,7 +5994,7 @@ bool collectItem(cell *c2, bool telekinesis) {
if(pg < 75 && g2 >= 75) if(pg < 75 && g2 >= 75)
addMessage(XLAT("Kill monsters and collect treasures, and you may get access to Hell...")); addMessage(XLAT("Kill monsters and collect treasures, and you may get access to Hell..."));
if(pg < 90 && g2 >= 90) if(pg < 90 && g2 >= 90)
addMessage(XLAT("To access Hell, collect 10 treasures each of 9 kinds...")); addMessage(XLAT("To access Hell, collect %1 treasures each of 9 kinds...", its(R10)));
if(hellUnlocked() && !lhu) { if(hellUnlocked() && !lhu) {
addMessage(XLAT("Abandon all hope, the gates of Hell are opened!")); addMessage(XLAT("Abandon all hope, the gates of Hell are opened!"));
addMessage(XLAT("And the Orbs of Yendor await!")); addMessage(XLAT("And the Orbs of Yendor await!"));
@ -6467,6 +6468,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
if(d >= 0) { if(d >= 0) {
cell *c2 = cwt.c->mov[d]; cell *c2 = cwt.c->mov[d];
bool goodTortoise = c2->monst == moTortoise && tortoise::seek() && !tortoise::diff(tortoise::getb(c2)) && !c2->item;
if(againstRose(cwt.c, c2) && !scentResistant()) { if(againstRose(cwt.c, c2) && !scentResistant()) {
if(checkonly) return false; if(checkonly) return false;
@ -6652,7 +6654,8 @@ bool movepcto(int d, int subdir, bool checkonly) {
knightFlavorMessage(c2); knightFlavorMessage(c2);
return false; return false;
} }
else if(c2->monst && (!isFriendly(c2) || c2->monst == moTameBomberbird || isMountable(c2->monst))) { else if(c2->monst && (!isFriendly(c2) || c2->monst == moTameBomberbird || isMountable(c2->monst))
&& !(peace::on && !isMultitile(c2->monst) && !goodTortoise)) {
bool fast = !((!items[itOrbSpeed]) || (items[itOrbSpeed]&1)); bool fast = !((!items[itOrbSpeed]) || (items[itOrbSpeed]&1));
@ -6731,7 +6734,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
!c2->item); !c2->item);
} */ } */
if(c2->monst == moTortoise && tortoise::seek() && !tortoise::diff(tortoise::getb(c2)) && !c2->item) { if(goodTortoise) {
items[itBabyTortoise] += 4; items[itBabyTortoise] += 4;
updateHi(itBabyTortoise, items[itBabyTortoise]); updateHi(itBabyTortoise, items[itBabyTortoise]);
c2->item = itBabyTortoise; c2->item = itBabyTortoise;
@ -6792,7 +6795,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
addMessage("Are you sure you want to step there?"); addMessage("Are you sure you want to step there?");
return false; return false;
} }
if(c2->item == itOrbYendor && !boatmove && !checkonly && yendor::check(c2)) { if(c2->item == itOrbYendor && !boatmove && !checkonly && !peace::on && yendor::check(c2)) {
return false; return false;
} }
if(monstersnear(c2, NULL, moPlayer, NULL, cwt.c)) { if(monstersnear(c2, NULL, moPlayer, NULL, cwt.c)) {
@ -6888,8 +6891,20 @@ bool movepcto(int d, int subdir, bool checkonly) {
movecost(cwt.c, c2); movecost(cwt.c, c2);
if(c2->monst == moGolem || c2->monst == moIllusion || isPrincess(c2->monst) || c2->monst == moMouse || {
c2->monst == moFriendlyGhost) { bool pushpast = false;
pushpast =
c2->monst == moGolem || c2->monst == moIllusion || isPrincess(c2->monst) || c2->monst == moMouse ||
c2->monst == moFriendlyGhost;
if(peace::on) pushpast |= c2->monst && !isMultitile(c2->monst);
if(isMimic(c2->monst)) {
addMessage(XLAT("You rejoin %the1.", c2->monst));
playSound(c2, "click");
killMonster(c2, moNone);
}
else if(pushpast) {
bool pswitch = false; bool pswitch = false;
if(c2->monst == moMouse) if(c2->monst == moMouse)
princess::mouseSqueak(c2); princess::mouseSqueak(c2);
@ -6907,10 +6922,6 @@ bool movepcto(int d, int subdir, bool checkonly) {
c2->monst = moNone; c2->monst = moNone;
switchplaces = true; switchplaces = true;
} }
else if(isMimic(c2->monst)) {
addMessage(XLAT("You rejoin %the1.", c2->monst));
playSound(c2, "click");
killMonster(c2, moNone);
} }
mountjump: mountjump:

651
graph.cpp

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,8 @@ void tsetspin(uint32_t& t, int d, int spin) {
struct heptagon { struct heptagon {
// automaton state // automaton state
hstate s : 8; hstate s : 6;
int dm4: 2;
// we are spin[i]-th neighbor of move[i] // we are spin[i]-th neighbor of move[i]
uint32_t spintable; uint32_t spintable;
int spin(int d) { return tspin(spintable, d); } int spin(int d) { return tspin(spintable, d); }
@ -126,6 +127,7 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0) {
//generateEmeraldval(parent); //generateEmeraldval(parent);
//generateEmeraldval(h); //generateEmeraldval(h);
if(pard == 0) { if(pard == 0) {
h->dm4 = parent->dm4+1;
if(purehepta) h->distance = parent->distance + 1; if(purehepta) h->distance = parent->distance + 1;
else if(parent->s == hsOrigin) h->distance = 2; else if(parent->s == hsOrigin) h->distance = 2;
else if(h->spin(0) == 5) else if(h->spin(0) == 5)
@ -134,7 +136,10 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0) {
h->distance = createStep(h->move[0], (h->spin(0)+2)%7)->distance + 3; h->distance = createStep(h->move[0], (h->spin(0)+2)%7)->distance + 3;
else h->distance = parent->distance + 2; else h->distance = parent->distance + 2;
} }
else h->distance = parent->distance - (purehepta?1:2); else {
h->distance = parent->distance - (purehepta?1:2);
h->dm4 = parent->dm4-1;
}
return h; return h;
} }

View File

@ -119,6 +119,12 @@ int arg::readCommon() {
else if(argis("-back")) { else if(argis("-back")) {
shift(); backcolor = strtol(args(), NULL, 16); shift(); backcolor = strtol(args(), NULL, 16);
} }
else if(argis("-borders")) {
shift(); bordcolor = strtol(args(), NULL, 16);
}
else if(argis("-fore")) {
shift(); forecolor = strtol(args(), NULL, 16);
}
else if(argis("-W2")) { else if(argis("-W2")) {
shift(); cheatdest = readland(args()); autocheat = true; shift(); cheatdest = readland(args()); autocheat = true;
} }
@ -168,6 +174,8 @@ int arg::readCommon() {
exit(0); exit(0);
} }
else if(argis("-aa")) { PHASEFROM(2); shift(); vid.antialias = argi(); }
else if(argis("-lw")) { PHASEFROM(2); shift(); vid.linewidth = argf(); }
else if(argis("-wm")) { PHASEFROM(2); vid.wallmode = argi(); } else if(argis("-wm")) { PHASEFROM(2); vid.wallmode = argi(); }
else if(argis("-mm")) { PHASEFROM(2); vid.monmode = argi(); } else if(argis("-mm")) { PHASEFROM(2); vid.monmode = argi(); }
@ -379,7 +387,11 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { if(curphase ==
return 0; return 0;
} }
#ifndef NOMAIN
int main(int argc, char **argv) { int main(int argc, char **argv) {
#ifdef EXTRA_MAIN
if(extra::main(argc, argv)) return 0;
#endif
#ifndef WEB #ifndef WEB
#ifdef LINUX #ifdef LINUX
moreStack(); moreStack();
@ -394,6 +406,7 @@ int main(int argc, char **argv) {
profile_info(); profile_info();
return 0; return 0;
} }
#endif
#ifdef USE_COMMANDLINE #ifdef USE_COMMANDLINE
namespace arg { namespace arg {
@ -401,11 +414,14 @@ namespace arg {
void read(int phase) { void read(int phase) {
curphase = phase; curphase = phase;
#ifdef EXTRA_CONFIG
extra::config();
#endif
while(argc) { while(argc) {
int r; int r;
r = readCommon(); if(r == 2) return; if(r == 0) { lshift(); continue; } r = readCommon(); if(r == 2) return; if(r == 0) { lshift(); continue; }
#ifdef LOCAL #ifdef EXTRA_ARG
r = readLocal(); if(r == 2) return; if(r == 0) { lshift(); continue; } r = extra::arg(); if(r == 2) return; if(r == 0) { lshift(); continue; }
#endif #endif
#ifdef ROGUEVIZ #ifdef ROGUEVIZ
r = rogueviz::readArgs(); if(r == 2) return; if(r == 0) { lshift(); continue; } r = rogueviz::readArgs(); if(r == 2) return; if(r == 0) { lshift(); continue; }

64
hyper.h
View File

@ -251,6 +251,7 @@ int darkened(int c);
extern int getcstat; extern int getcstat;
bool displaychr(int x, int y, int shift, int size, char chr, int col); bool displaychr(int x, int y, int shift, int size, char chr, int col);
bool displayfr(int x, int y, int b, int size, const string &s, int color, int align); bool displayfr(int x, int y, int b, int size, const string &s, int color, int align);
bool displayfrSP(int x, int y, int sh, int b, int size, const string &s, int color, int align, int p);
bool outofmap(hyperpoint h); bool outofmap(hyperpoint h);
void applymodel(hyperpoint H, hyperpoint& Hscr); void applymodel(hyperpoint H, hyperpoint& Hscr);
@ -262,6 +263,7 @@ void resetview(); extern heptspin viewctr; extern cell *centerover;
void drawthemap(); void drawthemap();
void drawfullmap(); void drawfullmap();
bool displaystr(int x, int y, int shift, int size, const char *str, int color, int align); bool displaystr(int x, int y, int shift, int size, const char *str, int color, int align);
bool displaystr(int x, int y, int shift, int size, const string& str, int color, int align);
extern int darken; extern int darken;
void calcparam(); void calcparam();
@ -322,7 +324,14 @@ struct videopar {
float scrdist; float scrdist;
bool usingGL; bool usingGL;
bool usingAA; int antialias;
#define AA_NOGL 1
#define AA_VERSION 2
#define AA_LINES 4
#define AA_POLY 8
#define AA_LINEWIDTH 16
#define AA_FONT 32
ld linewidth;
int joyvalue, joyvalue2, joypanthreshold; int joyvalue, joyvalue2, joypanthreshold;
ld joypanspeed; ld joypanspeed;
@ -344,7 +353,7 @@ extern videopar vid;
enum emtype {emNormal, emHelp, enum emtype {emNormal, emHelp,
emMenu, emMenu,
emVisual1, emVisual2, emBasicConfig, emGraphConfig, emDisplayMode,
emChangeMode, emCustomizeChar, emChangeMode, emCustomizeChar,
emQuit, emDraw, emScores, emPickEuclidean, emQuit, emDraw, emScores, emPickEuclidean,
emPickScores, emPickScores,
@ -360,7 +369,9 @@ enum emtype {emNormal, emHelp,
emJoyConfig, emJoyConfig,
emColor, emNumber, emColor, emNumber,
em3D, emRogueviz, em3D, emRogueviz,
emLinepattern emLinepattern,
emPeace, emInventory,
emSlideshows
}; };
extern emtype cmode, lastmode; extern emtype cmode, lastmode;
@ -704,6 +715,7 @@ template<class T> struct dynamicval {
T& where; T& where;
T backup; T backup;
dynamicval(T& wh, T val) : where(wh) { backup = wh; wh = val; } dynamicval(T& wh, T val) : where(wh) { backup = wh; wh = val; }
dynamicval(T& wh) : where(wh) { backup = wh; }
~dynamicval() { where = backup; } ~dynamicval() { where = backup; }
}; };
@ -790,6 +802,7 @@ namespace dialog {
int color, colorv, colork, colors, colorc; int color, colorv, colork, colors, colorc;
int scale; int scale;
double param; double param;
int position;
}; };
item& lastItem(); item& lastItem();
@ -801,7 +814,7 @@ namespace dialog {
void addHelp(string body); void addHelp(string body);
void addInfo(string body, int color = 0xC0C0C0); void addInfo(string body, int color = 0xC0C0C0);
void addItem(string body, int key); void addItem(string body, int key);
void addBreak(int val); int addBreak(int val);
void addTitle(string body, int color, int scale); void addTitle(string body, int color, int scale);
void init(); void init();
@ -947,6 +960,9 @@ void ShadowV(const transmatrix& V, const struct hpcshape& bp, int prio = PPR_MON
#define OUTLINE_OTHER 0xFFFFFFFF #define OUTLINE_OTHER 0xFFFFFFFF
#define OUTLINE_DEAD 0x800000FF #define OUTLINE_DEAD 0x800000FF
#define OUTLINE_TRANS 0 #define OUTLINE_TRANS 0
#define OUTLINE_DEFAULT ((bordcolor << 8) + 0xFF)
#define OUTLINE_FORE ((forecolor << 8) + 0xFF)
#define OUTLINE_BACK ((backcolor << 8) + 0xFF)
extern bool audio; extern bool audio;
extern string musiclicense; extern string musiclicense;
@ -1023,7 +1039,7 @@ extern cell *recallCell;
extern eLand cheatdest; extern eLand cheatdest;
void cheatMoveTo(eLand l); void cheatMoveTo(eLand l);
extern int backcolor; extern int backcolor, bordcolor, forecolor;
extern bool overgenerate; extern bool overgenerate;
void doOvergenerate(); void doOvergenerate();
@ -1131,6 +1147,7 @@ namespace tour {
extern bool on; extern bool on;
extern string tourhelp; extern string tourhelp;
extern string slidecommand; extern string slidecommand;
extern int currentslide;
bool handleKeyTour(int sym, int uni); bool handleKeyTour(int sym, int uni);
@ -1167,9 +1184,18 @@ namespace tour {
static const int LEGAL_NONEUC=4; static const int LEGAL_NONEUC=4;
static const int QUICKSKIP=8; static const int QUICKSKIP=8;
static const int FINALSLIDE=16; static const int FINALSLIDE=16;
static const int QUICKGEO=32;
static const int SIDESCREEN = 64;
extern slide slideHypersian; extern slide slideHypersian;
extern slide slideExpansion; extern slide slideExpansion;
namespace ss {
void showMenu();
void handleKey(int sym, int uni);
void list(slide*);
}
}; };
#endif #endif
@ -1184,10 +1210,8 @@ namespace rogueviz {
extern bool doCross; extern bool doCross;
void optimizeview(); void optimizeview();
#ifndef NOPNG
extern int pngres; extern int pngres;
extern int pngformat; extern int pngformat;
#endif
extern bool noGUI; extern bool noGUI;
extern bool dronemode; extern bool dronemode;
@ -1211,7 +1235,8 @@ namespace linepatterns {
patPower, patPower,
patNormal, patNormal,
patTrihepta, patTrihepta,
patBigTriangles patBigTriangles,
patBigRings
}; };
void clearAll(); void clearAll();
@ -1242,3 +1267,26 @@ void displaymm(char c, int x, int y, int rad, int size, const string& title, int
bool canPushThumperOn(cell *tgt, cell *thumper, cell *player); bool canPushThumperOn(cell *tgt, cell *thumper, cell *player);
void pushThumper(cell *th, cell *cto); void pushThumper(cell *th, cell *cto);
template<class T> T pick(T x, T y) { return hrand(2) ? x : y; }
template<class T> T pick(T x, T y, T z) { switch(hrand(3)) { case 0: return x; case 1: return y; case 2: return z; } return x; }
template<class T> T pick(T x, T y, T z, T v) { switch(hrand(4)) { case 0: return x; case 1: return y; case 2: return z; case 3: return v; } return x; }
eLand getNewSealand(eLand old);
bool createOnSea(eLand old);
namespace inv {
bool on;
}
bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks, bool hidden);
void initquickqueue();
void quickqueue();
int darkenedby(int c, int lev);
extern int mousex, mousey;
string generateHelpForItem(eItem it);
bool graphglyph();
extern bool hiliteclick;
extern int antialiaslines;
extern int ringcolor;

View File

@ -1,8 +1,8 @@
id ICON "hr-icon.ico" id ICON "hr-icon.ico"
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION 9,4,0,14 FILEVERSION 9,4,0,15
PRODUCTVERSION 9,4,0,14 PRODUCTVERSION 9,4,0,15
BEGIN BEGIN
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
BEGIN BEGIN
@ -10,12 +10,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Zeno Rogue" VALUE "CompanyName", "Zeno Rogue"
VALUE "FileDescription", "A roguelike in non-euclidean space" VALUE "FileDescription", "A roguelike in non-euclidean space"
VALUE "FileVersion", "94n" VALUE "FileVersion", "94n1"
VALUE "InternalName", "hyper" VALUE "InternalName", "hyper"
VALUE "LegalCopyright", "Zeno Rogue" VALUE "LegalCopyright", "Zeno Rogue"
VALUE "OriginalFilename", "hyper.exe" VALUE "OriginalFilename", "hyper.exe"
VALUE "ProductName", "HyperRogue" VALUE "ProductName", "HyperRogue"
VALUE "ProductVersion", "9.4n" VALUE "ProductVersion", "9.4n1"
END END
END END

View File

@ -1,6 +1,6 @@
#define VER "9.4n" #define VER "9.4n1"
#define VERNUM 9414 #define VERNUM 9415
#define VERNUM_HEX 0x9414 #define VERNUM_HEX 0x9415
#define GEN_M 0 #define GEN_M 0
#define GEN_F 1 #define GEN_F 1
@ -40,7 +40,9 @@
#define GFX #define GFX
#endif #endif
#ifndef NOGL
#define GL #define GL
#endif
#define PSEUDOKEY_WHEELDOWN 2501 #define PSEUDOKEY_WHEELDOWN 2501
#define PSEUDOKEY_WHEELUP 2502 #define PSEUDOKEY_WHEELUP 2502
@ -53,6 +55,8 @@
#define NOPNG #define NOPNG
#endif #endif
// #define INV
#ifndef MOBILE #ifndef MOBILE
#ifndef NOAUDIO #ifndef NOAUDIO
#define SDLAUDIO #define SDLAUDIO
@ -72,6 +76,10 @@ bool buttonclicked;
void gdpush(int t); void gdpush(int t);
#endif #endif
#ifndef HYPERPATH
#define HYPERPATH ""
#endif
#include <stdio.h> #include <stdio.h>
#ifdef NOSDL #ifdef NOSDL
@ -151,7 +159,11 @@ typedef int SDL_Event;
#ifdef GL #ifdef GL
#ifdef WINDOWS #ifdef MAC
#define AVOID_GLEW
#endif
#ifndef AVOID_GLEW
#include <GL/glew.h> #include <GL/glew.h>
#else #else
#define GL_GLEXT_PROTOTYPES 1 #define GL_GLEXT_PROTOTYPES 1
@ -251,6 +263,9 @@ const char *loadlevel = NULL;
#include "game.cpp" #include "game.cpp"
#include "landgen.cpp" #include "landgen.cpp"
#include "orbs.cpp" #include "orbs.cpp"
#ifdef INV
#include "inventory.cpp"
#endif
#include "system.cpp" #include "system.cpp"
#include "geometry.cpp" #include "geometry.cpp"
#include "polygons.cpp" #include "polygons.cpp"
@ -258,6 +273,9 @@ const char *loadlevel = NULL;
#ifndef MOBILE #ifndef MOBILE
#include "netgen.cpp" #include "netgen.cpp"
#endif #endif
#ifdef EXTRA
#include "extra/extra.cpp"
#endif
#include "graph.cpp" #include "graph.cpp"
#include "sound.cpp" #include "sound.cpp"
#include "achievement.cpp" #include "achievement.cpp"
@ -592,7 +610,7 @@ void mobile_draw(MOBPAR_FORMAL) {
displayTexts(); displayTexts();
#endif #endif
if((cmode != emVisual1 && cmode != emScores)) { if((cmode != emBasicConfig && cmode != emScores)) {
if(clicked && lclicked && andmode == 1 && !inmenu) { if(clicked && lclicked && andmode == 1 && !inmenu) {
if(!mouseout2() && mouseoh[2] < 50 && mouseh[2] < 50) { if(!mouseout2() && mouseoh[2] < 50 && mouseh[2] < 50) {
@ -646,3 +664,35 @@ void mobile_draw(MOBPAR_FORMAL) {
#ifdef NOAUDIO #ifdef NOAUDIO
void playSound(cell*, const string &s, int vol) { printf("play sound: %s vol %d\n", s.c_str(), vol); } void playSound(cell*, const string &s, int vol) { printf("play sound: %s vol %d\n", s.c_str(), vol); }
#endif #endif
// optional hooks
// you may include hyper.cpp from another file and define EXTRA_... to change some things
namespace extra {
// on drawing cells
void drawcell(cell *c, const transmatrix& V);
// on each frame
void frame();
// on stats drawing
void stats();
// return true if key is handled
bool handleKey(int sym, int uni);
// return true to exit immediately
bool main(int argc, char **argv);
// extra configuration, called together with reading arguments
void config();
// read command line arguments
int arg();
// change land distribution
eLand getNext(eLand old);
// change musics
bool changeMusic(eLand id);
}

View File

@ -379,7 +379,9 @@ void ksave(const char *fname) {
FILE *f = fopen(fname, "wt"); FILE *f = fopen(fname, "wt");
fprintf(f, "%d %d\n", cells, t); fprintf(f, "%d %d\n", cells, t);
for(neuron& n: net) { for(neuron& n: net) {
for(int k=0; k<cols; k++) fprintf(f, "%.4lf ", n.net[k]); fprintf(f, "\n"); for(int k=0; k<cols; k++)
fprintf(f, "%.4lf ", n.net[k]);
fprintf(f, "\n");
} }
fclose(f); fclose(f);
} }

View File

@ -388,6 +388,15 @@ eItem orbType(eLand l) {
return itNone; return itNone;
} }
const orbinfo& getOrbInfo(eItem orb) {
for(int i=0; i<ORBLINES; i++)
if(orbinfos[i].orb == orb && orbinfos[i].gchance)
return orbinfos[i];
static orbinfo oi;
oi.l = laMirror;
return oi;
}
enum eOrbLandRelation { enum eOrbLandRelation {
olrForbidden, // never appears: forbidden olrForbidden, // never appears: forbidden
olrDangerous, // never appears: would be dangerous olrDangerous, // never appears: would be dangerous
@ -613,10 +622,10 @@ bool landUnlocked(eLand l) {
switch(l) { switch(l) {
case laOvergrown: case laOvergrown:
return gold() >= 60 && items[itRuby] >= 10; return gold() >= R60 && items[itRuby] >= U10;
case laStorms: case laWhirlwind: case laStorms: case laWhirlwind:
return gold() >= 60; return gold() >= R60;
case laWildWest: case laHalloween: case laWildWest: case laHalloween:
return false; return false;
@ -627,49 +636,49 @@ bool landUnlocked(eLand l) {
case laMirror: case laMinefield: case laPalace: case laMirror: case laMinefield: case laPalace:
case laOcean: case laLivefjord: case laOcean: case laLivefjord:
return gold() >= 30; return gold() >= R30;
case laCaribbean: case laWhirlpool: case laCaribbean: case laWhirlpool:
return exploreland[0][laOcean] || items[itCoast] || items[itStatue]; return exploreland[0][laOcean] || items[itCoast] || items[itStatue];
case laRlyeh: case laDryForest: case laWineyard: case laCrossroads2: case laRlyeh: case laDryForest: case laWineyard: case laCrossroads2:
return gold() >= 60; return gold() >= R60;
case laDeadCaves: case laDeadCaves:
return gold() >= 60 && items[itGold] >= 10; return gold() >= R60 && items[itGold] >= U10;
case laGraveyard: case laGraveyard:
return tkills() >= 100; return tkills() >= R100;
case laHive: case laHive:
return tkills() >= 100 && gold() >= 60; return tkills() >= R100 && gold() >= R60;
case laRedRock: case laRedRock:
return gold() >= 60 && items[itSpice] >= 10; return gold() >= R60 && items[itSpice] >= U10;
case laEmerald: case laEmerald:
return (items[itFernFlower] >= 5 && items[itGold] >= 5) || kills[moVizier]; return (items[itFernFlower] >= U5 && items[itGold] >= U5) || kills[moVizier];
case laCamelot: case laCamelot:
return items[itEmerald] >= 5; return items[itEmerald] >= U5;
case laHell: case laCrossroads3: case laHell: case laCrossroads3:
return hellUnlocked(); return hellUnlocked();
case laPower: case laPower:
return items[itHell] >= 10; return items[itHell] >= U10;
case laCocytus: case laCocytus:
return items[itHell] >= 10 && items[itDiamond] >= 10; return items[itHell] >= U10 && items[itDiamond] >= U10;
case laTemple: case laTemple:
return items[itStatue] >= 5; return items[itStatue] >= U5;
case laClearing: case laClearing:
return items[itMutant] >= 5; return items[itMutant] >= U5;
case laIvoryTower: return gold() >= 30; case laIvoryTower: return gold() >= R30;
case laZebra: return gold() >= 30 && items[itFeather] >= 10; case laZebra: return gold() >= R30 && items[itFeather] >= U10;
case laEAir: case laEEarth: case laEWater: case laEFire: case laElementalWall: case laEAir: case laEEarth: case laEWater: case laEFire: case laElementalWall:
return elementalUnlocked(); return elementalUnlocked();
@ -678,52 +687,52 @@ bool landUnlocked(eLand l) {
return false; return false;
case laHaunted: case laHauntedWall: case laHauntedBorder: case laHaunted: case laHauntedWall: case laHauntedBorder:
return items[itBone] >= 10; return items[itBone] >= U10;
case laPrincessQuest: return kills[moVizier] && !shmup::on && multi::players == 1; case laPrincessQuest: return kills[moVizier] && !shmup::on && multi::players == 1;
case laRose: case laRose:
return gold() >= 60; return gold() >= R60;
case laWarpCoast: case laWarpSea: case laWarpCoast: case laWarpSea:
return gold() >= 30; return gold() >= R30;
case laCrossroads4: case laCrossroads4:
return gold() >= 200; return gold() >= R200;
case laEndorian: case laEndorian:
return items[itIvory] >= 10; return items[itIvory] >= U10;
case laTortoise: case laTortoise:
return tortoise::seek(); return tortoise::seek();
case laDragon: case laDragon:
return killtypes() >= 20; return killtypes() >= R20;
case laKraken: case laKraken:
return items[itFjord] >= 10; return items[itFjord] >= U10;
case laBurial: case laBurial:
return items[itKraken] >= 10; return items[itKraken] >= U10;
case laTrollheim: case laTrollheim:
return trollUnlocked(); return trollUnlocked();
case laDungeon: case laDungeon:
return items[itPalace] >= 5 && items[itIvory] >= 5; return items[itPalace] >= U5 && items[itIvory] >= U5;
case laMountain: case laMountain:
return items[itRuby] >= 5 && items[itIvory] >= 5; return items[itRuby] >= U5 && items[itIvory] >= U5;
case laReptile: case laReptile:
return gold() >= 30 && items[itElixir] >= 10; return gold() >= R30 && items[itElixir] >= U10;
case laPrairie: case laPrairie:
case laBull: case laBull:
return gold() >= 90; return gold() >= R90;
case laCrossroads5: case laCrossroads5:
return gold() >= 300; return gold() >= R300;
} }
return false; return false;
} }
@ -731,7 +740,7 @@ bool landUnlocked(eLand l) {
int orbsUnlocked() { int orbsUnlocked() {
int i = 0; int i = 0;
for(int t=0; t<ittypes; t++) for(int t=0; t<ittypes; t++)
if(itemclass(eItem(t)) == IC_TREASURE && items[t] >= 10) if(itemclass(eItem(t)) == IC_TREASURE && items[t] >= R10)
i++; i++;
return i; return i;
} }
@ -745,7 +754,7 @@ void countHyperstoneQuest(int& i1, int& i2) {
for(int t=1; t<ittypes; t++) for(int t=1; t<ittypes; t++)
if(t != itHyperstone && t != itBounty && t != itTreat && if(t != itHyperstone && t != itBounty && t != itTreat &&
itemclass(eItem(t)) == IC_TREASURE) { itemclass(eItem(t)) == IC_TREASURE) {
i2++; if(items[t] >= 10) i1++; i2++; if(items[t] >= R10) i1++;
} }
} }
@ -991,12 +1000,14 @@ ld orbprizefun(int tr) {
} }
ld orbcrossfun(int tr) { ld orbcrossfun(int tr) {
if(inv::on) return tr >= 50 ? 1 : 0;
if(tr < 10) return 0; if(tr < 10) return 0;
if(tr > 25) return 1; if(tr > 25) return 1;
return (tr*2 + 50) / 100.; return (tr*2 + 50) / 100.;
} }
bool buildPrizeMirror(cell *c, int freq) { bool buildPrizeMirror(cell *c, int freq) {
if(inv::on) return false;
if(c->type == 7 && !purehepta) return false; if(c->type == 7 && !purehepta) return false;
if(items[itShard] < 25) return false; if(items[itShard] < 25) return false;
if(freq && hrand(freq * 100 / orbprizefun(items[itShard])) >= 100) if(freq && hrand(freq * 100 / orbprizefun(items[itShard])) >= 100)
@ -1008,6 +1019,7 @@ bool buildPrizeMirror(cell *c, int freq) {
void placePrizeOrb(cell *c) { void placePrizeOrb(cell *c) {
eLand l = c->land; eLand l = c->land;
if(isElemental(l)) l = laElementalWall; if(isElemental(l)) l = laElementalWall;
if(peace::on) return;
// these two lands would have too much orbs according to normal rules // these two lands would have too much orbs according to normal rules
if(l == laPalace && hrand(100) >= 20) return; if(l == laPalace && hrand(100) >= 20) return;
@ -1021,6 +1033,7 @@ void placePrizeOrb(cell *c) {
l = laPrincessQuest; l = laPrincessQuest;
for(int i=0; i<ORBLINES; i++) { for(int i=0; i<ORBLINES; i++) {
const orbinfo& oi(orbinfos[i]); const orbinfo& oi(orbinfos[i]);
if(inv::on && oi.orb != itOrbYendor) return;
eOrbLandRelation olr = getOLR(oi.orb, l); eOrbLandRelation olr = getOLR(oi.orb, l);
if(olr != olrPrize25 && olr != olrPrize3) continue; if(olr != olrPrize25 && olr != olrPrize3) continue;
int treas = items[treasureType(oi.l)]; int treas = items[treasureType(oi.l)];
@ -1051,10 +1064,12 @@ void placeLocalOrbs(cell *c) {
if(l == laZebra && c->wall == waTrapdoor) return; if(l == laZebra && c->wall == waTrapdoor) return;
if(isGravityLand(l) && cellEdgeUnstable(c)) return; if(isGravityLand(l) && cellEdgeUnstable(c)) return;
if(isElemental(l)) l = laElementalWall; if(isElemental(l)) l = laElementalWall;
if(peace::on) return;
for(int i=0; i<ORBLINES; i++) { for(int i=0; i<ORBLINES; i++) {
const orbinfo& oi(orbinfos[i]); const orbinfo& oi(orbinfos[i]);
if(oi.l != l) continue; if(oi.l != l) continue;
if(inv::on && (oi.orb != itOrbYendor)) continue;
if(yendor::on && (oi.orb == itOrbSafety || oi.orb == itOrbYendor)) if(yendor::on && (oi.orb == itOrbSafety || oi.orb == itOrbYendor))
continue; continue;
if(!oi.lchance) continue; if(!oi.lchance) continue;
@ -1074,9 +1089,11 @@ void placeLocalOrbs(cell *c) {
} }
void placeCrossroadOrbs(cell *c) { void placeCrossroadOrbs(cell *c) {
if(peace::on) return;
for(int i=0; i<ORBLINES; i++) { for(int i=0; i<ORBLINES; i++) {
const orbinfo& oi(orbinfos[i]); const orbinfo& oi(orbinfos[i]);
if(!oi.gchance) continue; if(!oi.gchance) continue;
if(inv::on && oi.orb != itOrbSafety && oi.orb != itOrbYendor) return;
int treas = items[treasureType(oi.l)] * landMultiplier(oi.l); int treas = items[treasureType(oi.l)] * landMultiplier(oi.l);
if(tactic::on && isCrossroads(tactic::lasttactic)) { if(tactic::on && isCrossroads(tactic::lasttactic)) {
if(oi.orb == itOrbYendor || oi.orb == itOrbSummon || oi.orb == itOrbFish || oi.orb == itOrbDigging || oi.orb == itOrbLove || oi.orb == itOrbLuck) if(oi.orb == itOrbYendor || oi.orb == itOrbSummon || oi.orb == itOrbFish || oi.orb == itOrbDigging || oi.orb == itOrbLove || oi.orb == itOrbLuck)
@ -1097,8 +1114,10 @@ void placeCrossroadOrbs(cell *c) {
} }
void placeOceanOrbs(cell *c) { void placeOceanOrbs(cell *c) {
if(peace::on) return;
for(int i=0; i<ORBLINES; i++) { for(int i=0; i<ORBLINES; i++) {
const orbinfo& oi(orbinfos[i]); const orbinfo& oi(orbinfos[i]);
if(inv::on && oi.orb != itOrbSafety && oi.orb != itOrbYendor) return;
if(items[treasureType(oi.l)] * landMultiplier(oi.l) < 10) continue; if(items[treasureType(oi.l)] * landMultiplier(oi.l) < 10) continue;
if(!oi.gchance) continue; if(!oi.gchance) continue;
if(oi.orb == itOrbLife) continue; // useless if(oi.orb == itOrbLife) continue; // useless
@ -1136,8 +1155,7 @@ void raiseBuggyGeneration(cell *c, const char *s) {
} }
// return; // return;
#ifdef LOCAL #ifdef DEBUG_LANDGEN
describeCell(c); describeCell(c);
for(int i=0; i<c->type; i++) describeCell(c->mov[i]); for(int i=0; i<c->type; i++) describeCell(c->mov[i]);
@ -1547,10 +1565,6 @@ eLand pickluck(eLand l1, eLand l2) {
#define LIKELY for(int u=0; u<5; u++) #define LIKELY for(int u=0; u<5; u++)
template<class T> T pick(T x, T y) { return hrand(2) ? x : y; }
template<class T> T pick(T x, T y, T z) { switch(hrand(3)) { case 0: return x; case 1: return y; case 2: return z; } return x; }
template<class T> T pick(T x, T y, T z, T v) { switch(hrand(4)) { case 0: return x; case 1: return y; case 2: return z; case 3: return v; } return x; }
bool noChaos(eLand l) { bool noChaos(eLand l) {
if(l == laOcean || l == laTemple) return false; if(l == laOcean || l == laTemple) return false;
return return
@ -1563,6 +1577,7 @@ eLand getNewSealand(eLand old) {
while(true) { while(true) {
eLand p = pick(laOcean, pick(laCaribbean, laLivefjord, laWarpSea, laKraken)); eLand p = pick(laOcean, pick(laCaribbean, laLivefjord, laWarpSea, laKraken));
if(p == laKraken && !landUnlocked(p)) continue; if(p == laKraken && !landUnlocked(p)) continue;
if(p == laKraken && peace::on) continue;
if(incompatible(old, p)) continue; if(incompatible(old, p)) continue;
if(p == old) continue; if(p == old) continue;
if(chaosmode && noChaos(p)) continue; if(chaosmode && noChaos(p)) continue;
@ -1574,49 +1589,31 @@ bool doEndorian = false;
int whichnow=0; int whichnow=0;
bool createOnSea(eLand old) {
return
old == laWarpSea || old == laCaribbean || old == laKraken ||
(old == laLivefjord && hrand(2)) ||
(old == laOcean && (chaosmode ? hrand(2) : !generatingEquidistant));
}
eLand getNewLand(eLand old) { eLand getNewLand(eLand old) {
/* eLand landtab[10] = { #ifdef EXTRA_NEWLAND
laWhirlwind, laRose, laEndorian, laRlyeh, if(true) {
laPalace, laOcean, laEmerald, laStorms, eLand l = extra::getNext(old);
laGraveyard, laAlchemist if(l) return l;
}; */ }
#endif
// return landtab[items[itStrongWind]++ % 10];
// if(old != laPrairie) return laRiver;
#ifdef TOUR #ifdef TOUR
if(tour::on) { if(tour::on) {
eLand l = tour::getNext(old); eLand l = tour::getNext(old);
if(l) return l; if(l) return l;
} }
#endif
#ifdef LOCAL if(peace::on) {
extern bool doAutoplay; eLand l = peace::getNext(old);
if(doAutoplay) if(l) return l;
return pick(laOcean, laLivefjord, laWarpSea, laWarpCoast);
extern bool doCross;
if(doCross) {
whichnow++;
eLand tabb[30] = {
/* laIce, laRedRock, laCaribbean, laWarpCoast, laWhirlwind, laPower,
laMirror, laPalace, laLivefjord, laAlchemist, laCocytus,
laHell, laJungle, laCaves, laDesert, laRlyeh, laStorms,
laGraveyard, laMotion, laDryForest, laDragon, laZebra, laIvoryTower,
laTrollheim, laOvergrown, laBurial, laRose, laHive, laEmerald,
laEmerald */
laIce, laPalace, laDryForest, laRedRock, laWhirlwind,
laAlchemist, laWarpCoast, laOvergrown,
laEmerald, laWhirlwind,
laIce, laRedRock, laWarpCoast, laPalace, laWhirlwind,
laAlchemist, laDryForest, laOvergrown,
laEmerald, laDesert,
laIce, laRedRock, laWarpCoast, laPalace, laWhirlwind,
laAlchemist, laDryForest, laOvergrown,
laEmerald, laDesert,
};
return tabb[whichnow%30];
} }
#endif #endif
@ -1673,15 +1670,13 @@ eLand getNewLand(eLand old) {
if(isWarped(old) && (hrand(100) < 25) && chaosmode) return eLand(old ^ laWarpCoast ^ laWarpSea); if(isWarped(old) && (hrand(100) < 25) && chaosmode) return eLand(old ^ laWarpCoast ^ laWarpSea);
if(old == laWarpSea || old == laCaribbean || old == laKraken || if(createOnSea(old))
(old == laLivefjord && hrand(2)) ||
(old == laOcean && (chaosmode ? hrand(2) : !generatingEquidistant)))
return getNewSealand(old); return getNewSealand(old);
if(old == laGraveyard && generatingEquidistant) if(old == laGraveyard && generatingEquidistant)
return laHaunted; return laHaunted;
if(old == laOcean && gold() >= 60 && hrand(100) < 75 && !rlyehComplete()) if(old == laOcean && gold() >= R60 && hrand(100) < 75 && !rlyehComplete())
return laRlyeh; return laRlyeh;
if(old == laRlyeh && !rlyehComplete()) if(old == laRlyeh && !rlyehComplete())
@ -1708,7 +1703,7 @@ eLand getNewLand(eLand old) {
if(old != laDeadCaves) tab[cnt++] = laCaves; if(old != laDeadCaves) tab[cnt++] = laCaves;
// the intermediate lands // the intermediate lands
if(gold() >= 30) { if(gold() >= R30) {
tab[cnt++] = laCrossroads; tab[cnt++] = laCrossroads;
tab[cnt++] = laMirror; tab[cnt++] = laMirror;
tab[cnt++] = laOcean; tab[cnt++] = laOcean;
@ -1717,15 +1712,15 @@ eLand getNewLand(eLand old) {
tab[cnt++] = laPalace; tab[cnt++] = laPalace;
if(old == laDragon) LIKELY tab[cnt++] = laReptile; if(old == laDragon) LIKELY tab[cnt++] = laReptile;
if(kills[moVizier]) tab[cnt++] = laEmerald; if(kills[moVizier]) tab[cnt++] = laEmerald;
if(items[itFeather] >= 10) tab[cnt++] = laZebra; if(items[itFeather] >= U10) tab[cnt++] = laZebra;
tab[cnt++] = laWarpCoast; tab[cnt++] = laWarpCoast;
if(euclid) tab[cnt++] = laWarpSea; if(euclid) tab[cnt++] = laWarpSea;
// Ivory Tower tends to crash while generating equidistant // Ivory Tower tends to crash while generating equidistant
if(!generatingEquidistant) tab[cnt++] = laIvoryTower; if(!generatingEquidistant) tab[cnt++] = laIvoryTower;
if(items[itElixir] >= 10) tab[cnt++] = laReptile; if(items[itElixir] >= U10) tab[cnt++] = laReptile;
if(items[itIvory] >= 10 && !generatingEquidistant) tab[cnt++] = laEndorian; if(items[itIvory] >= U10 && !generatingEquidistant) tab[cnt++] = laEndorian;
if(items[itKraken] >= 10) tab[cnt++] = laBurial; if(items[itKraken] >= U10) tab[cnt++] = laBurial;
} }
if(landUnlocked(laDungeon)) { if(landUnlocked(laDungeon)) {
@ -1734,29 +1729,29 @@ eLand getNewLand(eLand old) {
} }
// the advanced lands // the advanced lands
if(gold() >= 60) { if(gold() >= R60) {
tab[cnt++] = laStorms; tab[cnt++] = laStorms;
tab[cnt++] = laWhirlwind; tab[cnt++] = laWhirlwind;
tab[cnt++] = laCrossroads; tab[cnt++] = laCrossroads;
if(!generatingEquidistant) tab[cnt++] = laCrossroads2; if(!generatingEquidistant) tab[cnt++] = laCrossroads2;
if(items[itRuby] >= 10) { if(items[itRuby] >= U10) {
tab[cnt++] = laOvergrown; tab[cnt++] = laOvergrown;
if(old == laJungle) LIKELY tab[cnt++] = laOvergrown; if(old == laJungle) LIKELY tab[cnt++] = laOvergrown;
} }
if(rlyehComplete()) tab[cnt++] = laRlyeh; if(rlyehComplete()) tab[cnt++] = laRlyeh;
else if(chaosmode && (old == laWarpCoast || old == laLivefjord || old == laOcean)) else if(chaosmode && (old == laWarpCoast || old == laLivefjord || old == laOcean))
tab[cnt++] = laRlyeh; tab[cnt++] = laRlyeh;
if(items[itStatue] >= 5 && chaosmode) if(items[itStatue] >= U5 && chaosmode)
tab[cnt++] = laTemple; tab[cnt++] = laTemple;
if(old == laCrossroads || old == laCrossroads2) tab[cnt++] = laOcean; if(old == laCrossroads || old == laCrossroads2) tab[cnt++] = laOcean;
if(old == laOcean) tab[cnt++] = laCrossroads; if(old == laOcean) tab[cnt++] = laCrossroads;
if(items[itGold] >= 5 && items[itFernFlower] >= 5 && !kills[moVizier]) if(items[itGold] >= U5 && items[itFernFlower] >= U5 && !kills[moVizier])
tab[cnt++] = laEmerald; tab[cnt++] = laEmerald;
tab[cnt++] = laDryForest; tab[cnt++] = laDryForest;
tab[cnt++] = laWineyard; tab[cnt++] = laWineyard;
if(items[itGold] >= 10) tab[cnt++] = laDeadCaves; if(items[itGold] >= U10) tab[cnt++] = laDeadCaves;
// tab[cnt++] = laCaribbean; // tab[cnt++] = laCaribbean;
if(items[itSpice] >= 10) { if(items[itSpice] >= U10) {
tab[cnt++] = laRedRock; tab[cnt++] = laRedRock;
if(old == laDesert) LIKELY tab[cnt++] = laRedRock; if(old == laDesert) LIKELY tab[cnt++] = laRedRock;
} }
@ -1765,22 +1760,22 @@ eLand getNewLand(eLand old) {
tab[cnt++] = laRose; tab[cnt++] = laRose;
} }
if(gold() >= 90) { if(gold() >= R90) {
if(!chaosmode) tab[cnt++] = laPrairie; if(!chaosmode) tab[cnt++] = laPrairie;
if(old == laPrairie) LIKELY tab[cnt++] = laBull; if(old == laPrairie) LIKELY tab[cnt++] = laBull;
tab[cnt++] = laBull; tab[cnt++] = laBull;
if(old == laBull && !chaosmode) LIKELY tab[cnt++] = laPrairie; if(old == laBull && !chaosmode) LIKELY tab[cnt++] = laPrairie;
} }
if(gold() >= 300) if(gold() >= R300)
tab[cnt++] = laCrossroads5; tab[cnt++] = laCrossroads5;
if(tkills() >= 100) { if(tkills() >= R100) {
tab[cnt++] = laGraveyard; tab[cnt++] = laGraveyard;
if(gold() >= 60) tab[cnt++] = laHive; if(gold() >= R60) tab[cnt++] = laHive;
} }
if(killtypes() >= 20) { if(killtypes() >= R20) {
tab[cnt++] = laDragon; tab[cnt++] = laDragon;
if(old == laReptile) LIKELY tab[cnt++] = laDragon; if(old == laReptile) LIKELY tab[cnt++] = laDragon;
} }
@ -1815,8 +1810,8 @@ eLand getNewLand(eLand old) {
tab[cnt++] = laHell; tab[cnt++] = laHell;
} }
if(items[itHell] >= 10) { if(items[itHell] >= U10) {
if(items[itDiamond] >= 10) { if(items[itDiamond] >= U10) {
tab[cnt++] = laCocytus; tab[cnt++] = laCocytus;
if(old == laHell || old == laIce) LIKELY tab[cnt++] = laCocytus; if(old == laHell || old == laIce) LIKELY tab[cnt++] = laCocytus;
} }
@ -1839,6 +1834,7 @@ eLand getNewLand(eLand old) {
} }
bool notDippingFor(eItem i) { bool notDippingFor(eItem i) {
if(peace::on) return false;
int v = items[i] - currentLocalTreasure; int v = items[i] - currentLocalTreasure;
if(v <= 10) return true; if(v <= 10) return true;
if(v >= 20) return false; if(v >= 20) return false;
@ -1846,6 +1842,7 @@ bool notDippingFor(eItem i) {
} }
bool notDippingForExtra(eItem i, eItem x) { bool notDippingForExtra(eItem i, eItem x) {
if(peace::on) return false;
int v = items[i] - min(items[x], currentLocalTreasure); int v = items[i] - min(items[x], currentLocalTreasure);
if(v <= 10) return true; if(v <= 10) return true;
if(v >= 20) return false; if(v >= 20) return false;
@ -1932,11 +1929,7 @@ eLand showlist[10] = {
laHell, laRlyeh, laAlchemist, laGraveyard, laCaves, laDesert, laIce, laJungle, laMotion, laMirror laHell, laRlyeh, laAlchemist, laGraveyard, laCaves, laDesert, laIce, laJungle, laMotion, laMirror
}; };
void buildBarrier(cell *c, int d, eLand l) { void buildBarrierForce(cell *c, int d, eLand l) {
d %= 7;
cellwalker bb(c, d);
if(checkBarriersFront(bb) && checkBarriersBack(bb)) {
c->bardir = d; c->bardir = d;
eLand oldland = c->land; eLand oldland = c->land;
if(oldland == laNone) { if(oldland == laNone) {
@ -1951,6 +1944,13 @@ void buildBarrier(cell *c, int d, eLand l) {
c->landparam = 40; c->landparam = 40;
extendcheck(c); extendcheck(c);
} }
void buildBarrier(cell *c, int d, eLand l) {
d %= 7;
cellwalker bb(c, d);
if(checkBarriersFront(bb) && checkBarriersBack(bb))
buildBarrierForce(c, d, l);
} }
bool buildBarrier4(cell *c, int d, int mode, eLand ll, eLand lr) { bool buildBarrier4(cell *c, int d, int mode, eLand ll, eLand lr) {
@ -2138,20 +2138,12 @@ extern bool bugtrack;
bool generatingEquidistant = false; bool generatingEquidistant = false;
void buildAnotherEquidistant(cell *c) { cell *buildAnotherEquidistant(cell *c, int radius) {
//printf("building another coast\n");
if(yendor::on) return;
int gdir = -1; int gdir = -1;
for(int i=0; i<c->type; i++) { for(int i=0; i<c->type; i++) {
if(c->mov[i] && c->mov[i]->mpdist < c->mpdist) gdir = i; if(c->mov[i] && c->mov[i]->mpdist < c->mpdist) gdir = i;
} }
if(gdir == -1) return; if(gdir == -1) return NULL;
generatingEquidistant = true;
int radius = c->land == laOcean ? 30 : HAUNTED_RADIUS + 5;
cellwalker cw(c, (gdir+3) % c->type); cellwalker cw(c, (gdir+3) % c->type);
vector<cell*> coastpath; vector<cell*> coastpath;
@ -2161,13 +2153,10 @@ void buildAnotherEquidistant(cell *c) {
#ifdef AUTOPLAY #ifdef AUTOPLAY
if(doAutoplay) printf("avoiding the Crossroads II\n"); // todo if(doAutoplay) printf("avoiding the Crossroads II\n"); // todo
#endif #endif
generatingEquidistant = false; return NULL;
return;
}
if(cw.c->bardir != NODIR) {
generatingEquidistant = false;
return;
} }
if(cw.c->bardir != NODIR) return NULL;
/* forCellEx(c2, cw.c) if(c2->bardir != NODIR) { /* forCellEx(c2, cw.c) if(c2->bardir != NODIR) {
generatingEquidistant = false; generatingEquidistant = false;
return; return;
@ -2176,21 +2165,21 @@ void buildAnotherEquidistant(cell *c) {
if(cw.c->land == laNone && cw.c->mpdist <= 7) { if(cw.c->land == laNone && cw.c->mpdist <= 7) {
raiseBuggyGeneration(cw.c, "landNone 1"); raiseBuggyGeneration(cw.c, "landNone 1");
for(int i=0; i<size(coastpath); i++) coastpath[i]->item = itPirate; for(int i=0; i<size(coastpath); i++) coastpath[i]->item = itPirate;
return; return NULL;
} }
cwstep(cw); cwspin(cw, 3); cwstep(cw); cwspin(cw, 3);
if(cw.c->type == 7 && hrand(2) == 0) cwspin(cw, 1); if(cw.c->type == 7 && hrand(2) == 0) cwspin(cw, 1);
} }
int mpd[10];
for(int i=0; i<10; i++) mpd[i] = coastpath[i]->mpdist;
coastpath.push_back(cw.c); coastpath.push_back(cw.c);
// printf("setdists\n"); // printf("setdists\n");
for(int i=1; i<size(coastpath) - 1; i++) { for(int i=1; i<size(coastpath) - 1; i++) {
if(coastpath[i-1]->land == laNone) { if(coastpath[i-1]->land == laNone) {
raiseBuggyGeneration(cwt.c, "landNone 3"); raiseBuggyGeneration(cwt.c, "landNone 3");
int mpd[10];
for(int i=0; i<10; i++) mpd[i] = coastpath[i]->mpdist;
{for(int i=0; i<10; i++) printf("%d ", mpd[i]);} printf("\n"); {for(int i=0; i<10; i++) printf("%d ", mpd[i]);} printf("\n");
for(int i=0; i<size(coastpath); i++) coastpath[i]->item = itPirate; for(int i=0; i<size(coastpath); i++) coastpath[i]->item = itPirate;
return; return NULL;
} }
setdist(coastpath[i], BARLEV, coastpath[i-1]); setdist(coastpath[i], BARLEV, coastpath[i-1]);
setdist(coastpath[i], BARLEV-1, coastpath[i-1]); setdist(coastpath[i], BARLEV-1, coastpath[i-1]);
@ -2210,16 +2199,14 @@ void buildAnotherEquidistant(cell *c) {
if(c2->land == laNone) { if(c2->land == laNone) {
raiseBuggyGeneration(c2, "landNone 2"); raiseBuggyGeneration(c2, "landNone 2");
for(int i=0; i<size(coastpath); i++) coastpath[i]->item = itPirate; for(int i=0; i<size(coastpath); i++) coastpath[i]->item = itPirate;
return; return NULL;
} }
if(c2->land != c->land) { // prevent gravity anomalies
generatingEquidistant = false; if(c2->land != c->land) return NULL;
return; // prevent gravity anomalies
}
// else if(c->type == 7 && hrand(10000) < 20 && !isCrossroads(c->land) && gold() >= 200) // else if(c->type == 7 && hrand(10000) < 20 && !isCrossroads(c->land) && gold() >= 200)
if(c2->type == 7 && gold() >= 200 && hrand(10) < 2 && buildBarrierNowall(c2, laCrossroads4, true)) { if(c2->type == 7 && gold() >= R200 && hrand(10) < 2 && buildBarrierNowall(c2, laCrossroads4, true)) {
nowall = true; nowall = true;
// raiseBuggyGeneration(c2, "check"); // raiseBuggyGeneration(c2, "check");
// return; // return;
@ -2233,6 +2220,20 @@ void buildAnotherEquidistant(cell *c) {
setdist(coastpath[i], j, NULL); setdist(coastpath[i], j, NULL);
} }
return c2;
}
void buildAnotherEquidistant(cell *c) {
//printf("building another coast\n");
if(yendor::on) return;
generatingEquidistant = true;
int radius = c->land == laOcean ? 30 : HAUNTED_RADIUS + 5;
buildAnotherEquidistant(c, radius);
generatingEquidistant = false; generatingEquidistant = false;
} }
@ -2279,7 +2280,11 @@ eMonster crossroadsMonster() {
moWaterElemental, moAirElemental, moFireElemental, moWaterElemental, moAirElemental, moFireElemental,
moFatGuard, moMiner, moPalace, moVizier moFatGuard, moMiner, moPalace, moVizier
}; };
return m[hrand(24)]; eMonster mo = m[hrand(24)];
if(peace::on && mo == moWaterElemental) return crossroadsMonster();
if(peace::on && mo == moFireFairy) return crossroadsMonster();
if(peace::on && isMultitile(mo)) return crossroadsMonster();
return mo;
} }
eMonster wanderingCrossroadsMonster() { eMonster wanderingCrossroadsMonster() {
@ -2535,7 +2540,7 @@ void buildRedWall(cell *c, int gemchance) {
c->wall = waRed3; c->wall = waRed3;
if(hrand(100+ki) < gemchance + ki) if(hrand(100+ki) < gemchance + ki)
c->item = itRedGem; c->item = itRedGem;
if(items[itRedGem] >= 10 && hrand(8000) < gemchance) if(items[itRedGem] >= 10 && hrand(8000) < gemchance && !peace::on && !inv::on)
c->item = itOrbSpace; c->item = itOrbSpace;
else if(hrand(8000) < gemchance * PRIZEMUL) else if(hrand(8000) < gemchance * PRIZEMUL)
placePrizeOrb(c); placePrizeOrb(c);
@ -2876,7 +2881,7 @@ void buildBigStuff(cell *c, cell *from) {
else if(c->type == 7 && c->land == laCrossroads4 && hrand(10000) < 7000 && c->land && else if(c->type == 7 && c->land == laCrossroads4 && hrand(10000) < 7000 && c->land &&
buildBarrierNowall(c, getNewLand(laCrossroads4))) ; buildBarrierNowall(c, getNewLand(laCrossroads4))) ;
else if(c->type == 7 && hrand(10000) < 20 && !generatingEquidistant && !yendor::on && !tactic::on && !isCrossroads(c->land) && gold() >= 200 && else if(c->type == 7 && hrand(10000) < 20 && !generatingEquidistant && !yendor::on && !tactic::on && !isCrossroads(c->land) && gold() >= R200 &&
!isSealand(c->land) && !isHaunted(c->land) && !isGravityLand(c->land) && !isSealand(c->land) && !isHaunted(c->land) && !isGravityLand(c->land) &&
(c->land != laRlyeh || rlyehComplete()) && (c->land != laRlyeh || rlyehComplete()) &&
c->land != laTortoise && c->land != laPrairie && c->land && c->land != laTortoise && c->land != laPrairie && c->land &&
@ -2936,8 +2941,8 @@ void buildBigStuff(cell *c, cell *from) {
} }
if((!chaosmode) && bearsCamelot(c->land) && c->type == 7 && if((!chaosmode) && bearsCamelot(c->land) && c->type == 7 &&
(quickfind(laCamelot) || (hrand(2000) < 200 && (quickfind(laCamelot) || peace::on || (hrand(2000) < 200 &&
items[itEmerald] >= 5 && !tactic::on))) { items[itEmerald] >= U5 && !tactic::on))) {
int rtr = newRoundTableRadius(); int rtr = newRoundTableRadius();
heptagon *alt = createAlternateMap(c, rtr+14, hsOrigin); heptagon *alt = createAlternateMap(c, rtr+14, hsOrigin);
if(alt) { if(alt) {
@ -2951,8 +2956,8 @@ void buildBigStuff(cell *c, cell *from) {
// buildbigstuff // buildbigstuff
if(c->land == laRlyeh && c->type == 7 && if(c->land == laRlyeh && c->type == 7 &&
(quickfind(laTemple) || (hrand(2000) < 100 && (quickfind(laTemple) || peace::on || (hrand(2000) < 100 &&
items[itStatue] >= 5 && !randomPatternsMode && items[itStatue] >= U5 && !randomPatternsMode &&
!tactic::on && !yendor::on))) !tactic::on && !yendor::on)))
createAlternateMap(c, 2, hsA); createAlternateMap(c, 2, hsA);
@ -2963,7 +2968,7 @@ void buildBigStuff(cell *c, cell *from) {
if(c->land == laOvergrown && c->type == 7 && if(c->land == laOvergrown && c->type == 7 &&
(quickfind(laClearing) || (hrand(2000) < 25 && (quickfind(laClearing) || (hrand(2000) < 25 &&
!randomPatternsMode && items[itMutant] >= 5 && !randomPatternsMode && items[itMutant] >= U5 &&
!tactic::on && !yendor::on))) { !tactic::on && !yendor::on))) {
heptagon *h = createAlternateMap(c, 2, hsA); heptagon *h = createAlternateMap(c, 2, hsA);
if(h) clearing::bpdata[h].root = NULL; if(h) clearing::bpdata[h].root = NULL;
@ -2974,7 +2979,7 @@ void buildBigStuff(cell *c, cell *from) {
if(h) h->alt->emeraldval = hrand(2); if(h) h->alt->emeraldval = hrand(2);
} }
if(c->land == laOcean && c->type == 7 && deepOcean && !generatingEquidistant && if(c->land == laOcean && c->type == 7 && deepOcean && !generatingEquidistant && !peace::on &&
(quickfind(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);
@ -2983,9 +2988,10 @@ void buildBigStuff(cell *c, cell *from) {
createAlternateMap(c, 2, hsA); createAlternateMap(c, 2, hsA);
if(c->land == laPalace && c->type == 7 && !princess::generating && !shmup::on && multi::players == 1 && if(c->land == laPalace && c->type == 7 && !princess::generating && !shmup::on && multi::players == 1 &&
(princess::forceMouse ? (from && from->pathdist != INF) : (hrand(2000) < 20)) && (princess::forceMouse ? (from && from->pathdist != INF) :
(hrand(2000) < (peace::on ? 100 : 20))) &&
!c->master->alt && !c->master->alt &&
(princess::challenge || kills[moVizier]) && !tactic::on && !yendor::on) (princess::challenge || kills[moVizier] || peace::on) && !tactic::on && !yendor::on)
createAlternateMap(c, 141, hsOrigin, waPalace); createAlternateMap(c, 141, hsOrigin, waPalace);
} }
@ -3233,6 +3239,7 @@ bool redtrolls(cell *c) {
} }
bool reptilecheat = false; bool reptilecheat = false;
bool weaponless = false;
eMonster pickTroll(cell *c) { eMonster pickTroll(cell *c) {
if(redtrolls(c)) if(redtrolls(c))
@ -3450,6 +3457,8 @@ void setdist(cell *c, int d, cell *from) {
cell *c2 = c->mov[hrand(c->type)]; cell *c2 = c->mov[hrand(c->type)];
if(c2->wall == waNone) c2->wall = waTrapdoor; if(c2->wall == waNone) c2->wall = waTrapdoor;
} }
if((c->wall == waClosePlate || c->wall == waTrapdoor) && peace::on) c->wall = waNone;
} }
if(d==8 && c->land == laEmerald) { if(d==8 && c->land == laEmerald) {
@ -3641,7 +3650,7 @@ void setdist(cell *c, int d, cell *from) {
} }
if(c->land == laTrollheim) { if(c->land == laTrollheim) {
if(hrand(50000) < (chaosmode?1000:5) && c->wall != waBarrier && celldist(c) >= 7 && !safety) { if(hrand(50000) < (chaosmode?1000:5) && c->wall != waBarrier && celldist(c) >= 7 && !safety && !peace::on) {
bool okay = true; bool okay = true;
forCellCM(c2, c) forCellCM(c3, c2) forCellCM(c4, c3) forCellCM(c5, c4) { forCellCM(c2, c) forCellCM(c3, c2) forCellCM(c4, c3) forCellCM(c5, c4) {
cell *cx = chaosmode ? c3 : c5; cell *cx = chaosmode ? c3 : c5;
@ -4252,7 +4261,7 @@ void setdist(cell *c, int d, cell *from) {
c2->hitpoints = 1; c2->hitpoints = 1;
c2->mondir = c->spn(i); c2->mondir = c->spn(i);
} }
playSound(c, "seen-kraken"); if(!peace::on) playSound(c, "seen-kraken");
} }
} }
@ -4282,7 +4291,7 @@ void setdist(cell *c, int d, cell *from) {
if(d == 8 && c->land == laOvergrown) { if(d == 8 && c->land == laOvergrown) {
if(hrand(doCross ?450:15000) < 20 + (2 * items[itMutant] + hard) && !safety) { if(hrand(doCross ?450:15000) < 20 + (2 * items[itMutant] + hard) && !safety) {
c->item = itMutant; if(!peace::on) c->item = itMutant;
c->landparam = items[itMutant] + 5 + hrand(11); c->landparam = items[itMutant] + 5 + hrand(11);
c->wall = waNone; c->wall = waNone;
for(int i=0; i<c->type; i++) for(int i=0; i<c->type; i++)
@ -4338,7 +4347,7 @@ void setdist(cell *c, int d, cell *from) {
int depth = getHauntedDepth(c); int depth = getHauntedDepth(c);
if(hrand(500 + depth) < depth - items[itLotus] && !safety) if(hrand(500 + depth) < depth - items[itLotus] && !safety && !peace::on)
c->item = itLotus; c->item = itLotus;
} }
} }
@ -4373,7 +4382,7 @@ void setdist(cell *c, int d, cell *from) {
} }
if(coast && hrand(10) < 5) { if(coast && hrand(10) < 5) {
c->wall = waBoat; c->wall = waBoat;
if(items[itPirate] >= 10 && hrand(100) < 2 && !safety) if(items[itPirate] >= 10 && hrand(100) < 2 && !safety && !peace::on && !inv::on)
c->item = itOrbTime; c->item = itOrbTime;
else if(hrand(100) < 2*PRIZEMUL && !safety) else if(hrand(100) < 2*PRIZEMUL && !safety)
placePrizeOrb(c); placePrizeOrb(c);
@ -4384,7 +4393,7 @@ void setdist(cell *c, int d, cell *from) {
c->monst = moSeep; c->monst = moSeep;
if(d == 7 && c->land == laLivefjord && c->wall == waSea && hrand(5000) < 15 + items[itFjord] + hard && !safety) { if(d == 7 && c->land == laLivefjord && c->wall == waSea && hrand(5000) < 15 + items[itFjord] + hard && !safety) {
if(items[itFjord] >= 5 && hrand(100) < 20) if(items[itFjord] >= 5 && hrand(100) < 20 && !peace::on)
c->monst = moWaterElemental; c->monst = moWaterElemental;
else { else {
c->monst = moViking; c->monst = moViking;
@ -4401,7 +4410,7 @@ void setdist(cell *c, int d, cell *from) {
c->item = itFjord; c->item = itFjord;
} }
if(d == 7 && c->land == laLivefjord && items[itFjord] >= 10 && hrand(2000) < 2) if(d == 7 && c->land == laLivefjord && items[itFjord] >= 10 && hrand(2000) < 2 && !peace::on && !inv::on)
c->item = itOrbFish; c->item = itOrbFish;
if(d == 7 && c->land == laLivefjord && hrand(2000) < 2*PRIZEMUL) if(d == 7 && c->land == laLivefjord && hrand(2000) < 2*PRIZEMUL)
@ -4444,13 +4453,13 @@ void setdist(cell *c, int d, cell *from) {
else if((c->landparam >= 1 && c->landparam <= 25) || chaosmode) { else if((c->landparam >= 1 && c->landparam <= 25) || chaosmode) {
if(hrand(1000) < 5) if(hrand(1000) < 5)
c->wall = waBoat; c->wall = waBoat;
if(hrand(1000) < PT(50 + kills[moAlbatross]/2, 150)) if(hrand(1000) < PT(50 + kills[moAlbatross]/2, 150) && !peace::on)
c->item = itCoast; c->item = itCoast;
if(hrand(15000) < 10 + 2 * items[itCoast] + 2 * hard) if(hrand(15000) < 10 + 2 * items[itCoast] + 2 * hard)
c->monst = moAlbatross; c->monst = moAlbatross;
if(items[itCoast] >= 10 && hrand(10000) < 5) if(items[itCoast] >= 10 && hrand(10000) < 5 && !peace::on && !inv::on)
c->item = itOrbAir; c->item = itOrbAir;
else if(items[itCoast] >= 10 && hrand(10000) < 6) else if(items[itCoast] >= 10 && hrand(10000) < 6 && !peace::on && !inv::on)
c->item = itOrbEmpathy; c->item = itOrbEmpathy;
if(hrand(10000) < 5*PRIZEMUL) if(hrand(10000) < 5*PRIZEMUL)
placePrizeOrb(c); placePrizeOrb(c);
@ -4539,13 +4548,13 @@ void setdist(cell *c, int d, cell *from) {
if(hrand(5000) < minefreq) if(hrand(5000) < minefreq)
c->wall = waMineMine; c->wall = waMineMine;
else if(hrand(5000) < tfreq && !safety) { else if(hrand(5000) < tfreq && !safety && !peace::on) {
c->item = itBombEgg; c->item = itBombEgg;
c->landparam = items[itBombEgg] + 5 + hrand(11); c->landparam = items[itBombEgg] + 5 + hrand(11);
} }
else if(hrand(5000) < treas - 20 + yendor::hardness() && !safety) else if(hrand(5000) < treas - 20 + yendor::hardness() && !safety)
c->monst = moBomberbird; c->monst = moBomberbird;
else if(treas >= 10 && hrand(5000) < 10 && !safety) else if(treas >= 10 && hrand(5000) < 10 && !safety && !peace::on && !inv::on)
c->item = itOrbFriend; c->item = itOrbFriend;
else if(hrand(5000) < 10*PRIZEMUL && !safety) else if(hrand(5000) < 10*PRIZEMUL && !safety)
placePrizeOrb(c); placePrizeOrb(c);
@ -4665,7 +4674,7 @@ void setdist(cell *c, int d, cell *from) {
else else
c->monst = moFamiliar; c->monst = moFamiliar;
} }
else if(c->landparam >= 14 && hrand(2000) < PT(50+kills[moGargoyle]+kills[moFamiliar], 150) && !cellEdgeUnstable(c) ) { else if(c->landparam >= 14 && hrand(2000) < PT(50+kills[moGargoyle]+kills[moFamiliar], 150) && !cellEdgeUnstable(c) && !peace::on) {
c->item = itIvory; c->item = itIvory;
} }
} }
@ -4673,7 +4682,7 @@ void setdist(cell *c, int d, cell *from) {
if(c->land == laDungeon) { if(c->land == laDungeon) {
int lp = c->landparam * c->landparam; int lp = c->landparam * c->landparam;
if(lp > 100) lp = 100; if(lp > 100) lp = 100;
if(c->landparam >= 10 && hrand(20000) < 5*lp + items[itSlime] + hard && !cellEdgeUnstable(c)) { if(c->landparam >= 10 && hrand(20000) < 5*lp + items[itSlime] + hard && !cellEdgeUnstable(c) && !peace::on) {
c->monst = moSkeleton, c->hitpoints = 3; c->monst = moSkeleton, c->hitpoints = 3;
} }
else if(c->landparam >= 10 && hrand(50000) < lp/2 + items[itSlime] + hard) { else if(c->landparam >= 10 && hrand(50000) < lp/2 + items[itSlime] + hard) {
@ -4709,14 +4718,14 @@ void setdist(cell *c, int d, cell *from) {
} }
if(c->land == laTortoise) { if(c->land == laTortoise) {
if(hrand(4000) < 50 + items[itBabyTortoise]*2 + hard * 6 && !safety) { if(hrand(4000) < (peace::on ? 750 : 50 + items[itBabyTortoise]*2 + hard * 6) && !safety) {
c->monst = moTortoise; c->monst = moTortoise;
c->hitpoints = 3; c->hitpoints = 3;
} }
int chance = 50 + items[itBabyTortoise]*2; int chance = 50 + items[itBabyTortoise]*2;
if(quickfind(laTortoise)) chance += 150; if(quickfind(laTortoise)) chance += 150;
if((tactic::on || euclid) && hrand(4000) < chance && !safety) { if((tactic::on || euclid || peace::on) && hrand(4000) < chance && !safety) {
c->item = itBabyTortoise; c->item = itBabyTortoise;
tortoise::babymap[c] = getBits(c) ^ tortoise::getRandomBits(); tortoise::babymap[c] = getBits(c) ^ tortoise::getRandomBits();
} }
@ -4730,7 +4739,7 @@ void setdist(cell *c, int d, cell *from) {
if(hrand(5000) < PT(100 + 2 * (kills[moPalace] + kills[moFatGuard] + kills[moVizier] + kills[moSkeleton]), 200) && notDippingFor(itPalace) && if(hrand(5000) < PT(100 + 2 * (kills[moPalace] + kills[moFatGuard] + kills[moVizier] + kills[moSkeleton]), 200) && notDippingFor(itPalace) &&
c->wall != waOpenGate && !lookingForPrincess0) c->wall != waOpenGate && !lookingForPrincess0)
c->item = itPalace; c->item = itPalace;
if(items[itPalace] >= 10 && hrand(5000) < 16 && c->wall != waOpenGate) if(items[itPalace] >= 10 && hrand(5000) < 16 && c->wall != waOpenGate && !inv::on && !peace::on)
c->item = hrand(100) < 80 ? itOrbFrog : itOrbDiscord; c->item = hrand(100) < 80 ? itOrbFrog : itOrbDiscord;
if(hrand(5000) < 20*PRIZEMUL && c->wall != waOpenGate) if(hrand(5000) < 20*PRIZEMUL && c->wall != waOpenGate)
placePrizeOrb(c); placePrizeOrb(c);
@ -4806,7 +4815,7 @@ void setdist(cell *c, int d, cell *from) {
if(hrand(5000) < PT(100 + 2 * (kills[moWorm] + kills[moDesertman]), 200) && notDippingFor(itSpice)) if(hrand(5000) < PT(100 + 2 * (kills[moWorm] + kills[moDesertman]), 200) && notDippingFor(itSpice))
c->item = itSpice; c->item = itSpice;
if(hrand(8000) < 10 + 2 * (items[itSpice] + hard) && !c->monst) if(hrand(8000) < 10 + 2 * (items[itSpice] + hard) && !c->monst)
c->monst = hrand(2) ? moWorm : moDesertman, c->monst = (hrand(2) && !peace::on) ? moWorm : moDesertman,
c->mondir = NODIR; c->mondir = NODIR;
} }
if(c->land == laRedRock) { if(c->land == laRedRock) {
@ -4814,7 +4823,7 @@ void setdist(cell *c, int d, cell *from) {
int i = -1; int i = -1;
for(int t=0; t<6; t++) if(c->mov[t]->mpdist > c->mpdist && !pseudohept(c->mov[t])) for(int t=0; t<6; t++) if(c->mov[t]->mpdist > c->mpdist && !pseudohept(c->mov[t]))
i = t; i = t;
if(i != -1) { if(i != -1 && !peace::on) {
c->monst = moHexSnake; c->monst = moHexSnake;
preventbarriers(c); preventbarriers(c);
int len = purehepta ? 2 : ROCKSNAKELENGTH; int len = purehepta ? 2 : ROCKSNAKELENGTH;
@ -4853,7 +4862,7 @@ void setdist(cell *c, int d, cell *from) {
else if((havewhat&HF_DRAGON) && items[itDragon] < 10) else if((havewhat&HF_DRAGON) && items[itDragon] < 10)
dchance = 5; dchance = 5;
if(hrand(150000) < dchance && !c->monst && (!c->wall || c->wall == waChasm)) { if(hrand(150000) < dchance && !c->monst && (!c->wall || c->wall == waChasm) && !peace::on) {
havewhat |= HF_DRAGON; havewhat |= HF_DRAGON;
// printf("dragon generated with dchance = %d\n", dchance); // printf("dragon generated with dchance = %d\n", dchance);
vector<int> possi; vector<int> possi;
@ -4887,7 +4896,7 @@ void setdist(cell *c, int d, cell *from) {
else c2->mondir = NODIR; else c2->mondir = NODIR;
} }
} }
if(!c->monst && !tactic::on && !yendor::on && !euclid && hrand(4000) < 10 && !safety) { if(!c->monst && !tactic::on && !yendor::on && !peace::on && !euclid && hrand(4000) < 10 && !safety) {
c->item = itBabyTortoise; c->item = itBabyTortoise;
tortoise::babymap[c] = getBits(c) ^ tortoise::getRandomBits(); tortoise::babymap[c] = getBits(c) ^ tortoise::getRandomBits();
} }
@ -4918,7 +4927,7 @@ void setdist(cell *c, int d, cell *from) {
} }
else if(hrand(5000) < 100 + elkills*3 && notDippingFor(itElemental)) else if(hrand(5000) < 100 + elkills*3 && notDippingFor(itElemental))
c->item = localshard; c->item = localshard;
else if(hrand(5000) < 10 && items[itElemental] >= 10) else if(hrand(5000) < 10 && items[itElemental] >= 10 && !inv::on && !peace::on)
c->item = itOrbSummon; c->item = itOrbSummon;
else if(hrand(5000) < 10*PRIZEMUL) else if(hrand(5000) < 10*PRIZEMUL)
placePrizeOrb(c); placePrizeOrb(c);
@ -4939,7 +4948,7 @@ void setdist(cell *c, int d, cell *from) {
c->stuntime = 7; c->stuntime = 7;
} }
} }
if(c->land == laBurial && !safety) { if(c->land == laBurial && !safety && !peace::on) {
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 + (quickfind(laBurial) ? 40 : 0)) else if(hrand(5000) < 20 + (quickfind(laBurial) ? 40 : 0))
@ -4956,7 +4965,7 @@ void setdist(cell *c, int d, cell *from) {
int hardchance = items[itRuby] + hard; int hardchance = items[itRuby] + hard;
if(hardchance > 25) hardchance = 25; if(hardchance > 25) hardchance = 25;
bool hardivy = hrand(100) < hardchance; bool hardivy = hrand(100) < hardchance;
if(hardivy ? buildIvy(c, 1, 9) : buildIvy(c, 0, c->type)) if((hardivy ? buildIvy(c, 1, 9) : buildIvy(c, 0, c->type)) && !peace::on)
c->item = itRuby; c->item = itRuby;
} }
} }
@ -5061,7 +5070,7 @@ void setdist(cell *c, int d, cell *from) {
if(c->land == laRlyeh) { if(c->land == laRlyeh) {
if(hrand(5000) < PT(30 + 2 * (kills[moCultist] + kills[moTentacle] + kills[moPyroCultist]), 100) && notDippingFor(itStatue)) if(hrand(5000) < PT(30 + 2 * (kills[moCultist] + kills[moTentacle] + kills[moPyroCultist]), 100) && notDippingFor(itStatue))
c->item = itStatue; c->item = itStatue;
if(hrand(8000) < 5 + items[itStatue] + hard && !c->monst) if(hrand(8000) < 5 + items[itStatue] + hard && !c->monst && !peace::on)
c->monst = moTentacle, c->item = itStatue, c->mondir = NODIR; c->monst = moTentacle, c->item = itStatue, c->mondir = NODIR;
else if(hrand(12000) < 5 + items[itStatue] + hard) else if(hrand(12000) < 5 + items[itStatue] + hard)
c->monst = hrand(3) ? ((hrand(40) < items[itStatue]-25) ? moCultistLeader : moCultist) : moPyroCultist; c->monst = hrand(3) ? ((hrand(40) < items[itStatue]-25) ? moCultistLeader : moCultist) : moPyroCultist;
@ -5082,13 +5091,13 @@ void setdist(cell *c, int d, cell *from) {
(euclid || c->master->alt) ? celldistAlt(c) : 10; (euclid || c->master->alt) ? celldistAlt(c) : 10;
// remember: d is negative // remember: d is negative
if(chaosmode ? hrand(100) < 25 : d % TEMPLE_EACH == 0) { if(chaosmode ? hrand(100) < 25 : d % TEMPLE_EACH == 0) {
if(hrand(5000) < 20 - 2*d && !c->monst) if(hrand(5000) < 20 - 2*d && !c->monst && !peace::on)
c->monst = moTentacle, c->mondir = NODIR; c->monst = moTentacle, c->mondir = NODIR;
} }
else { else {
// int d0 = d % TEMPLE_EACH; // int d0 = d % TEMPLE_EACH;
// if(d0<0) d0=-d0; // if(d0<0) d0=-d0;
if(hrand(100) < 30) // && d0 != 1 && d0 != TEMPLE_EACH-1) if(hrand(100) < (peace::on ? 15 : 30)) // && d0 != 1 && d0 != TEMPLE_EACH-1)
c->wall = waBigStatue; c->wall = waBigStatue;
else if(hrand(20000) < -d) else if(hrand(20000) < -d)
c->monst = hrand(3) ? moCultist : moPyroCultist; c->monst = hrand(3) ? moCultist : moPyroCultist;
@ -5096,7 +5105,7 @@ void setdist(cell *c, int d, cell *from) {
c->monst = moCultistLeader; c->monst = moCultistLeader;
else if(hrand(5000) < 250) else if(hrand(5000) < 250)
c->item = itGrimoire; c->item = itGrimoire;
else if(hrand(5000) < 10 && (chaosmode ? items[itGrimoire] >= 10 : -d > TEMPLE_EACH * 10)) else if(hrand(5000) < 10 && (chaosmode ? items[itGrimoire] >= 10 : -d > TEMPLE_EACH * 10) && !peace::on && !inv::on)
c->item = itOrbDragon; c->item = itOrbDragon;
} }
} }
@ -5116,7 +5125,7 @@ void setdist(cell *c, int d, cell *from) {
c->item = itFernFlower; c->item = itFernFlower;
if(hrand(4000) < 40 + items[itFernFlower] + hard) if(hrand(4000) < 40 + items[itFernFlower] + hard)
c->monst = moHedge; c->monst = moHedge;
else if(hrand(8000) < 2 * items[itFernFlower] + hard) else if(hrand(8000) < 2 * items[itFernFlower] + hard && !peace::on)
c->monst = moFireFairy; c->monst = moFireFairy;
} }
if(c->land == laHell) { if(c->land == laHell) {
@ -5167,8 +5176,8 @@ void setdist(cell *c, int d, cell *from) {
c->monst = eMonster(moBug0 + hrand(3)); */ c->monst = eMonster(moBug0 + hrand(3)); */
} }
if(c->land == laCaribbean) { if(c->land == laCaribbean) {
// if(hrand(1500) < 60 && celldistAlt(c) <= -5) if(hrand(1500) < 4 && celldistAlt(c) <= -5 && peace::on)
// c->item = itCompass; c->item = itCompass;
if(hrand(16000) < 40 + (items[itPirate] + hard)) if(hrand(16000) < 40 + (items[itPirate] + hard))
c->monst = moPirate; c->monst = moPirate;
} }
@ -5227,6 +5236,7 @@ int getGhostTimer() {
} }
int getGhostcount() { int getGhostcount() {
if(peace::on) return 0;
int t = getGhostTimer(); int t = getGhostTimer();
int ghostcount = 0; int ghostcount = 0;
if(t > 80) ghostcount = (t-80 + hrand(20)) / 20; if(t > 80) ghostcount = (t-80 + hrand(20)) / 20;
@ -5383,12 +5393,12 @@ void wandering() {
playSeenSound(c); playSeenSound(c);
continue; continue;
} }
if(c->land == laLivefjord && wchance(items[itFjord], 80) && items[itFjord] >= 10 && canReachPlayer(c, moWaterElemental)) { if(!peace::on && c->land == laLivefjord && wchance(items[itFjord], 80) && items[itFjord] >= 10 && canReachPlayer(c, moWaterElemental)) {
c->monst = moWaterElemental; c->monst = moWaterElemental;
playSeenSound(c); playSeenSound(c);
continue; continue;
} }
if(c->land == laKraken && ((sphere && !hrand(15)) || wchance(items[itKraken], 240)) && !pseudohept(c)) { if(!peace::on && c->land == laKraken && ((sphere && !hrand(15)) || wchance(items[itKraken], 240)) && !pseudohept(c)) {
bool b = canReachPlayer(c, moKrakenH); bool b = canReachPlayer(c, moKrakenH);
if(sphere && (haveKraken() || !items[itOrbFish])) { if(sphere && (haveKraken() || !items[itOrbFish])) {
c->monst = moViking; c->wall = waBoat; c->item = itOrbFish; c->monst = moViking; c->wall = waBoat; c->item = itOrbFish;
@ -5427,13 +5437,13 @@ void wandering() {
c->monst = hrand(2) ? moWolf : moYeti; c->monst = hrand(2) ? moWolf : moYeti;
else if(c->land == laDesert && wchance(items[itSpice], 10)) else if(c->land == laDesert && wchance(items[itSpice], 10))
c->monst = hrand(10) ? moDesertman : moWorm; c->monst = (hrand(10) || peace::on) ? moDesertman : moWorm;
else if(c->land == laDragon && (items[itDragon] >= 8 || items[itOrbYendor]) && wchance(items[itDragon], 20)) else if(c->land == laDragon && (items[itDragon] >= 8 || items[itOrbYendor]) && wchance(items[itDragon], 20))
c->monst = moFireElemental; c->monst = moFireElemental;
else if(c->land == laRedRock && wchance(items[itRedGem], 10)) else if(c->land == laRedRock && wchance(items[itRedGem], 10))
c->monst = hrand(10) ? moRedTroll : moHexSnake; c->monst = (hrand(10) || peace::on) ? moRedTroll : moHexSnake;
else if(c->land == laCaves && wchance(items[itGold], 5)) else if(c->land == laCaves && wchance(items[itGold], 5))
c->monst = hrand(3) ? moTroll : moGoblin; c->monst = hrand(3) ? moTroll : moGoblin;
@ -5513,7 +5523,7 @@ void wandering() {
else if(c->land == laAlchemist && wchance(items[itElixir], 3) && canReachPlayer(c, moSlime) && c->item == itNone) else if(c->land == laAlchemist && wchance(items[itElixir], 3) && canReachPlayer(c, moSlime) && c->item == itNone)
c->monst = moSlime; // ? c->monst = moSlime; // ?
else if(isElemental(c->land) && wchance(items[itElemental], 20)) else if(isElemental(c->land) && wchance(items[itElemental], 20) && !peace::on)
c->monst = elementalOf(c->land); c->monst = elementalOf(c->land);
else if(c->land == laIvoryTower && wchance(items[itIvory], 20)) else if(c->land == laIvoryTower && wchance(items[itIvory], 20))

View File

@ -39,21 +39,21 @@ dictionary<noun> nouns[NUMLAN];
#include <set> #include <set>
int utfsize(char c) {
unsigned char cu = c;
if(cu < 128) return 1;
if(cu < 224) return 2;
if(cu < 0xE0) return 3;
return 4;
}
void addutftoset(set<string>& s, string& w) { void addutftoset(set<string>& s, string& w) {
int i = 0; int i = 0;
//printf("%s\n", w.c_str()); //printf("%s\n", w.c_str());
while(i < size(w)) { while(i < size(w)) {
int siz = utfsize(w[i]);
if(((signed char)(w[i])) < 0) { s.insert(w.substr(i, siz));
string z = w.substr(i, 2); i += siz;
// printf("Insert: %s [%02x%02x]\n", z.c_str(), w[i], w[i+1]);
s.insert(w.substr(i, 2));
i += 2;
}
else {
s.insert(w.substr(i, 1));
i++;
}
} }
} }
@ -143,6 +143,8 @@ int main() {
plural.insert("Elemental Planes"); plural.insert("Elemental Planes");
plural.insert("Crossroads IV"); plural.insert("Crossroads IV");
plural.insert("Kraken Depths"); plural.insert("Kraken Depths");
allchars.insert("");
allchars.insert("δ");
#define S(a,b) d[1].add(a,b); #define S(a,b) d[1].add(a,b);
#define N(a,b,c,d,e,f) \ #define N(a,b,c,d,e,f) \
@ -236,7 +238,7 @@ int main() {
//printf("ALL:"); //printf("ALL:");
for(set<string>::iterator it = allchars.begin(); it != allchars.end(); it++) { for(set<string>::iterator it = allchars.begin(); it != allchars.end(); it++) {
// printf(" \"%s\",", it->c_str()); // printf(" \"%s\",", it->c_str());
if(size(*it) == 2) { javastring += (*it); vchars.push_back(*it); c++; } if(size(*it) >= 2) { javastring += (*it); vchars.push_back(*it); c++; }
} }
printf("// DO NOT EDIT -- this file is generated automatically with langen\n"); printf("// DO NOT EDIT -- this file is generated automatically with langen\n");
printf("\n"); printf("\n");

View File

@ -265,7 +265,7 @@ S("You feel that you have enough treasure to access new lands!", "Cítíš, že
S("Collect more treasures, there are still more lands waiting...", "Sbírej další poklady, další kraje stále čekají...") S("Collect more treasures, there are still more lands waiting...", "Sbírej další poklady, další kraje stále čekají...")
S("You feel that the stars are right, and you can access R'Lyeh!", "Cítíš, že postavení hvězd je správné, a ty můžeš vstoupit do R'Lyeh!") S("You feel that the stars are right, and you can access R'Lyeh!", "Cítíš, že postavení hvězd je správné, a ty můžeš vstoupit do R'Lyeh!")
S("Kill monsters and collect treasures, and you may get access to Hell...", "Zabíjej netvory a sbírej poklady a možná najdeš cestu do Pekla...") S("Kill monsters and collect treasures, and you may get access to Hell...", "Zabíjej netvory a sbírej poklady a možná najdeš cestu do Pekla...")
S("To access Hell, collect 10 treasures each of 9 kinds...", "Aby ses dostal do Pekla, sesbírej 10 pokladů od každého z 9 různých typů...") S("To access Hell, collect %1 treasures each of 9 kinds...", "Aby ses dostal do Pekla, sesbírej %1 pokladů od každého z 9 různých typů...")
S("Abandon all hope, the gates of Hell are opened!", "Zanech vší naděje, brány Pekla jsou otevřeny!") S("Abandon all hope, the gates of Hell are opened!", "Zanech vší naděje, brány Pekla jsou otevřeny!")
S("And the Orbs of Yendor await!", "A Yendorské sféry čekají!") S("And the Orbs of Yendor await!", "A Yendorské sféry čekají!")
S("You switch places with %the1.", "Vyměni%l0 sis místo s %abl1.") S("You switch places with %the1.", "Vyměni%l0 sis místo s %abl1.")
@ -367,11 +367,11 @@ S("GAME OVER", "KONEC HRY")
S("Your score: %1", "Tvé skóre: %1") S("Your score: %1", "Tvé skóre: %1")
S("Enemies killed: %1", "Zabitých netvorů: %1") S("Enemies killed: %1", "Zabitých netvorů: %1")
S("Orbs of Yendor found: %1", "Nalezených Yendorských sfér: %1") S("Orbs of Yendor found: %1", "Nalezených Yendorských sfér: %1")
S("Collect 30 $$$ to access more worlds", "Další kraje zpřístupníš sesbíráním 30 $$$") S("Collect %1 $$$ to access more worlds", "Další kraje zpřístupníš sesbíráním %1 $$$")
// S("Collect 60 $$$ to access R'Lyeh and Dry Forest", "R'Lyeh a Suchý hvozd zpřístupníš sesbíráním 60 $$$") // S("Collect %1 $$$ to access R'Lyeh and Dry Forest", "R'Lyeh a Suchý hvozd zpřístupníš sesbíráním %1 $$$")
S("Collect at least 10 treasures in each of 9 types to access Hell", "Peklo zpřístupníš sesbíráním 10 pokladů od každého z 9 typů") S("Collect at least %1 treasures in each of 9 types to access Hell", "Peklo zpřístupníš sesbíráním %1 pokladů od každého z 9 typů")
S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Yendorské sféry zpřístupníš sesbíráním nejméně 10 Čertových kvítek") S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Yendorské sféry zpřístupníš sesbíráním nejméně 10 Čertových kvítek")
S("Hyperstone Quest: collect at least 10 %1 in %the2", "Hyperkamový úkol: sesbírej nejméně 10 pokladů %abl2") S("Hyperstone Quest: collect at least %3 %1 in %the2", "Hyperkamový úkol: sesbírej nejméně %3 pokladů %abl2")
S("Hyperstone Quest completed!", "Hyperkamový úkol splněn!") S("Hyperstone Quest completed!", "Hyperkamový úkol splněn!")
S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Hledej Yendorské sféry v Pekle nebo na Křižovatce!") S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Hledej Yendorské sféry v Pekle nebo na Křižovatce!")
S("Unlock the Orb of Yendor!", "Odemkni Yendorskou sféru!") S("Unlock the Orb of Yendor!", "Odemkni Yendorskou sféru!")
@ -1009,7 +1009,7 @@ S("Periodic Editor", "Periodický editor")
// also translate this line: // also translate this line:
// "Stiskem kláves 0-4 můžete různě přepínat zdi\n", // "Stiskem kláves 0-4 můžete různě přepínat zdi\n",
S("Collect 60 $$$ to access even more lands", "Sesbíráním 60 $$$ získáš přístup do dalších krajů") S("Collect %1 $$$ to access even more lands", "Sesbíráním %1 $$$ získáš přístup do dalších krajů")
// Emerald Mine // Emerald Mine
// ------------ // ------------
@ -2530,8 +2530,8 @@ S("Accessible only from %the1 (until finished).\n", "Tento kraj je dostupný pou
S("Accessible only from %the1 or %the2.\n", "Tento kraj je dostupný pouze skrz %a1 nebo %a2.\n") S("Accessible only from %the1 or %the2.\n", "Tento kraj je dostupný pouze skrz %a1 nebo %a2.\n")
S("Kills required: %1.\n", "Potřebuješ zabít %1 nepřátel.\n") S("Kills required: %1.\n", "Potřebuješ zabít %1 nepřátel.\n")
S("Finished lands required: %1 (collect 10 treasure)\n", S("Finished lands required: %1 (collect %2 treasure)\n",
"Potřebuješ dokončit %1 krajů (získat v nich 10 pokladů)\n") "Potřebuješ dokončit %1 krajů (získat v nich %2 pokladů)\n")
S("Treasure required: %1 x %2.\n", "Potřebuješ %1 x %2.\n") S("Treasure required: %1 x %2.\n", "Potřebuješ %1 x %2.\n")
@ -3821,8 +3821,8 @@ S(
S("%The1 scares %the2 a bit!", "%1 trochu vyleka%l1 %a2!") S("%The1 scares %the2 a bit!", "%1 trochu vyleka%l1 %a2!")
S("%The1 attacks your shell!", "%1 zaútoči%l1 na tvůj krunýř!") S("%The1 attacks your shell!", "%1 zaútoči%l1 na tvůj krunýř!")
S("Hyperstone Quest: collect at least 10 points in %the2", S("Hyperstone Quest: collect at least %3 points in %the2",
"Hyperkamový úkol: získej nejméně 10 bodů %abl2") "Hyperkamový úkol: získej nejméně %3 bodů %abl2")
S("animals killed: %1", "zabitých zvířat: %1") S("animals killed: %1", "zabitých zvířat: %1")
S("\n\nTortoises are not monsters! They are just annoyed. They do not count for your total kills.", S("\n\nTortoises are not monsters! They are just annoyed. They do not count for your total kills.",
@ -5011,7 +5011,7 @@ N("Tortoise", GEN_F, "Želva", "Želvy", "Želva", "Želvou")
S("line patterns", "vzory čar") S("line patterns", "vzory čar")
S("1 turn", "1 kolo") S("1 turn", "1 kolo")
S("%1 turns", "kola: %1") S("%1 turns", "kola: %1")
S("items/kills mode", "mód předmětů/zabitých netvorů") S("inventory/kill mode", "mód předmětů/zabitých netvorů")
S("images", "obrázky") S("images", "obrázky")
S("letters", "písmena") S("letters", "písmena")
S("input", "vstup") S("input", "vstup")

View File

@ -243,7 +243,7 @@ S("You feel that you have enough treasure to access new lands!", "Du spürst, da
S("Collect more treasures, there are still more lands waiting...", "Sammle mehr Schätze, es warten weitere Länder auf dich...") S("Collect more treasures, there are still more lands waiting...", "Sammle mehr Schätze, es warten weitere Länder auf dich...")
S("You feel that the stars are right, and you can access R'Lyeh!", "Die Sterne stehen günstig, du kannst R´Lyeh erreichen!") S("You feel that the stars are right, and you can access R'Lyeh!", "Die Sterne stehen günstig, du kannst R´Lyeh erreichen!")
S("Kill monsters and collect treasures, and you may get access to Hell...", "Wenn du Monster tötest und Schätze sammelst erhältst du vielleicht Zutritt zur Hölle...") S("Kill monsters and collect treasures, and you may get access to Hell...", "Wenn du Monster tötest und Schätze sammelst erhältst du vielleicht Zutritt zur Hölle...")
S("To access Hell, collect 10 treasures each of 9 kinds...", "Um die Hölle zu erreichen sammle je 10 von 9 verschiedenen Schätzen...") S("To access Hell, collect %1 treasures each of 9 kinds...", "Um die Hölle zu erreichen sammle je %1 von 9 verschiedenen Schätzen...")
S("Abandon all hope, the gates of Hell are opened!", "Gib jegliche Hoffnung auf, die Pforte der Hölle ist geöffnet!") S("Abandon all hope, the gates of Hell are opened!", "Gib jegliche Hoffnung auf, die Pforte der Hölle ist geöffnet!")
S("And the Orbs of Yendor await!", "Und die Orbs von Yendor erwarten dich!") S("And the Orbs of Yendor await!", "Und die Orbs von Yendor erwarten dich!")
S("You switch places with %the1.", "Du tauschst den Platz mit %dem1 %a1.") S("You switch places with %the1.", "Du tauschst den Platz mit %dem1 %a1.")
@ -334,10 +334,10 @@ S("GAME OVER", "GAME OVER")
S("Your score: %1", "Punkte: %1") S("Your score: %1", "Punkte: %1")
S("Enemies killed: %1", "Getötete Gegner: %1") S("Enemies killed: %1", "Getötete Gegner: %1")
S("Orbs of Yendor found: %1", "Orbs von Yendor gefunden: %1") S("Orbs of Yendor found: %1", "Orbs von Yendor gefunden: %1")
S("Collect 30 $$$ to access more worlds", "Sammle 30 $$$ um mehr Länder betreten zu können") S("Collect %1 $$$ to access more worlds", "Sammle %1 $$$ um mehr Länder betreten zu können")
S("Collect at least 10 treasures in each of 9 types to access Hell", "Sammle 9 verschiedene Schätze mindestens 10x um Zugang zur Hölle zu erhalten") S("Collect at least %1 treasures in each of 9 types to access Hell", "Sammle 9 verschiedene Schätze mindestens %1x um Zugang zur Hölle zu erhalten")
S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Sammle mindestens 10 Dämonenblümchen um die Orbs von Yendor zu finden") S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Sammle mindestens 10 Dämonenblümchen um die Orbs von Yendor zu finden")
S("Hyperstone Quest: collect at least 10 %1 in %the2", "Hyperstein-Herausforderung: Sammle 10 %P1 %a2") S("Hyperstone Quest: collect at least %3 %1 in %the2", "Hyperstein-Herausforderung: Sammle %3 %P1 %a2")
S("Hyperstone Quest completed!", "Hyperstein-Herausforderung abgeschlossen!") S("Hyperstone Quest completed!", "Hyperstein-Herausforderung abgeschlossen!")
S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Such die Orbs von Yendor in der Hölle oder auf den Kreuzungen!") S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Such die Orbs von Yendor in der Hölle oder auf den Kreuzungen!")
S("Unlock the Orb of Yendor!", "Öffne den Orb von Yendor!") S("Unlock the Orb of Yendor!", "Öffne den Orb von Yendor!")
@ -947,7 +947,7 @@ S("Periodic Editor", "Periodischer Editor")
// "In the periodic editor, press 0-4 to switch walls in different ways\n", // "In the periodic editor, press 0-4 to switch walls in different ways\n",
// "Im periodischen Editor kannst du 0-4 verwenden um die Wände zu verändern\n" // "Im periodischen Editor kannst du 0-4 verwenden um die Wände zu verändern\n"
S("Collect 60 $$$ to access even more lands", "Sammle 60 $$$ um noch mehr Länder zu besuchen.") S("Collect %1 $$$ to access even more lands", "Sammle %1 $$$ um noch mehr Länder zu besuchen.")
// Emerald Mine // Emerald Mine
@ -2337,8 +2337,8 @@ S("Accessible only from %the1 (until finished).\n", "Nur von %der1 %a1 aus errei
S("Accessible only from %the1 or %the2.\n", "Nur von %der1 %a1 oder %der %a2 aus erreichbar.\n") S("Accessible only from %the1 or %the2.\n", "Nur von %der1 %a1 oder %der %a2 aus erreichbar.\n")
S("Kills required: %1.\n", "Benötigte Kills: %1.\n") S("Kills required: %1.\n", "Benötigte Kills: %1.\n")
S("Finished lands required: %1 (collect 10 treasure)\n", S("Finished lands required: %1 (collect %2 treasure)\n",
"Abgeschlossene Länder benötigt: %1 (sammle 10 Schätze)\n") "Abgeschlossene Länder benötigt: %1 (sammle %2 Schätze)\n")
S("Treasure required: %1 x %2.\n", "Benötigte Schätze: %1 x %2.\n") S("Treasure required: %1 x %2.\n", "Benötigte Schätze: %1 x %2.\n")
@ -3427,7 +3427,8 @@ S("Dragon Scales are a prized material for armors. "
"wie sie einen Drachen getötet haben.\n\n" "wie sie einen Drachen getötet haben.\n\n"
"Drachenschuppen verschwinden nach 500 Zügen.") "Drachenschuppen verschwinden nach 500 Zügen.")
S("Dragons are powerful monsters. They are slow, but evil, " S(
"Dragons are powerful monsters. They are slow, but evil, "
"and love to pick on creatures who are even slower than " "and love to pick on creatures who are even slower than "
"them. They must be stopped!\n\n" "them. They must be stopped!\n\n"
@ -3438,8 +3439,8 @@ S("Dragons are powerful monsters. They are slow, but evil, "
"The head will regenerate on the " "The head will regenerate on the "
"turns the Dragon is not moving, so you will usually have to hit it with " "turns the Dragon is not moving, so you will usually have to hit it with "
"your last attack; otherwise, if the head is healthy, it may breathe " "your last attack; otherwise, if the head is healthy, it may breathe "
"fire (at range 3), losing the hitpoint. Killing the Dragon gives you " "fire (at range 3), losing the hitpoint. Killing the Dragon "
"treasure.", "while still in the Dragon Chasms gives you treasure.",
"Drachen sind mächtige Monster. Sie sind langsam, aber böse, " "Drachen sind mächtige Monster. Sie sind langsam, aber böse, "
"und lieben es Wesen zu schikanieren, die noch langsamer sind als sie. " "und lieben es Wesen zu schikanieren, die noch langsamer sind als sie. "
@ -3525,8 +3526,8 @@ S("Galápagos is the land of Tortoises. "
S("%The1 scares %the2 a bit!", "%Der1 %1 ängstigt %den2 %a2 ein wenig!") S("%The1 scares %the2 a bit!", "%Der1 %1 ängstigt %den2 %a2 ein wenig!")
S("%The1 attacks your shell!", "%Der1 %1 attackiert deinen Panzer!") S("%The1 attacks your shell!", "%Der1 %1 attackiert deinen Panzer!")
S("Hyperstone Quest: collect at least 10 points in %the2", S("Hyperstone Quest: collect at least %3 points in %the2",
"Hyperstein-Herausforderung: sammle mindestens 10 Punkte %abl2") "Hyperstein-Herausforderung: sammle mindestens %3 Punkte %abl2")
S("animals killed: %1", "getötete Tiere: %1") S("animals killed: %1", "getötete Tiere: %1")
S("\n\nTortoises are not monsters! They are just annoyed. They do not count for your total kills.", S("\n\nTortoises are not monsters! They are just annoyed. They do not count for your total kills.",

View File

@ -248,7 +248,7 @@ S("You feel that you have enough treasure to access new lands!", "Masz wystarcza
S("Collect more treasures, there are still more lands waiting...", "Zbieraj skarby, nowe krainy czekają...") S("Collect more treasures, there are still more lands waiting...", "Zbieraj skarby, nowe krainy czekają...")
S("You feel that the stars are right, and you can access R'Lyeh!", "Gwiazdy są na miejscu, R'Lyeh czeka!") S("You feel that the stars are right, and you can access R'Lyeh!", "Gwiazdy są na miejscu, R'Lyeh czeka!")
S("Kill monsters and collect treasures, and you may get access to Hell...", "Zabijaj potwory, zdobywaj skarby, może trafisz do Piekła...") S("Kill monsters and collect treasures, and you may get access to Hell...", "Zabijaj potwory, zdobywaj skarby, może trafisz do Piekła...")
S("To access Hell, collect 10 treasures each of 9 kinds...", "By dostać się do Piekła, znajdź po 10 skarbów każdego z 9 rodzajów...") S("To access Hell, collect %1 treasures each of 9 kinds...", "By dostać się do Piekła, znajdź po %1 skarbów każdego z 9 rodzajów...")
S("Abandon all hope, the gates of Hell are opened!", "Porzuć wszelką nadzieję, bramy Piekła są otwarte!") S("Abandon all hope, the gates of Hell are opened!", "Porzuć wszelką nadzieję, bramy Piekła są otwarte!")
S("And the Orbs of Yendor await!", "I sfery Yendoru czekają!") S("And the Orbs of Yendor await!", "I sfery Yendoru czekają!")
S("You switch places with %the1.", "Zamieniasz się miejscami z %abl1.") S("You switch places with %the1.", "Zamieniasz się miejscami z %abl1.")
@ -339,10 +339,10 @@ S("GAME OVER", "KONIEC GRY")
S("Your score: %1", "Twój wynik: %1") S("Your score: %1", "Twój wynik: %1")
S("Enemies killed: %1", "Potwory pokonane: %1") S("Enemies killed: %1", "Potwory pokonane: %1")
S("Orbs of Yendor found: %1", "Znalezione Sfery Yendoru: %1") S("Orbs of Yendor found: %1", "Znalezione Sfery Yendoru: %1")
S("Collect 30 $$$ to access more worlds", "Znajdź 30 $$$, by iść do nowych krain") S("Collect %1 $$$ to access more worlds", "Znajdź %1 $$$, by iść do nowych krain")
S("Collect at least 10 treasures in each of 9 types to access Hell", "Znajdź po 10 skarbów w 9 typach, by się dostać do Piekła") S("Collect at least %1 treasures in each of 9 types to access Hell", "Znajdź po %1 skarbów w 9 typach, by się dostać do Piekła")
S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Znajdź 10 Czarciego Ziela, by znaleźć Sfery Yendoru") S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Znajdź 10 Czarciego Ziela, by znaleźć Sfery Yendoru")
S("Hyperstone Quest: collect at least 10 %1 in %the2", "Misja alternatywna: znajdź co najmniej 10 skarbów %abl2") S("Hyperstone Quest: collect at least %3 %1 in %the2", "Misja alternatywna: znajdź co najmniej %3 skarbów %abl2")
S("Hyperstone Quest completed!", "Misja alternatywna zakończona!") S("Hyperstone Quest completed!", "Misja alternatywna zakończona!")
S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Szukaj Sfer Yendoru w Piekle albo na Skrzyżowaniu!") S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Szukaj Sfer Yendoru w Piekle albo na Skrzyżowaniu!")
S("Unlock the Orb of Yendor!", "Otwórz Sferę Yendoru!") S("Unlock the Orb of Yendor!", "Otwórz Sferę Yendoru!")
@ -994,7 +994,7 @@ S("Periodic Editor", "Edytor okresowy")
// also translate this line: // also translate this line:
// "In the periodic editor, press 0-4 to switch walls in different ways\n", // "In the periodic editor, press 0-4 to switch walls in different ways\n",
S("Collect 60 $$$ to access even more lands", "Znajdź 60 $$$ by iść do kolejnych krain") S("Collect %1 $$$ to access even more lands", "Znajdź %1 $$$ by iść do kolejnych krain")
// Emerald Mine // Emerald Mine
// ------------ // ------------
@ -2500,8 +2500,8 @@ S("Accessible only from %the1 (until finished).\n", "Kraina dostępna tylko popr
S("Accessible only from %the1 or %the2.\n", "Kraina dostępna tylko poprzez %a1 i %a2.\n") S("Accessible only from %the1 or %the2.\n", "Kraina dostępna tylko poprzez %a1 i %a2.\n")
S("Kills required: %1.\n", "Wymagani pokonani przeciwnicy: %1.\n") S("Kills required: %1.\n", "Wymagani pokonani przeciwnicy: %1.\n")
S("Finished lands required: %1 (collect 10 treasure)\n", S("Finished lands required: %1 (collect %2 treasure)\n",
"Wymagane ukończone krainy: %1 (zdobądź 10 skarbów)\n") "Wymagane ukończone krainy: %1 (zdobądź %2 skarbów)\n")
S("Treasure required: %1 x %2.\n", "Wymagane skarby: %1 x %2.\n") S("Treasure required: %1 x %2.\n", "Wymagane skarby: %1 x %2.\n")
@ -3737,8 +3737,8 @@ S(
S("%The1 scares %the2 a bit!", "%1 troszkę przestraszy%ł1 %a2!") S("%The1 scares %the2 a bit!", "%1 troszkę przestraszy%ł1 %a2!")
S("%The1 attacks your shell!", "%1 zaatakowa%ł1 Twoją skorupę!") S("%The1 attacks your shell!", "%1 zaatakowa%ł1 Twoją skorupę!")
S("Hyperstone Quest: collect at least 10 points in %the2", S("Hyperstone Quest: collect at least %3 points in %the2",
"Misja Hiperkamień: zdobądź co najmniej 10 punktów %abl2") "Misja Hiperkamień: zdobądź co najmniej %3 punktów %abl2")
S("animals killed: %1", "zabitych zwierząt: %1") S("animals killed: %1", "zabitych zwierząt: %1")
S("\n\nTortoises are not monsters! They are just annoyed. They do not count for your total kills.", S("\n\nTortoises are not monsters! They are just annoyed. They do not count for your total kills.",
@ -4946,7 +4946,7 @@ N("Tortoise", GEN_M, "Żółw", "Żółwie", "Żółwia", "Żółwiem")
S("line patterns", "wzory linii") S("line patterns", "wzory linii")
S("1 turn", "1 kolejka") S("1 turn", "1 kolejka")
S("%1 turns", "kolejek: %1") S("%1 turns", "kolejek: %1")
S("items/kills mode", "tryb rzeczy/zabić") S("inventory/kill mode", "tryb rzeczy/zabić")
S("images", "obrazki") S("images", "obrazki")
S("letters", "literki") S("letters", "literki")
S("input", "sterowanie") S("input", "sterowanie")
@ -5442,4 +5442,22 @@ S(
#undef Orb #undef Orb
/*
// for 10.0
S("configure keys/joysticks", "konfiguracja klawiszy/joysticka")
S("Press F5 or 'o' to try again!", "Naciśnij F5 lub 'o' by spróbować jeszcze raz!")
S("peaceful mode", "tryb pokojowy")
S("inventory mode", "tryb inwentarza")
S("inventory", "sfery")
S("mirror what?", "co odbić?")
S("Which orb to use?", "Której Sfery użyć?")
S("Unlocked by: %1 in %2", "Odblokwane przez: %1 %abl2")
S(" (next at %1)", " (kolejny przy %1)")
S(" (next at %1 to %2)", " (kolejny przy %1 do %2)")
S("Number of uses left: %1", "Pozostało użyć: %1")
S("You mirror %the1.", "Odbijasz %a1.")
S("You need to stand next to a magic mirror or cloud to use %the1.",
"Musisz stać przy magicznym lustrze, by odbić %a1.")
S("Each orb type can be mirrored only once.", "Każdy typ sfery może być odbity tylko raz.")
*/

View File

@ -248,7 +248,7 @@ S("You feel that you have enough treasure to access new lands!", "Вы чувс
S("Collect more treasures, there are still more lands waiting...", "Собирайте больше сокровищ, ещё много земель Вас ждут...") S("Collect more treasures, there are still more lands waiting...", "Собирайте больше сокровищ, ещё много земель Вас ждут...")
S("You feel that the stars are right, and you can access R'Lyeh!", "Вы чувствуете, что звёзды правы, Вы можете открыть Р'Льех!") S("You feel that the stars are right, and you can access R'Lyeh!", "Вы чувствуете, что звёзды правы, Вы можете открыть Р'Льех!")
S("Kill monsters and collect treasures, and you may get access to Hell...", "Убивайте монстров и собирайте сокровища, и Вы сможете открыть Ад...") S("Kill monsters and collect treasures, and you may get access to Hell...", "Убивайте монстров и собирайте сокровища, и Вы сможете открыть Ад...")
S("To access Hell, collect 10 treasures each of 9 kinds...", "Чтобы открыть Ад, соберите по 10 сокровищ из 9 различных мест...") S("To access Hell, collect %1 treasures each of 9 kinds...", "Чтобы открыть Ад, соберите по %1 сокровищ из 9 различных мест...")
S("Abandon all hope, the gates of Hell are opened!", "Оставь надежду, врата Ада открылись!") S("Abandon all hope, the gates of Hell are opened!", "Оставь надежду, врата Ада открылись!")
S("And the Orbs of Yendor await!", "Шары Йендора ждут!") S("And the Orbs of Yendor await!", "Шары Йендора ждут!")
S("You switch places with %the1.", "Вы поменялись местами с %abl1.") S("You switch places with %the1.", "Вы поменялись местами с %abl1.")
@ -340,10 +340,10 @@ S("GAME OVER", "КОНЕЦ ИГРЫ")
S("Your score: %1", "Ваш счёт: %1") S("Your score: %1", "Ваш счёт: %1")
S("Enemies killed: %1", "Врагов убито: %1") S("Enemies killed: %1", "Врагов убито: %1")
S("Orbs of Yendor found: %1", "Собрано сфер Йендора: %1") S("Orbs of Yendor found: %1", "Собрано сфер Йендора: %1")
S("Collect 30 $$$ to access more worlds", "Соберите 30 $$$, чтобы открыть новые земли") S("Collect %1 $$$ to access more worlds", "Соберите %1 $$$, чтобы открыть новые земли")
S("Collect at least 10 treasures in each of 9 types to access Hell", "Соберите хотя бы по 10 сокровищ 9 разных типов, чтобы попасть в Ад") S("Collect at least %1 treasures in each of 9 types to access Hell", "Соберите хотя бы по %1 сокровищ 9 разных типов, чтобы попасть в Ад")
S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Соберите 10 адских ромашек, чтобы найти сферу Йендора") S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "Соберите 10 адских ромашек, чтобы найти сферу Йендора")
S("Hyperstone Quest: collect at least 10 %1 in %the2", "Миссия Гиперкамня: соберите 10 драгоценностей в %abl2") S("Hyperstone Quest: collect at least %3 %1 in %the2", "Миссия Гиперкамня: соберите %3 драгоценностей в %abl2")
S("Hyperstone Quest completed!", "Миссия Гиперкамня закончена!") S("Hyperstone Quest completed!", "Миссия Гиперкамня закончена!")
S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Ищите сферы Йендора в Аду и на Перекрёстке!") S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Ищите сферы Йендора в Аду и на Перекрёстке!")
S("Unlock the Orb of Yendor!", "Откройте сферу Йендора!") S("Unlock the Orb of Yendor!", "Откройте сферу Йендора!")
@ -978,7 +978,7 @@ S("Periodic Editor", "Периодический редактор")
// also translate this line: // also translate this line:
// "In the periodic editor, press 0-4 to switch walls in different ways\n", // "In the periodic editor, press 0-4 to switch walls in different ways\n",
S("Collect 60 $$$ to access even more lands", "Соберите 60 $$$, чтобы открыть новые земли") S("Collect %1 $$$ to access even more lands", "Соберите %1 $$$, чтобы открыть новые земли")
// Emerald Mine // Emerald Mine
// ------------ // ------------
@ -2169,6 +2169,18 @@ S("player 4 X", "игрок 4 X")
S("player 4 Y", "игрок 4 Y") S("player 4 Y", "игрок 4 Y")
S("player 4 go", "игрок 4 идёт") S("player 4 go", "игрок 4 идёт")
S("player 4 spin", "игрок 4 вертит") S("player 4 spin", "игрок 4 вертит")
S("player 5 X", "игрок 5 X")
S("player 5 Y", "игрок 5 Y")
S("player 5 go", "игрок 5 идёт")
S("player 5 spin", "игрок 5 вертит")
S("player 6 X", "игрок 6 X")
S("player 6 Y", "игрок 6 Y")
S("player 6 go", "игрок 6 идёт")
S("player 6 spin", "игрок 6 вертит")
S("player 7 X", "игрок 7 X")
S("player 7 Y", "игрок 7 Y")
S("player 7 go", "игрок 7 идёт")
S("player 7 spin", "игрок 7 вертит")
S("Joystick %1, axis %2", "Джойстик %1, ось %2") S("Joystick %1, axis %2", "Джойстик %1, ось %2")
S("one player", "один игрок") S("one player", "один игрок")
@ -2492,8 +2504,8 @@ S("Accessible only from %the1 (until finished).\n", "Доступно тольк
S("Accessible only from %the1 or %the2.\n", "Доступно только из %a1 и %a2.\n") S("Accessible only from %the1 or %the2.\n", "Доступно только из %a1 и %a2.\n")
S("Kills required: %1.\n", "УБийств нужно: %1 $$$.\n") S("Kills required: %1.\n", "УБийств нужно: %1 $$$.\n")
S("Finished lands required: %1 (collect 10 treasure)\n", S("Finished lands required: %1 (collect %2 treasure)\n",
"Земель окончено: %1 (собрано 10 сокровищ)\n") "Земель окончено: %1 (собрано %2 сокровищ)\n")
S("Treasure required: %1 x %2.\n", "Сокровищ собрано: %1 x %2.\n") S("Treasure required: %1 x %2.\n", "Сокровищ собрано: %1 x %2.\n")
@ -3864,8 +3876,8 @@ S(
S("%The1 scares %the2 a bit!", "%1 немного пугает %a2!") S("%The1 scares %the2 a bit!", "%1 немного пугает %a2!")
S("%The1 attacks your shell!", "%1 атакует вашу раковину!") S("%The1 attacks your shell!", "%1 атакует вашу раковину!")
S("Hyperstone Quest: collect at least 10 points in %the2", S("Hyperstone Quest: collect at least %3 points in %the2",
"Миссия Гиперкамней: собери не меньше 10 очков %abl2") "Миссия Гиперкамней: собери не меньше %3 очков %abl2")
S("animals killed: %1", "животных убито: %1") S("animals killed: %1", "животных убито: %1")
S("\n\nTortoises are not monsters! They are just annoyed. They do not count for your total kills.", S("\n\nTortoises are not monsters! They are just annoyed. They do not count for your total kills.",
@ -5091,7 +5103,7 @@ N("Tortoise", GEN_F, "Черепаха", "Черепахи", "Черепаху",
S("line patterns", "шаблоны линий") S("line patterns", "шаблоны линий")
S("1 turn", "1 ход") S("1 turn", "1 ход")
S("%1 turns", "ходов: %1") S("%1 turns", "ходов: %1")
S("items/kills mode", "режим предметов/убийств") S("inventory/kill mode", "режим предметов/убийств")
S("images", "изображения") S("images", "изображения")
S("letters", "буквы") S("letters", "буквы")
S("input", "ввод") S("input", "ввод")

View File

@ -229,7 +229,7 @@ S("You feel that you have enough treasure to access new lands!", "Yeni diyarlara
S("Collect more treasures, there are still more lands waiting...", "Daha fazla hazine topla, hâlâ seni bekleyen diyarlar var...") S("Collect more treasures, there are still more lands waiting...", "Daha fazla hazine topla, hâlâ seni bekleyen diyarlar var...")
S("You feel that the stars are right, and you can access R'Lyeh!", "Yıldızlar sana, R'Lyeh'e ulaşabileceğini söylüyor!") S("You feel that the stars are right, and you can access R'Lyeh!", "Yıldızlar sana, R'Lyeh'e ulaşabileceğini söylüyor!")
S("Kill monsters and collect treasures, and you may get access to Hell...", "Canavarlar öldür, hazineler topla ve belki Cehenneme erişebilirsin...") S("Kill monsters and collect treasures, and you may get access to Hell...", "Canavarlar öldür, hazineler topla ve belki Cehenneme erişebilirsin...")
S("To access Hell, collect 10 treasures each of 9 kinds...", "Cehenneme erişmek için her 9 hazine tipinden 10'ar tane toplamalısın...") S("To access Hell, collect %1 treasures each of 9 kinds...", "Cehenneme erişmek için her 9 hazine tipinden %1'ar tane toplamalısın...")
S("Abandon all hope, the gates of Hell are opened!", "Umutlar tükendi, Cehennemin kapılarııldı!") S("Abandon all hope, the gates of Hell are opened!", "Umutlar tükendi, Cehennemin kapılarııldı!")
S("And the Orbs of Yendor await!", "Yendorun Küresi seni bekliyor!") S("And the Orbs of Yendor await!", "Yendorun Küresi seni bekliyor!")
S("You switch places with %the1.", "%abl1 yer değiştirdin.") S("You switch places with %the1.", "%abl1 yer değiştirdin.")
@ -320,11 +320,11 @@ S("GAME OVER", "OYUN BİTTİ")
S("Your score: %1", "Puanın: %1") S("Your score: %1", "Puanın: %1")
S("Enemies killed: %1", "Öldürülen Düşmanlar: %1") S("Enemies killed: %1", "Öldürülen Düşmanlar: %1")
S("Orbs of Yendor found: %1", "Bulunan Yendor Küresi sayısı: %1") S("Orbs of Yendor found: %1", "Bulunan Yendor Küresi sayısı: %1")
S("Collect 30 $$$ to access more worlds", "30 $$$ toplayarak başka dünyalara eriş") S("Collect %1 $$$ to access more worlds", "%1 $$$ toplayarak başka dünyalara eriş")
// S("Collect 60 $$$ to access R'Lyeh and Dry Forest", "60 $$$ toplayarak R'Lyeh ve Kara Ormana eriş.") // S("Collect %1 $$$ to access R'Lyeh and Dry Forest", "60 $$$ toplayarak R'Lyeh ve Kara Ormana eriş.")
S("Collect at least 10 treasures in each of 9 types to access Hell", "9 hazine çeşidinin hepsinden 10'ar tane toplayarak Cehenneme erişebilirsin.") S("Collect at least %1 treasures in each of 9 types to access Hell", "9 hazine çeşidinin hepsinden %1'ar tane toplayarak Cehenneme erişebilirsin.")
S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "10 Şeytan Papatyası toplayarak Yendorun Kürelerini bulabilirsin.") S("Collect at least 10 Demon Daisies to find the Orbs of Yendor", "10 Şeytan Papatyası toplayarak Yendorun Kürelerini bulabilirsin.")
S("Hyperstone Quest: collect at least 10 %1 in %the2", "Aşkıntaş Görevi: %2'de en az 10 hazine topla.") S("Hyperstone Quest: collect at least %3 %1 in %the2", "Aşkıntaş Görevi: %2'de en az %3 hazine topla.")
S("Hyperstone Quest completed!", "Aşkıntaş görevi tamamlandı.") S("Hyperstone Quest completed!", "Aşkıntaş görevi tamamlandı.")
S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Yendorun Küreleri için Cehennemi yahut Arayolları ara!") S("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Yendorun Küreleri için Cehennemi yahut Arayolları ara!")
S("Unlock the Orb of Yendor!", "Yendor'un küresinin kilidini aç!") S("Unlock the Orb of Yendor!", "Yendor'un küresinin kilidini aç!")
@ -921,7 +921,7 @@ S("Periodic Editor", "Periyodik Editör")
// "In the periodic editor, press 0-4 to switch walls in different ways\n", // "In the periodic editor, press 0-4 to switch walls in different ways\n",
// "Periyodik editörde, duvarları farklı şekillerde seçmek için 0-4'e basın.\n" // "Periyodik editörde, duvarları farklı şekillerde seçmek için 0-4'e basın.\n"
S("Collect 60 $$$ to access even more lands", "Daha da fazla diyara ulaşmak için 60 $$$ toplayın.") S("Collect %1 $$$ to access even more lands", "Daha da fazla diyara ulaşmak için %1 $$$ toplayın.")
// Emerald Mine // Emerald Mine
// ------------ // ------------
@ -2382,8 +2382,8 @@ S("Accessible only from %the1 (until finished).\n", "Sadece %a1 erişilebilir. %
S("Accessible only from %the1 or %the2.\n", "Sadece %a1 veya %a2 erişilebilir.\n") S("Accessible only from %the1 or %the2.\n", "Sadece %a1 veya %a2 erişilebilir.\n")
S("Kills required: %1.\n", "Gereken leşler: %1 $$$.\n") S("Kills required: %1.\n", "Gereken leşler: %1 $$$.\n")
S("Finished lands required: %1 (collect 10 treasure)\n", S("Finished lands required: %1 (collect %2 treasure)\n",
"Gereken bitirilmiş diyarlar: %1 (10 hazine toplananlar)\n") "Gereken bitirilmiş diyarlar: %1 (%2 hazine toplananlar)\n")
S("Treasure required: %1 x %2.\n", "Gereken hazine: %1 tane %2.\n") S("Treasure required: %1 x %2.\n", "Gereken hazine: %1 tane %2.\n")

View File

@ -427,6 +427,8 @@ namespace mapeditor {
int subscreen; //0=normal, 1=config, 2=patterns, 3=predesigned int subscreen; //0=normal, 1=config, 2=patterns, 3=predesigned
cell *drawcell;
#ifndef NOEDIT #ifndef NOEDIT
int paintwhat = 0; int paintwhat = 0;
int painttype = 0; int painttype = 0;
@ -437,8 +439,6 @@ namespace mapeditor {
bool symRotation, sym01, sym02, sym03; bool symRotation, sym01, sym02, sym03;
int whichpart; int whichpart;
cell *drawcell;
const char *mapeditorhelp = const char *mapeditorhelp =
"This mode allows you to edit the map.\n\n" "This mode allows you to edit the map.\n\n"
"NOTE: Use at your own risk. Combinations which never " "NOTE: Use at your own risk. Combinations which never "
@ -547,7 +547,7 @@ namespace mapeditor {
bool editext = false; bool editext = false;
#define CDIR 0xC0C0C0 #define CDIR 0xC0C0C0
#define CFILE 0xFFFFFF #define CFILE forecolor
bool filecmp(const pair<string,int> &f1, const pair<string,int> &f2) { bool filecmp(const pair<string,int> &f1, const pair<string,int> &f2) {
if(f1.first == "../") return true; if(f1.first == "../") return true;
@ -559,7 +559,7 @@ namespace mapeditor {
void drawFileDialog() { void drawFileDialog() {
displayfr(vid.xres/2, 30 + vid.fsize, 2, vid.fsize, displayfr(vid.xres/2, 30 + vid.fsize, 2, vid.fsize,
XLAT(cmode == emDraw ? "pics to save/load:" : "level to save/load:"), 0xFFFFFF, 8); XLAT(cmode == emDraw ? "pics to save/load:" : "level to save/load:"), forecolor, 8);
string cfile = cmode == emDraw ? picfile : levelfile; string cfile = cmode == emDraw ? picfile : levelfile;
displayfr(vid.xres/2, 34 + vid.fsize * 2, 2, vid.fsize, displayfr(vid.xres/2, 34 + vid.fsize * 2, 2, vid.fsize,
@ -748,7 +748,7 @@ namespace mapeditor {
getcstat = '-'; getcstat = '-';
displayfr(8, 8 + fs, 2, vid.fsize, paintwhat_str, 0xFFFFFF, 0); displayfr(8, 8 + fs, 2, vid.fsize, paintwhat_str, forecolor, 0);
displayfr(8, 8+fs*2, 2, vid.fsize, XLAT("use at your own risk!"), 0x800000, 0); displayfr(8, 8+fs*2, 2, vid.fsize, XLAT("use at your own risk!"), 0x800000, 0);
displayButton(8, 8+fs*4, XLAT("0-9 = radius (%1)", its(radius)), ('0' + (radius+1)%10), 0); displayButton(8, 8+fs*4, XLAT("0-9 = radius (%1)", its(radius)), ('0' + (radius+1)%10), 0);
@ -1931,7 +1931,7 @@ namespace mapeditor {
hyperpoint Plast = V * spin(-2*M_PI/ds.rots) * (ds.sym?Mirror*ds.list[0]:ds.list[size(ds.list)-1]); hyperpoint Plast = V * spin(-2*M_PI/ds.rots) * (ds.sym?Mirror*ds.list[0]:ds.list[size(ds.list)-1]);
int state = 0; int state = 0;
int gstate = 0; int gstate = 0;
double dist2; double dist2 = 0;
hyperpoint lpsm; hyperpoint lpsm;
for(int a=0; a<ds.rots; a++) for(int a=0; a<ds.rots; a++)
@ -2029,6 +2029,7 @@ namespace linepatterns {
{patTrihepta, "triheptagonal tesselation", (int) 0x0000C000}, {patTrihepta, "triheptagonal tesselation", (int) 0x0000C000},
{patNormal, "normal tesselation", (int) 0x0000C000}, {patNormal, "normal tesselation", (int) 0x0000C000},
{patBigTriangles, "big triangular grid", (int) 0x00606000}, {patBigTriangles, "big triangular grid", (int) 0x00606000},
{patBigRings, "big triangles: rings", (int) 0x0000C000},
{patTree, "underlying tree", (int) 0x00d0d000}, {patTree, "underlying tree", (int) 0x00d0d000},
{patAltTree, "circle/horocycle tree", (int) 0xd000d000}, {patAltTree, "circle/horocycle tree", (int) 0xd000d000},
@ -2061,16 +2062,7 @@ namespace linepatterns {
if(patterns[k].id == id) patterns[k].color ^= col; if(patterns[k].id == id) patterns[k].color ^= col;
} }
void drawAll() { void drawPattern(int id, int col, cell *c, const transmatrix& V) {
if(any()) for(map<cell*, transmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) {
cell *c = it->first;
transmatrix& V = it->second;
for(int k=0; patterns[k].lpname; k++) {
int col = patterns[k].color;
if(!(col & 255)) continue;
int id = patterns[k].id;
switch(id) { switch(id) {
@ -2135,7 +2127,7 @@ namespace linepatterns {
case patTriNet: case patTriNet:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2)) if(celldist(c) != celldist(c2)) { forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2)) if(celldist(c) != celldist(c2)) {
queueline(it->second*C0, gmatrix[c2]*C0, queueline(tC0(V), gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2), darkena(backcolor ^ 0xFFFFFF, 0, col2),
2); 2);
} }
@ -2143,21 +2135,21 @@ namespace linepatterns {
case patTriRings: case patTriRings:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && celldist(c) == celldist(c2)) forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && celldist(c) == celldist(c2))
queueline(it->second*C0, gmatrix[c2]*C0, queueline(tC0(V), gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2), darkena(backcolor ^ 0xFFFFFF, 0, col2),
2); 2);
break; break;
case patHepta: case patHepta:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) == pseudohept(c2)) forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) == pseudohept(c2))
queueline(it->second*C0, gmatrix[c2]*C0, queueline(tC0(V), gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2), darkena(backcolor ^ 0xFFFFFF, 0, col2),
2); 2);
break; break;
case patRhomb: case patRhomb:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) != pseudohept(c2)) forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) != pseudohept(c2))
queueline(it->second*C0, gmatrix[c2]*C0, queueline(tC0(V), gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2), darkena(backcolor ^ 0xFFFFFF, 0, col2),
2); 2);
break; break;
@ -2185,6 +2177,14 @@ namespace linepatterns {
case patBigTriangles: { case patBigTriangles: {
if(pseudohept(c) && !euclid) for(int i=0; i<S7; i++) if(pseudohept(c) && !euclid) for(int i=0; i<S7; i++)
if(c->master->move[i] < c->master) { if(c->master->move[i] < c->master) {
queueline(tC0(V), V*xspinpush0((purehepta?M_PI:0) -2*M_PI*i/S7, tessf), col1, 2);
}
break;
}
case patBigRings: {
if(pseudohept(c) && !euclid) for(int i=0; i<S7; i++)
if(c->master->move[i] && c->master->move[i] < c->master && c->master->move[i]->dm4 == c->master->dm4) {
cell *c2 = c->master->move[i]->c7; cell *c2 = c->master->move[i]->c7;
queueline(tC0(V), V*xspinpush0((purehepta?M_PI:0) -2*M_PI*i/S7, tessf), col2, 2); queueline(tC0(V), V*xspinpush0((purehepta?M_PI:0) -2*M_PI*i/S7, tessf), col2, 2);
} }
@ -2230,6 +2230,20 @@ namespace linepatterns {
} }
} }
} }
void drawAll() {
if(any()) for(map<cell*, transmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) {
cell *c = it->first;
transmatrix& V = it->second;
for(int k=0; patterns[k].lpname; k++) {
int col = patterns[k].color;
if(!(col & 255)) continue;
int id = patterns[k].id;
drawPattern(id, col, c, V);
}
} }
} }
#undef col1 #undef col1

690
menus.cpp
View File

@ -8,6 +8,13 @@
ld whatever = 0; ld whatever = 0;
void gotoHelp(const string& h, emtype c = cmode) {
help = h;
if(c != emHelp) lastmode = c;
cmode = emHelp;
printf("goto help, back = %d\n", c);
}
void showOverview() { void showOverview() {
DEBB(DF_GRAPH, (debugfile,"show overview\n")); DEBB(DF_GRAPH, (debugfile,"show overview\n"));
mouseovers = XLAT("world overview"); mouseovers = XLAT("world overview");
@ -48,7 +55,7 @@ void showOverview() {
if(landUnlocked(l)) col = linf[l].color; else col = 0x404040; if(landUnlocked(l)) col = linf[l].color; else col = 0x404040;
if(chaosmode && noChaos(l)) col = 0x400000; if(chaosmode && noChaos(l)) col = 0x400000;
if(l == curland) if(l == curland)
displayfrZ(1, i0, 1, vf-4, "*", 0xFFFFFF, 0); displayfrZ(1, i0, 1, vf-4, "*", forecolor, 0);
if(displayfrZ(xr*1, i0, 1, vf-4, XLAT1(linf[l].name), col, 0)) if(displayfrZ(xr*1, i0, 1, vf-4, XLAT1(linf[l].name), col, 0))
getcstat = 1000 + l; getcstat = 1000 + l;
eItem it = treasureType(l); eItem it = treasureType(l);
@ -127,10 +134,7 @@ void handleOverview(int sym, int uni) {
canmove = true; canmove = true;
if(princ) fullcenter(); if(princ) fullcenter();
} }
else { else gotoHelp(generateHelpForLand(eLand(umod)));
lastmode = cmode;
cmode = emHelp; help = generateHelpForLand(eLand(umod));
}
} }
else if(udiv == 2 && umod < ittypes) { else if(udiv == 2 && umod < ittypes) {
if(cheater && !hiliteclick) { if(cheater && !hiliteclick) {
@ -144,19 +148,10 @@ void handleOverview(int sym, int uni) {
if(hardcore) canmove = true; if(hardcore) canmove = true;
else checkmove(); else checkmove();
} }
else { else gotoHelp(generateHelpForItem(eItem(umod)));
lastmode = cmode;
cmode = emHelp; help = generateHelpForItem(eItem(umod));
} }
} else if(udiv == 3 && umod < walltypes) gotoHelp(generateHelpForWall(eWall(umod)));
else if(udiv == 3 && umod < walltypes) { else if(uni == SDLK_F1) gotoHelp(
lastmode = cmode;
cmode = emHelp; help = generateHelpForWall(eWall(umod));
}
else if(uni == SDLK_F1) {
lastmode = cmode;
cmode = emHelp;
help =
"This displays all lands available in the game. " "This displays all lands available in the game. "
"Bonus lands (available only in separate challenges) " "Bonus lands (available only in separate challenges) "
"are not included. Lands written in dark have to be " "are not included. Lands written in dark have to be "
@ -165,8 +160,8 @@ void handleOverview(int sym, int uni) {
"land or item to get information about it. Hover over " "land or item to get information about it. Hover over "
"an Orb to know its relation to the current land. " "an Orb to know its relation to the current land. "
"Cheaters can click to move between lands, and use the " "Cheaters can click to move between lands, and use the "
"mousewheel to gain or lose treasures and orbs quickly (Ctrl = precise, Shift = reverse)."; "mousewheel to gain or lose treasures and orbs quickly (Ctrl = precise, Shift = reverse)."
} );
else if(dialog::handlePageButtons(uni)) ; else if(dialog::handlePageButtons(uni)) ;
else if(doexiton(sym, uni)) cmode = emNormal; else if(doexiton(sym, uni)) cmode = emNormal;
} }
@ -188,7 +183,10 @@ void showMainMenu() {
dialog::init(XLAT("HyperRogue %1", VER), 0xC00000, 200, 100); dialog::init(XLAT("HyperRogue %1", VER), 0xC00000, 200, 100);
dialog::addItem(XLAT("basic configuration"), 'b'); dialog::addItem(XLAT("basic configuration"), 'b');
dialog::addItem(XLAT("advanced configuration"), 'a'); dialog::addItem(XLAT("graphics configuration"), 'g');
dialog::addItem(XLAT("special display modes"), 'd');
dialog::addItem(XLAT("special game modes"), 'm');
#ifndef NOSAVE #ifndef NOSAVE
dialog::addItem(XLAT("local highscores"), 't'); dialog::addItem(XLAT("local highscores"), 't');
#endif #endif
@ -197,7 +195,6 @@ void showMainMenu() {
dialog::addItem(XLAT("cheats"), 'c'); dialog::addItem(XLAT("cheats"), 'c');
else dialog::addBreak(100); else dialog::addBreak(100);
dialog::addItem(XLAT("restart game"), 'r'); dialog::lastItem().keycaption += " / F5"; dialog::addItem(XLAT("restart game"), 'r'); dialog::lastItem().keycaption += " / F5";
dialog::addItem(XLAT("special game modes"), 'm');
string q; string q;
#ifdef MOBILE #ifdef MOBILE
@ -215,10 +212,13 @@ void showMainMenu() {
dialog::addItem(XLAT(q), SDLK_ESCAPE); dialog::addItem(XLAT(q), SDLK_ESCAPE);
dialog::addItem(XLAT("world overview"), 'o'); dialog::addItem(XLAT("world overview"), 'o');
if(inv::on)
dialog::addItem(XLAT("inventory"), 'i');
if(checkHalloweenDate()) dialog::addItem(XLAT("Halloween mini-game"), 'y'-96); if(checkHalloweenDate()) dialog::addItem(XLAT("Halloween mini-game"), 'y'-96);
#ifdef ROGUEVIZ #ifdef ROGUEVIZ
dialog::addItem(XLAT("rogueviz menu"), 'g'); dialog::addItem(XLAT("rogueviz menu"), 'u');
#endif #endif
#ifdef MOBILE #ifdef MOBILE
@ -241,14 +241,12 @@ void showMainMenu() {
void handleMenuKey(int sym, int uni) { void handleMenuKey(int sym, int uni) {
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);
if(sym == SDLK_F1 || sym == 'h') { if(sym == SDLK_F1 || sym == 'h') gotoHelp(help);
lastmode = cmode;
cmode = emHelp;
}
else if(sym == 'c' && cheater) else if(sym == 'c' && cheater)
cmode = emCheatMenu; cmode = emCheatMenu;
else if(sym == 'b') cmode = emVisual1; else if(sym == 'b') cmode = emBasicConfig;
else if(sym == 'a') cmode = emVisual2; else if(sym == 'g') cmode = emGraphConfig;
else if(sym == 'd') cmode = emDisplayMode;
else if(sym == 'm') cmode = emChangeMode; else if(sym == 'm') cmode = emChangeMode;
#ifndef NOSAVE #ifndef NOSAVE
else if(sym == 't') loadScores(); else if(sym == 't') loadScores();
@ -278,6 +276,10 @@ void handleMenuKey(int sym, int uni) {
clearMessages(); clearMessages();
cmode = emOverview; cmode = emOverview;
} }
else if(sym == 'i') {
clearMessages();
cmode = emInventory;
}
else if(sym == SDLK_ESCAPE) { else if(sym == SDLK_ESCAPE) {
cmode = emQuit; cmode = emQuit;
achievement_final(false); achievement_final(false);
@ -291,7 +293,7 @@ void handleMenuKey(int sym, int uni) {
#endif #endif
#endif #endif
#ifdef ROGUEVIZ #ifdef ROGUEVIZ
else if(uni == 'g') cmode = emRogueviz; else if(uni == 'u') cmode = emRogueviz;
#endif #endif
else if(doexiton(sym, uni)) { else if(doexiton(sym, uni)) {
cmode = emNormal; cmode = emNormal;
@ -299,91 +301,93 @@ void handleMenuKey(int sym, int uni) {
} }
} }
void showVisual1() { void showAllConfig() {
dialog::init(XLAT("basic configuration")); dialog::addBreak(50);
dialog::addItem(XLAT("exit configuration"), 'v');
#ifndef MOBILE #ifndef NOCONFIG
dialog::addSelItem(XLAT("video resolution"), its(vid.xres) + "x"+its(vid.yres), 0); dialog::addItem(XLAT("save the current config"), 's');
#endif #endif
}
void handleAllConfig(int sym, int uni) {
if(sym == SDLK_F1 || uni == 'h') gotoHelp(help);
if(uni == 'v') cmode = emMenu;
if(sym == SDLK_ESCAPE) cmode = emNormal;
#ifndef NOCONFIG
if(uni == 's') saveConfig();
#endif
}
void showGraphConfig() {
dialog::init(XLAT("graphics configuration"));
#ifndef ONEGRAPH
#ifdef GL
dialog::addBoolItem(XLAT("openGL mode"), vid.usingGL, 'o');
#endif
#endif
if(!vid.usingGL)
dialog::addBoolItem(XLAT("anti-aliasing"), vid.antialias & AA_NOGL, 'O');
if(vid.usingGL)
dialog::addSelItem(XLAT("anti-aliasing"),
(vid.antialias & AA_POLY) ? "polygons" :
(vid.antialias & AA_LINES) ? "lines" :
"NO", 'O');
if(vid.usingGL) {
dialog::addSelItem(XLAT("line width"), fts(vid.linewidth), 'w');
// dialog::addBoolItem(XLAT("finer lines at the boundary"), vid.antialias & AA_LINEWIDTH, 'b');
}
#ifndef MOBWEB
dialog::addSelItem(XLAT("framerate limit"), its(vid.framelimit), 'l');
#endif
#ifndef IOS #ifndef IOS
dialog::addBoolItem(XLAT("fullscreen mode"), (vid.full), 'f'); dialog::addBoolItem(XLAT("fullscreen mode"), (vid.full), 'f');
#endif #endif
dialog::addSelItem(XLAT("scrolling speed"), fts(vid.sspeed), 'a');
dialog::addSelItem(XLAT("movement animation speed"), fts(vid.mspeed), 'r');
dialog::addSelItem(XLAT("projection"), fts(vid.alpha), 'p');
dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z');
#ifdef LOCAL dialog::addSelItem(XLAT("scrolling speed"), fts(vid.sspeed), 'a');
dialog::addSelItem(XLAT("movement animation speed"), fts(vid.mspeed), 'm');
dialog::addBoolItem(XLAT("extra graphical effects"), (vid.particles), 'u');
#ifdef WHATEVER
dialog::addSelItem(XLAT("whatever"), fts(whatever), 'j'); dialog::addSelItem(XLAT("whatever"), fts(whatever), 'j');
#endif #endif
const char *wdmodes[6] = {"ASCII", "black", "plain", "Escher", "plain/3D", "Escher/3D"};
const char *mdmodes[6] = {"ASCII", "items only", "items and monsters", "high contrast",
"3D", "high contrast/3D"};
const char *glyphsortnames[6] = { const char *glyphsortnames[6] = {
"first on top", "first on bottom", "first on top", "first on bottom",
"last on top", "last on bottom", "last on top", "last on bottom",
"by land", "by number" "by land", "by number"
}; };
const char *glyphmodenames[3] = {"letters", "auto", "images"};
dialog::addSelItem(XLAT("items/kills mode"), XLAT(vid.graphglyph ? "images" : "letters"), 'd');
dialog::addBoolItem(XLAT("mark heptagons"), (vid.darkhepta), '7');
dialog::addBoolItem(XLAT("draw the grid"), (vid.grid), '6');
dialog::addBoolItem(XLAT("extra graphical effects"), (vid.particles), 'u');
dialog::addSelItem(XLAT("wall display mode"), XLAT(wdmodes[vid.wallmode]), 'w');
dialog::addSelItem(XLAT("monster display mode"), XLAT(mdmodes[vid.monmode]), 'm');
const char *axmodes[5] = {"OFF", "auto", "light", "heavy", "arrows"};
dialog::addSelItem(XLAT("help for keyboard users"), XLAT(axmodes[vid.axes]), 'c');
#ifndef NOAUDIO
dialog::addSelItem(XLAT("background music volume"), its(musicvolume), 'b');
dialog::addSelItem(XLAT("sound effects volume"), its(effvolume), 'e');
#endif
#ifndef NOTRANS
dialog::addSelItem(XLAT("language"), XLAT("EN"), 'l');
#endif
dialog::addSelItem(XLAT("player character"), numplayers() > 1 ? "" : csname(vid.cs), 'g');
dialog::addSelItem(XLAT("inventory/kill sorting"), XLAT(glyphsortnames[glyphsortorder]), 'k'); dialog::addSelItem(XLAT("inventory/kill sorting"), XLAT(glyphsortnames[glyphsortorder]), 'k');
dialog::addBreak(50); dialog::addSelItem(XLAT("inventory/kill mode"), XLAT(glyphmodenames[vid.graphglyph]), 'd');
dialog::addItem(XLAT("exit configuration"), 'v');
#ifndef NOCONFIG #ifdef MOBILE
dialog::addItem(XLAT("save the current config"), 's'); dialog::addSelItem(XLAT("font scale"), its(fontscale), 'b');
#endif #endif
if(lang() != 0) { dialog::addSelItem(XLAT("sight range"), its(sightrange), 'r');
string tw = "";
string s = XLAT("TRANSLATIONWARNING");
if(s != "" && s != "TRANSLATIONWARNING") tw += s;
s = XLAT("TRANSLATIONWARNING2");
if(s != "" && s != "TRANSLATIONWARNING2") { if(tw != "") tw += " "; tw += s; }
if(tw != "") {
dialog::addBreak(50);
dialog::addHelp(tw);
dialog::lastItem().color = 0xFF0000;
}
}
#ifdef MOBILE
dialog::addSelItem(XLAT("compass size"), its(vid.mobilecompasssize), 'c');
#endif
dialog::addSelItem(XLAT("aura brightness"), its(vid.aurastr), 'z');
dialog::addSelItem(XLAT("aura smoothening factor"), its(vid.aurasmoothen), 'x');
showAllConfig();
dialog::display(); dialog::display();
} }
void projectionDialog() {
geom3::tc_alpha = ticks;
dialog::editNumber(vid.alpha, -5, 5, .1, 1,
XLAT("projection"),
XLAT("HyperRogue uses the Minkowski hyperboloid model internally. "
"Klein and Poincaré models can be obtained by perspective, "
"and the Gans model is obtained by orthogonal projection. "
// "This parameter specifies the distance from the hyperboloid center "
// "to the eye. "
"See also the conformal mode (in the special modes menu) "
"for more models."));
dialog::sidedialog = true;
}
void switchFullscreen() { void switchFullscreen() {
vid.full = !vid.full; vid.full = !vid.full;
#ifdef ANDROID #ifdef ANDROID
@ -417,34 +421,15 @@ void switchGL() {
#endif #endif
} }
void switchHardcore() { void handleGraphConfig(int sym, int uni) {
if(hardcore && !canmove) {
restartGame();
hardcore = false;
cmode = emNormal;
}
else if(hardcore && canmove) { hardcore = false; }
else { hardcore = true; canmove = true; hardcoreAt = turncount; }
if(hardcore)
addMessage("One wrong move, and it is game over!");
else
addMessage("Not so hardcore?");
if(pureHardcore()) cmode = emNormal;
}
void handleVisual1(int sym, int uni) {
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);
if(uni == 'O') uni = 'o', shiftmul = -1;
char xuni = uni | 96; char xuni = uni | 96;
if(uni >= 32 && uni < 64) xuni = uni;
if(xuni == 'p') projectionDialog();
if(xuni == '6') vid.grid = !vid.grid;
if(xuni == 'u') vid.particles = !vid.particles; if(xuni == 'u') vid.particles = !vid.particles;
if(xuni == 'd') vid.graphglyph = (1+vid.graphglyph)%3;
if(xuni == 'd') vid.graphglyph = !vid.graphglyph;
if(xuni == 'j') { if(xuni == 'j') {
dialog::editNumber(whatever, -10, 10, 1, 0, XLAT("whatever"), dialog::editNumber(whatever, -10, 10, 1, 0, XLAT("whatever"),
@ -452,36 +437,126 @@ void handleVisual1(int sym, int uni) {
dialog::sidedialog = true; dialog::sidedialog = true;
} }
if(xuni == 'z') {
dialog::editNumber(vid.scale, .001, 1000, .1, 1, XLAT("scale factor"),
XLAT("Scale the displayed model."));
dialog::scaleLog();
dialog::sidedialog = true;
}
if(xuni == 'a') dialog::editNumber(vid.sspeed, -5, 5, 1, 0, if(xuni == 'a') dialog::editNumber(vid.sspeed, -5, 5, 1, 0,
XLAT("scrolling speed"), XLAT("scrolling speed"),
XLAT("+5 = center instantly, -5 = do not center the map")); XLAT("+5 = center instantly, -5 = do not center the map"));
if(xuni == 'r') dialog::editNumber(vid.mspeed, -5, 5, 1, 0, if(xuni == 'm') dialog::editNumber(vid.mspeed, -5, 5, 1, 0,
XLAT("movement animation speed"), XLAT("movement animation speed"),
XLAT("+5 = move instantly")); XLAT("+5 = move instantly"));
if(xuni == 'r') {
dialog::editNumber(sightrange, 4, cheater ? 10 : 7, 1, 7, XLAT("sight range"),
XLAT("Roughly 42% cells are on the edge of your sight range. Reducing "
"the sight range makes HyperRogue work faster, but also makes "
"the game effectively harder."));
dialog::sidedialog = true;
}
if(xuni == 'k') { if(xuni == 'k') {
glyphsortorder = eGlyphsortorder((glyphsortorder+6+(shiftmul>0?1:-1)) % gsoMAX); glyphsortorder = eGlyphsortorder((glyphsortorder+6+(shiftmul>0?1:-1)) % gsoMAX);
} }
if(xuni == 'f') switchFullscreen(); if(xuni == 'f') switchFullscreen();
if(xuni == 'v') cmode = emNormal; #ifndef ONEGRAPH
if(sym == SDLK_F2) cmode = emVisual2; if(xuni == 'o' && shiftmul > 0) switchGL();
#ifndef NOCONFIG
if(xuni == 's') saveConfig();
#endif #endif
if(xuni == '7') { vid.darkhepta = !vid.darkhepta; } if(xuni == 'o' && shiftmul < 0) {
if(xuni == 'w') { vid.wallmode += 60 + (shiftmul > 0 ? 1 : -1); vid.wallmode %= 6; } if(!vid.usingGL)
if(xuni == 'm') { vid.monmode += 60 + (shiftmul > 0 ? 1 : -1); vid.monmode %= 6; } vid.antialias ^= AA_NOGL | AA_FONT;
else if(vid.antialias & AA_POLY)
vid.antialias ^= AA_POLY | AA_LINES;
else if(vid.antialias & AA_LINES)
vid.antialias |= AA_POLY;
else
vid.antialias |= AA_LINES;
}
// if(xuni == 'b') vid.antialias ^= AA_LINEWIDTH;
if(xuni == 'w' && vid.usingGL)
dialog::editNumber(vid.linewidth, 0, 10, 0.1, 1, XLAT("line width"), "");
if(xuni == 'c')
dialog::editNumber(vid.mobilecompasssize, 0, 100, 10, 20, XLAT("compass size"), "");
if(xuni == 'l')
dialog::editNumber(vid.framelimit, 5, 300, 10, 300, XLAT("framerate limit"), "");
#ifdef MOBILE
if(xuni =='b')
dialog::editNumber(fontscale, 0, 400, 10, 100, XLAT("font scale"), "");
#endif
if(xuni =='z')
dialog::editNumber(vid.aurastr, 0, 256, 10, 128, XLAT("aura brightness"), "");
else if(xuni =='x')
dialog::editNumber(vid.aurasmoothen, 1, 180, 1, 5, XLAT("aura smoothening factor"), "");
handleAllConfig(sym, xuni);
}
void showBasicConfig() {
const char *axmodes[5] = {"OFF", "auto", "light", "heavy", "arrows"};
dialog::init(XLAT("basic configuration"));
#ifndef NOTRANS
dialog::addSelItem(XLAT("language"), XLAT("EN"), 'l');
#endif
dialog::addSelItem(XLAT("player character"), numplayers() > 1 ? "" : csname(vid.cs), 'g');
#ifndef NOAUDIO
dialog::addSelItem(XLAT("background music volume"), its(musicvolume), 'b');
dialog::addSelItem(XLAT("sound effects volume"), its(effvolume), 'e');
#endif
// input:
dialog::addSelItem(XLAT("help for keyboard users"), XLAT(axmodes[vid.axes]), 'c');
dialog::addBoolItem(XLAT("reverse pointer control"), (revcontrol), 'r');
dialog::addBoolItem(XLAT("draw circle around the target"), (vid.drawmousecircle), 'd');
dialog::addSelItem(XLAT("message flash time"), its(vid.flashtime), 't');
#ifdef MOBILE
dialog::addBoolItem(XLAT("targetting ranged Orbs long-click only"), (vid.shifttarget&2), 'i');
#else
dialog::addBoolItem(XLAT("targetting ranged Orbs Shift+click only"), (vid.shifttarget&1), 'i');
#endif
#ifdef STEAM
dialog::addBoolItem(XLAT("send scores to Steam leaderboards"), (vid.steamscore&1), 'l');
#endif
#ifndef MOBILE
dialog::addSelItem(XLAT("configure keys/joysticks"), "", 'p');
#endif
showAllConfig();
if(lang() != 0) {
string tw = "";
string s = XLAT("TRANSLATIONWARNING");
if(s != "" && s != "TRANSLATIONWARNING") tw += s;
s = XLAT("TRANSLATIONWARNING2");
if(s != "" && s != "TRANSLATIONWARNING2") { if(tw != "") tw += " "; tw += s; }
if(tw != "") {
dialog::addBreak(50);
dialog::addHelp(tw);
dialog::lastItem().color = 0xFF0000;
}
}
dialog::display();
}
void handleBasicConfig(int sym, int uni) {
dialog::handleNavigation(sym, uni);
char xuni = uni | 96;
if(uni >= 32 && uni < 64) xuni = uni;
if(xuni == 'c') { vid.axes += 60 + (shiftmul > 0 ? 1 : -1); vid.axes %= 5; } if(xuni == 'c') { vid.axes += 60 + (shiftmul > 0 ? 1 : -1); vid.axes %= 5; }
#ifndef NOAUDIO #ifndef NOAUDIO
if(xuni == 'b') { if(xuni == 'b') {
@ -507,10 +582,26 @@ void handleVisual1(int sym, int uni) {
if(xuni == 'g') cmode = emCustomizeChar; if(xuni == 'g') cmode = emCustomizeChar;
#ifdef LOCAL #ifndef MOBILE
extern void process_local(int); if(xuni == 'p') {
process_local(sym); cmode = emShmupConfig;
multi::shmupcfg = shmup::on;
}
#endif #endif
if(xuni == 'r') revcontrol = !revcontrol;
if(xuni == 'd') vid.drawmousecircle = !vid.drawmousecircle;
#ifdef STEAM
if(xuni == 'l') vid.steamscore = vid.steamscore^1;
#endif
if(xuni == 't')
dialog::editNumber(vid.flashtime, 0, 64, 1, 8, XLAT("message flash time"),
XLAT("How long should the messages stay on the screen."));
if(xuni == 'i') { vid.shifttarget = vid.shifttarget^3; }
handleAllConfig(sym, xuni);
} }
void showJoystickConfig() { void showJoystickConfig() {
@ -537,20 +628,33 @@ void handleJoystickConfig(int sym, int uni) {
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);
char xuni = uni | 96; char xuni = uni | 96;
if(xuni == 'p') autojoy = !autojoy; if(xuni == 'p') autojoy = !autojoy;
if(xuni == 'a') else if(xuni == 'a')
dialog::editNumber(vid.joyvalue, 0, 32768, 100, 4800, XLAT("first joystick: movement threshold"), ""); dialog::editNumber(vid.joyvalue, 0, 32768, 100, 4800, XLAT("first joystick: movement threshold"), "");
if(xuni == 'b') else if(xuni == 'b')
dialog::editNumber(vid.joyvalue2, 0, 32768, 100, 5600, XLAT("first joystick: execute movement threshold"), ""); dialog::editNumber(vid.joyvalue2, 0, 32768, 100, 5600, XLAT("first joystick: execute movement threshold"), "");
if(xuni == 'c') else if(xuni == 'c')
dialog::editNumber(vid.joypanthreshold, 0, 32768, 100, 2500, XLAT("second joystick: pan threshold"), ""); dialog::editNumber(vid.joypanthreshold, 0, 32768, 100, 2500, XLAT("second joystick: pan threshold"), "");
if(xuni == 'd') else if(xuni == 'd')
dialog::editNumber(vid.joypanspeed, 0, 1e-2, 1e-5, 1e-4, XLAT("second joystick: panning speed"), ""); dialog::editNumber(vid.joypanspeed, 0, 1e-2, 1e-5, 1e-4, XLAT("second joystick: panning speed"), "");
if(xuni == 'v') else if(xuni == 'v')
cmode = emShmupConfig; cmode = emShmupConfig;
if(sym == SDLK_F10) cmode = emNormal; else if(doexiton(sym, uni)) cmode = emShmupConfig;
if(doexiton(sym, uni)) cmode = emShmupConfig; }
void projectionDialog() {
geom3::tc_alpha = ticks;
dialog::editNumber(vid.alpha, -5, 5, .1, 1,
XLAT("projection"),
XLAT("HyperRogue uses the Minkowski hyperboloid model internally. "
"Klein and Poincar models can be obtained by perspective, "
"and the Gans model is obtained by orthogonal projection. "
// "This parameter specifies the distance from the hyperboloid center "
// "to the eye. "
"See also the conformal mode (in the special modes menu) "
"for more models."));
dialog::sidedialog = true;
} }
void show3D() { void show3D() {
@ -576,6 +680,7 @@ void show3D() {
dialog::addBreak(50); dialog::addBreak(50);
dialog::addSelItem(XLAT("Y shift"), fts3(vid.yshift), 'y'); dialog::addSelItem(XLAT("Y shift"), fts3(vid.yshift), 'y');
dialog::addSelItem(XLAT("camera rotation"), fts3(vid.camera_angle), 's'); dialog::addSelItem(XLAT("camera rotation"), fts3(vid.camera_angle), 's');
dialog::addSelItem(XLAT("distance between eyes"), fts3(vid.eye), 'e');
dialog::addBreak(50); dialog::addBreak(50);
dialog::addBoolItem(XLAT("ball model"), pmodel == mdBall, 'B'); dialog::addBoolItem(XLAT("ball model"), pmodel == mdBall, 'B');
dialog::addBoolItem(XLAT("hyperboloid model"), pmodel == mdHyperboloid, 'M'); dialog::addBoolItem(XLAT("hyperboloid model"), pmodel == mdHyperboloid, 'M');
@ -700,6 +805,14 @@ void handle3D(int sym, int uni) {
dialog::editNumber(geom3::rock_wall_ratio, 0, 1, .1, .9, XLAT("Rock-III to wall ratio"), ""); dialog::editNumber(geom3::rock_wall_ratio, 0, 1, .1, .9, XLAT("Rock-III to wall ratio"), "");
else if(uni == 'h') else if(uni == 'h')
dialog::editNumber(geom3::human_wall_ratio, 0, 1, .1, .7, XLAT("Human to wall ratio"), ""); dialog::editNumber(geom3::human_wall_ratio, 0, 1, .1, .7, XLAT("Human to wall ratio"), "");
else if(uni == 'e') {
dialog::editNumber(vid.eye, -10, 10, 0.01, 0, XLAT("distance between eyes"),
XLAT("Watch the Minkowski hyperboloid or the hypersian rug mode with the "
"red/cyan 3D glasses."));
dialog::sidedialog = true;
}
else if(uni == 'y') else if(uni == 'y')
dialog::editNumber(vid.yshift, 0, 1, .1, 0, XLAT("Y shift"), dialog::editNumber(vid.yshift, 0, 1, .1, 0, XLAT("Y shift"),
"Don't center on the player character." "Don't center on the player character."
@ -720,139 +833,126 @@ void handle3D(int sym, int uni) {
else if(uni == 'M') else if(uni == 'M')
pmodel = (pmodel == mdHyperboloid ? mdDisk : mdHyperboloid); pmodel = (pmodel == mdHyperboloid ? mdDisk : mdHyperboloid);
else if(doexiton(sym, uni)) cmode = emVisual2; else if(doexiton(sym, uni)) cmode = emDisplayMode;
if(cmode == emNumber) dialog::sidedialog = true; if(cmode == emNumber) dialog::sidedialog = true;
} }
void showVisual2() { void showDisplayMode() {
dialog::init(XLAT("advanced configuration")); dialog::init(XLAT("special display modes"));
#ifndef ONEGRAPH const char *wdmodes[6] = {"ASCII", "black", "plain", "Escher", "plain/3D", "Escher/3D"};
#ifdef GL const char *mdmodes[6] = {"ASCII", "items only", "items and monsters", "high contrast",
dialog::addSelItem(XLAT("openGL & antialiasing mode"), vid.usingGL ? "OpenGL" : vid.usingAA ? "AA" : "OFF", 'o'); "3D", "high contrast/3D"};
#endif
#endif
dialog::addSelItem(XLAT("distance between eyes"), fts3(vid.eye), 'e');
#ifndef MOBWEB
dialog::addSelItem(XLAT("framerate limit"), its(vid.framelimit), 'f');
#endif
#ifndef MOBILE dialog::addBoolItem(XLAT("orthogonal projection"), vid.alpha >= 500, '1');
dialog::addSelItem(XLAT("configure input"), "", 'p'); dialog::addBoolItem(XLAT("small Poincaré model"), vid.alpha == 1 && vid.scale < 1, '2');
#endif dialog::addBoolItem(XLAT("big Poincaré model"), vid.alpha == 1 && vid.scale >= 1, '3');
dialog::addBoolItem(XLAT("Klein-Beltrami model"), vid.alpha == 0, '4');
dialog::addSelItem(XLAT("wall display mode"), XLAT(wdmodes[vid.wallmode]), '5');
dialog::addBoolItem(XLAT("draw the grid"), (vid.grid), '6');
dialog::addBoolItem(XLAT("mark heptagons"), (vid.darkhepta), '7');
dialog::addSelItem(XLAT("3D configuration"), "", '9');
#ifdef MOBILE dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z');
dialog::addSelItem(XLAT("font scale"), its(fontscale), 'b'); dialog::addSelItem(XLAT("monster display mode"), XLAT(mdmodes[vid.monmode]), 'm');
#endif
dialog::addSelItem(XLAT("sight range"), its(sightrange), 'a');
dialog::addBoolItem(XLAT("reverse pointer control"), (revcontrol), 'r');
dialog::addBoolItem(XLAT("draw circle around the target"), (vid.drawmousecircle), 'd');
dialog::addSelItem(XLAT("message flash time"), its(vid.flashtime), 't');
#ifdef MOBILE
dialog::addBoolItem(XLAT("targetting ranged Orbs long-click only"), (vid.shifttarget&2), 'i');
#else
dialog::addBoolItem(XLAT("targetting ranged Orbs Shift+click only"), (vid.shifttarget&1), 'i');
#endif
#ifdef STEAM
dialog::addBoolItem(XLAT("send scores to Steam leaderboards"), (vid.steamscore&1), 'l');
#endif
dialog::addSelItem(XLAT("3D configuration"), "", '3');
#ifdef MOBILE
dialog::addSelItem(XLAT("compass size"), its(vid.mobilecompasssize), 'c');
#endif
dialog::addSelItem(XLAT("aura brightness"), its(vid.aurastr), 'z');
dialog::addSelItem(XLAT("aura smoothening factor"), its(vid.aurasmoothen), 'x');
dialog::addBreak(50); dialog::addBreak(50);
dialog::addItem(XLAT("exit configuration"), 'v');
#ifndef NOCONFIG #ifndef NOEDIT
dialog::addItem(XLAT("save the current config"), 's'); dialog::addBoolItem(XLAT("vector graphics editor"), (false), 'g');
#endif #endif
// display modes
#ifndef NORUG
dialog::addBoolItem(XLAT("hypersian rug mode"), (rug::rugged), 'u');
#endif
#ifndef NOMODEL
dialog::addBoolItem(XLAT("paper model creator"), (false), 'n');
#endif
dialog::addBoolItem(XLAT("conformal/history mode"), (conformal::on), 'a');
dialog::addBoolItem(XLAT("expansion"), viewdists, 'x');
showAllConfig();
dialog::display(); dialog::display();
} }
void handleVisual2(int sym, int uni) { void gmodekeys(int sym, int uni) {
if(uni == '1') { vid.alpha = 999; vid.scale = 998; }
if(uni == '2') { vid.alpha = 1; vid.scale = 0.4; }
if(uni == '3') { vid.alpha = 1; vid.scale = 1; }
if(uni == '4') { vid.alpha = 0; vid.scale = 1; }
if(uni == '5') { vid.wallmode += 60 + (shiftmul > 0 ? 1 : -1); vid.wallmode %= 6; }
if(uni == '6') vid.grid = !vid.grid;
if(uni == '7') { vid.darkhepta = !vid.darkhepta; }
if(uni == '%' && sym == '5') {
if(vid.wallmode == 0) vid.wallmode = 6;
vid.wallmode--;
}
}
void handleDisplayMode(int sym, int uni) {
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);
char xuni = uni; char xuni = uni;
if((xuni >= 'A' && xuni <= 'Z') || (xuni >= 1 && xuni <= 26)) xuni |= 32; if((xuni >= 'A' && xuni <= 'Z') || (xuni >= 1 && xuni <= 26)) xuni |= 32;
if(xuni == 'v' || sym == SDLK_F2 || sym == SDLK_ESCAPE) cmode = emNormal; if(xuni == 'p') projectionDialog();
#ifndef NOCONFIG
if(xuni == 's') saveConfig();
#endif
if(xuni == '3') cmode = em3D; if(xuni == 'z') {
dialog::editNumber(vid.scale, .001, 1000, .1, 1, XLAT("scale factor"),
if(xuni == 'c') XLAT("Scale the displayed model."));
dialog::editNumber(vid.mobilecompasssize, 0, 100, 10, 20, XLAT("compass size"), ""); dialog::scaleLog();
if(sym == SDLK_F1 || sym == 'h')
lastmode = cmode, cmode = emHelp;
#ifndef ONEGRAPH
if(xuni == 'o' && shiftmul > 0) switchGL();
#ifndef MOBILE
if(xuni == 'o' && shiftmul < 0 && !vid.usingGL) {
vid.usingAA = !vid.usingAA;
if(vid.usingAA) addMessage(XLAT("anti-aliasing enabled"));
if(!vid.usingAA) addMessage(XLAT("anti-aliasing disabled"));
}
#endif
#endif
#ifndef MOBILE
if(xuni == 'p') {
cmode = emShmupConfig;
multi::shmupcfg = shmup::on;
}
#endif
if(xuni == 'f')
dialog::editNumber(vid.framelimit, 5, 300, 10, 300, XLAT("framerate limit"), "");
if(xuni == 'a') {
dialog::editNumber(sightrange, 4, cheater ? 10 : 7, 1, 7, XLAT("sight range"),
XLAT("Roughly 42% cells are on the edge of your sight range. Reducing "
"the sight range makes HyperRogue work faster, but also makes "
"the game effectively harder."));
dialog::sidedialog = true; dialog::sidedialog = true;
} }
if(xuni == 'r') revcontrol = !revcontrol; if(xuni == 'm') { vid.monmode += 60 + (shiftmul > 0 ? 1 : -1); vid.monmode %= 6; }
if(xuni == 'd') vid.drawmousecircle = !vid.drawmousecircle;
#ifdef MOBILE if(xuni == '9') cmode = em3D;
if(xuni =='b')
dialog::editNumber(fontscale, 0, 400, 10, 100, XLAT("font scale"), ""); #ifndef NOEDIT
else if(xuni == 'g') {
cmode = emDraw;
mapeditor::initdraw(cwt.c);
}
#endif #endif
if(xuni =='z') else if(xuni == 'x') {
dialog::editNumber(vid.aurastr, 0, 256, 10, 128, XLAT("aura brightness"), ""); viewdists = !viewdists;
if(xuni =='x') cmode = emNormal;
dialog::editNumber(vid.aurasmoothen, 1, 180, 1, 5, XLAT("aura smoothening factor"), ""); }
#ifndef NORUG
else if(xuni == 'u') {
if(sphere) projectionDialog();
else rug::select();
}
#endif
else if(uni == 'a')
cmode = emConformal;
if(xuni == 'e') { #ifndef NOMODEL
dialog::editNumber(vid.eye, -10, 10, 0.01, 0, XLAT("distance between eyes"), else if(xuni == 'n')
XLAT("Watch the Minkowski hyperboloid or the hypersian rug mode with the " cmode = emNetgen;
"red/cyan 3D glasses.")); #endif
dialog::sidedialog = true;
else gmodekeys(sym, uni);
handleAllConfig(sym, xuni);
} }
#ifdef STEAM void switchHardcore() {
if(xuni == 'l') vid.steamscore = vid.steamscore^1; if(hardcore && !canmove) {
#endif restartGame();
if(xuni == 't') hardcore = false;
dialog::editNumber(vid.flashtime, 0, 64, 1, 8, XLAT("message flash time"), cmode = emNormal;
XLAT("How long should the messages stay on the screen.")); }
else if(hardcore && canmove) { hardcore = false; }
if(xuni == 'i') { vid.shifttarget = vid.shifttarget^3; } else { hardcore = true; canmove = true; hardcoreAt = turncount; }
if(hardcore)
addMessage("One wrong move, and it is game over!");
else
addMessage("Not so hardcore?");
if(pureHardcore()) cmode = emNormal;
} }
void showChangeMode() { void showChangeMode() {
@ -876,6 +976,8 @@ void showChangeMode() {
dialog::addBoolItem(XLAT("pure tactics mode"), (tactic::on), 't'); dialog::addBoolItem(XLAT("pure tactics mode"), (tactic::on), 't');
dialog::addBoolItem(XLAT("heptagonal mode"), (purehepta), '7'); dialog::addBoolItem(XLAT("heptagonal mode"), (purehepta), '7');
dialog::addBoolItem(XLAT("Chaos mode"), (chaosmode), 'C'); dialog::addBoolItem(XLAT("Chaos mode"), (chaosmode), 'C');
dialog::addBoolItem(XLAT("peaceful mode"), (chaosmode), 'P');
dialog::addBoolItem(XLAT("inventory mode"), (inv::on), 'i');
dialog::addBreak(50); dialog::addBreak(50);
// cheating and map editor // cheating and map editor
@ -883,21 +985,8 @@ void showChangeMode() {
dialog::addBoolItem(XLAT("cheat mode"), (cheater), 'c'); dialog::addBoolItem(XLAT("cheat mode"), (cheater), 'c');
#ifndef NOEDIT #ifndef NOEDIT
dialog::addBoolItem(XLAT("map editor"), (false), 'm'); dialog::addBoolItem(XLAT("map editor"), (false), 'm');
dialog::addBreak(50);
dialog::addBoolItem(XLAT("vector graphics editor"), (false), 'g');
#endif #endif
// display modes
#ifndef NORUG
dialog::addBoolItem(XLAT("hypersian rug mode"), (rug::rugged), 'u');
#endif
#ifndef NOMODEL
dialog::addBoolItem(XLAT("paper model creator"), (false), 'n');
#endif
dialog::addBoolItem(XLAT("conformal/history mode"), (conformal::on), 'a');
dialog::addBoolItem(XLAT("expansion"), viewdists, 'x');
dialog::addBreak(50); dialog::addBreak(50);
dialog::addItem(XLAT("return to the game"), 'v'); dialog::addItem(XLAT("return to the game"), 'v');
@ -908,7 +997,7 @@ void handleChangeMode(int sym, int uni) {
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);
char xuni = uni; char xuni = uni;
if(xuni == 'v' || sym == SDLK_F2 || sym == SDLK_ESCAPE) cmode = emNormal; if(xuni == 'v' || sym == SDLK_ESCAPE) cmode = emNormal;
else if(uni == 'c') { else if(uni == 'c') {
if(tactic::on && gold()) { if(tactic::on && gold()) {
@ -929,43 +1018,27 @@ void handleChangeMode(int sym, int uni) {
} }
} }
#ifndef NOEDIT
else if(xuni == 'g') {
cmode = emDraw;
mapeditor::initdraw(cwt.c);
}
#endif
else if(xuni == 'e') { else if(xuni == 'e') {
cmode = emPickEuclidean; cmode = emPickEuclidean;
} }
else if(xuni == 'x') {
viewdists = !viewdists;
cmode = emNormal;
}
else if(xuni == 't') { else if(xuni == 't') {
clearMessages(); clearMessages();
cmode = emTactic; cmode = emTactic;
} }
#ifndef NORUG
else if(xuni == 'u') {
if(sphere) projectionDialog();
else rug::select();
}
#endif
else if(xuni == 'y') { else if(xuni == 'y') {
clearMessages(); clearMessages();
if(yendor::everwon || autocheat) if(yendor::everwon || autocheat)
cmode = emYendor; cmode = emYendor;
else { else gotoHelp(yendor::chelp);
cmode = emHelp;
help = yendor::chelp;
lastmode = emChangeMode;
}
} }
else if(xuni == '7') else if(xuni == '7')
restartGame('7'); restartGame('7');
else if(uni == 'a') else if(xuni == 'P')
cmode = emConformal; cmode = emPeace;
else if(xuni == 'i') {
restartGame('i');
cmode = emNormal;
}
#ifdef TOUR #ifdef TOUR
else if(uni == 'T') { else if(uni == 'T') {
cmode = emNormal; cmode = emNormal;
@ -973,15 +1046,13 @@ void handleChangeMode(int sym, int uni) {
} }
#endif #endif
else if(uni == 'C') { else if(uni == 'C') {
if(!chaosmode) { if(!chaosmode) gotoHelp(
cmode = emHelp;
help =
"In the Chaos mode, lands change very often, and " "In the Chaos mode, lands change very often, and "
"there are no walls between them. " "there are no walls between them. "
"Some lands are incompatible with this." "Some lands are incompatible with this."
"\n\nYou need to reach Crossroads IV to unlock the Chaos mode."; "\n\nYou need to reach Crossroads IV to unlock the Chaos mode.",
lastmode = chaosUnlocked ? emNormal : emChangeMode; chaosUnlocked ? emNormal : emChangeMode
} );
if(chaosUnlocked) restartGame('C'); if(chaosUnlocked) restartGame('C');
} }
else if(xuni == 'p') { else if(xuni == 'p') {
@ -1013,10 +1084,6 @@ void handleChangeMode(int sym, int uni) {
cmode = emShmupConfig; cmode = emShmupConfig;
#endif #endif
} }
#ifndef NOMODEL
else if(xuni == 'n')
cmode = emNetgen;
#endif
else if(xuni == 'h' && !shmup::on) else if(xuni == 'h' && !shmup::on)
switchHardcore(); switchHardcore();
else if(xuni == 'r') { else if(xuni == 'r') {
@ -1126,7 +1193,7 @@ void handleCustomizeChar(int sym, int uni) {
if(xuni == 'd') switchcolor(cs.dresscolor, cat ? haircolors : dresscolors); if(xuni == 'd') switchcolor(cs.dresscolor, cat ? haircolors : dresscolors);
if(xuni == 'f') switchcolor(cs.dresscolor2, dresscolors2); if(xuni == 'f') switchcolor(cs.dresscolor2, dresscolors2);
if(xuni == 'u') switchcolor(cs.uicolor, eyecolors); if(xuni == 'u') switchcolor(cs.uicolor, eyecolors);
if(xuni == 'v' || sym == SDLK_F2 || sym == SDLK_ESCAPE) cmode = emNormal; if(xuni == 'v' || sym == SDLK_ESCAPE) cmode = emNormal;
} }
int eupage = 0; int eupage = 0;
@ -1220,8 +1287,7 @@ void handleEuclidean(int sym, int uni) {
} }
else euclidland = laIce; else euclidland = laIce;
} }
else if(uni == '2' || sym == SDLK_F1) { else if(uni == '2' || sym == SDLK_F1) gotoHelp(
help =
"If you want to know how much the gameplay is affected by the " "If you want to know how much the gameplay is affected by the "
"hyperbolic geometry in HyperRogue, this mode is for you!\n\n" "hyperbolic geometry in HyperRogue, this mode is for you!\n\n"
@ -1231,10 +1297,8 @@ void handleEuclidean(int sym, int uni) {
"ultraparallel lines (Crossroads, Vineyard, Palace) cannot be " "ultraparallel lines (Crossroads, Vineyard, Palace) cannot be "
"faithfully represented in Euclidean, so yo get more " "faithfully represented in Euclidean, so yo get more "
"or less simplified versions of them. Choose Crossroads to play a game " "or less simplified versions of them. Choose Crossroads to play a game "
"where many different lands appear."; "where many different lands appear."
cmode = emHelp; );
lastmode = emPickEuclidean;
}
else if(doexiton(sym, uni)) cmode = emNormal; else if(doexiton(sym, uni)) cmode = emNormal;
} }
@ -1259,12 +1323,12 @@ void showScores() {
mouseovers = XLAT("t/left/right - change display, up/down - scroll, s - sort by") + modes; mouseovers = XLAT("t/left/right - change display, up/down - scroll, s - sort by") + modes;
displaystr(bx*4, vid.fsize*2, 0, vid.fsize, "#", 0xFFFFFF, 16); displaystr(bx*4, vid.fsize*2, 0, vid.fsize, "#", forecolor, 16);
displaystr(bx*8, vid.fsize*2, 0, vid.fsize, "$$$", 0xFFFFFF, 16); displaystr(bx*8, vid.fsize*2, 0, vid.fsize, "$$$", forecolor, 16);
displaystr(bx*12, vid.fsize*2, 0, vid.fsize, XLAT("kills"), 0xFFFFFF, 16); displaystr(bx*12, vid.fsize*2, 0, vid.fsize, XLAT("kills"), forecolor, 16);
displaystr(bx*18, vid.fsize*2, 0, vid.fsize, XLAT("time"), 0xFFFFFF, 16); displaystr(bx*18, vid.fsize*2, 0, vid.fsize, XLAT("time"), forecolor, 16);
displaystr(bx*22, vid.fsize*2, 0, vid.fsize, XLAT("ver"), 0xFFFFFF, 16); displaystr(bx*22, vid.fsize*2, 0, vid.fsize, XLAT("ver"), forecolor, 16);
displaystr(bx*23, vid.fsize*2, 0, vid.fsize, displayfor(NULL), 0xFFFFFF, 0); displaystr(bx*23, vid.fsize*2, 0, vid.fsize, displayfor(NULL), forecolor, 0);
if(scorefrom < 0) scorefrom = 0; if(scorefrom < 0) scorefrom = 0;
int id = 0; int id = 0;
int omit = scorefrom; int omit = scorefrom;
@ -1448,7 +1512,6 @@ void showHelp() {
getcstat = SDLK_ESCAPE; getcstat = SDLK_ESCAPE;
if(help == "HELPFUN") { if(help == "HELPFUN") {
help_delegate(); help_delegate();
dialog::display();
return; return;
} }
@ -1462,7 +1525,7 @@ void showHelp() {
dialog::addHelp(help.substr(id+1)); dialog::addHelp(help.substr(id+1));
} }
else { else {
dialog::init("help", 0xFFFFFF, 120, 100); dialog::init("help", forecolor, 120, 100);
dialog::addHelp(help); dialog::addHelp(help);
} }
@ -1545,10 +1608,7 @@ void showDemo() {
void handleDemoKey(int sym, int uni) { void handleDemoKey(int sym, int uni) {
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);
if(sym == SDLK_F1 || sym == 'h') { if(sym == SDLK_F1 || sym == 'h') gotoHelp(help);
lastmode = cmode;
cmode = emHelp;
}
else if(sym == 'a') { else if(sym == 'a') {
toggleanim(!demoanim); toggleanim(!demoanim);
cmode = emNormal; cmode = emNormal;
@ -1596,6 +1656,11 @@ void displayMenus() {
if(cmode == emJoyConfig) showJoystickConfig(); if(cmode == emJoyConfig) showJoystickConfig();
if(cmode == emOverview) showOverview(); if(cmode == emOverview) showOverview();
if(cmode == emYendor) yendor::showMenu(); if(cmode == emYendor) yendor::showMenu();
if(cmode == emPeace) peace::showMenu();
#ifdef INV
if(cmode == emInventory) inv::showMenu();
#endif
if(cmode == emSlideshows) tour::ss::showMenu();
if(cmode == emChangeMode) showChangeMode(); if(cmode == emChangeMode) showChangeMode();
if(cmode == emCustomizeChar) showCustomizeChar(); if(cmode == emCustomizeChar) showCustomizeChar();
if(cmode == emShmupConfig) shmup::showShmupConfig(); if(cmode == emShmupConfig) shmup::showShmupConfig();
@ -1604,8 +1669,9 @@ void displayMenus() {
if(cmode == emPickEuclidean) showEuclideanMenu(); if(cmode == emPickEuclidean) showEuclideanMenu();
if(cmode == emMenu) showMainMenu(); if(cmode == emMenu) showMainMenu();
if(cmode == emCheatMenu) showCheatMenu(); if(cmode == emCheatMenu) showCheatMenu();
if(cmode == emVisual1) showVisual1(); if(cmode == emBasicConfig) showBasicConfig();
if(cmode == emVisual2) showVisual2(); if(cmode == emGraphConfig) showGraphConfig();
if(cmode == emDisplayMode) showDisplayMode();
if(cmode == emColor) dialog::drawColorDialog(*dialog::colorPointer); if(cmode == emColor) dialog::drawColorDialog(*dialog::colorPointer);
if(cmode == emNumber) dialog::drawNumberDialog(); if(cmode == emNumber) dialog::drawNumberDialog();
if(cmode == emLinepattern) linepatterns::showMenu(); if(cmode == emLinepattern) linepatterns::showMenu();

View File

@ -157,6 +157,7 @@ unsigned char fonttable[] = {
43,21,0,113,255,6,0,15,255,6,0,15,255,6,0,15,255,6,0,15,255,6,0,15,255,6,0,15,255,6,0,51,255,18,0,3,255,18,0,3,255,18,0,3,255,18,0,3,255,17,209,0,11,12,203,255,6,232,30,0,10,5,184,255,6,247,55,0,10,1,163,255,7,88,0,11,140,255,7,128,0,11,115,255,7,167,0,11,91,254,255,6,200,8,0,10,70,250,255,6,225,23,0,10,51,243,255,6,243,46,0,10,36,233,255,6,253,77,0,10,23,221,255,7,115,0,11,206,255,17,0,3,255,18,0,3,255,18,0,3,255,18,0,3,255,18,0,190, 43,21,0,113,255,6,0,15,255,6,0,15,255,6,0,15,255,6,0,15,255,6,0,15,255,6,0,15,255,6,0,51,255,18,0,3,255,18,0,3,255,18,0,3,255,18,0,3,255,17,209,0,11,12,203,255,6,232,30,0,10,5,184,255,6,247,55,0,10,1,163,255,7,88,0,11,140,255,7,128,0,11,115,255,7,167,0,11,91,254,255,6,200,8,0,10,70,250,255,6,225,23,0,10,51,243,255,6,243,46,0,10,36,233,255,6,253,77,0,10,23,221,255,7,115,0,11,206,255,17,0,3,255,18,0,3,255,18,0,3,255,18,0,3,255,18,0,190,
43,26,0,6,158,255,2,155,3,0,3,3,155,255,2,157,0,13,9,208,255,2,179,10,0,1,10,180,255,2,207,8,0,14,36,240,255,2,200,42,201,255,2,240,35,0,16,80,255,3,254,255,3,79,0,18,138,255,5,138,0,90,255,23,0,3,255,23,0,3,255,23,0,3,255,23,0,3,255,22,163,0,16,50,245,255,6,195,6,0,15,27,229,255,6,221,20,0,15,10,205,255,6,239,40,0,15,1,174,255,6,251,67,0,16,136,255,7,101,0,16,95,255,7,140,0,16,61,249,255,6,177,2,0,15,34,235,255,6,206,11,0,15,15,214,255,6,229,27,0,15,4,186,255,6,245,50,0,16,150,255,6,253,80,0,16,110,255,7,117,0,16,73,252,255,6,155,0,16,43,241,255,6,189,5,0,15,22,223,255,6,216,17,0,15,7,197,255,6,236,36,0,16,164,255,22,0,3,255,23,0,3,255,23,0,3,255,23,0,3,255,23,0,235, 43,26,0,6,158,255,2,155,3,0,3,3,155,255,2,157,0,13,9,208,255,2,179,10,0,1,10,180,255,2,207,8,0,14,36,240,255,2,200,42,201,255,2,240,35,0,16,80,255,3,254,255,3,79,0,18,138,255,5,138,0,90,255,23,0,3,255,23,0,3,255,23,0,3,255,23,0,3,255,22,163,0,16,50,245,255,6,195,6,0,15,27,229,255,6,221,20,0,15,10,205,255,6,239,40,0,15,1,174,255,6,251,67,0,16,136,255,7,101,0,16,95,255,7,140,0,16,61,249,255,6,177,2,0,15,34,235,255,6,206,11,0,15,15,214,255,6,229,27,0,15,4,186,255,6,245,50,0,16,150,255,6,253,80,0,16,110,255,7,117,0,16,73,252,255,6,155,0,16,43,241,255,6,189,5,0,15,22,223,255,6,216,17,0,15,7,197,255,6,236,36,0,16,164,255,22,0,3,255,23,0,3,255,23,0,3,255,23,0,3,255,23,0,235,
43,21,0,108,175,255,2,120,0,5,120,255,2,175,0,8,28,242,255,1,253,74,0,3,75,253,255,1,242,27,0,9,109,255,2,240,39,0,1,40,241,255,2,108,0,10,2,202,255,2,217,32,217,255,2,201,2,0,11,47,251,255,2,246,255,2,251,47,0,13,138,255,5,137,0,14,10,222,255,3,222,10,0,52,255,18,0,3,255,18,0,3,255,18,0,3,255,18,0,3,255,17,209,0,11,12,203,255,6,232,30,0,10,5,184,255,6,247,55,0,10,1,163,255,7,88,0,11,140,255,7,128,0,11,115,255,7,167,0,11,91,254,255,6,200,8,0,10,70,250,255,6,225,23,0,10,51,243,255,6,243,46,0,10,36,233,255,6,253,77,0,10,23,221,255,7,115,0,11,206,255,17,0,3,255,18,0,3,255,18,0,3,255,18,0,3,255,18,0,190, 43,21,0,108,175,255,2,120,0,5,120,255,2,175,0,8,28,242,255,1,253,74,0,3,75,253,255,1,242,27,0,9,109,255,2,240,39,0,1,40,241,255,2,108,0,10,2,202,255,2,217,32,217,255,2,201,2,0,11,47,251,255,2,246,255,2,251,47,0,13,138,255,5,137,0,14,10,222,255,3,222,10,0,52,255,18,0,3,255,18,0,3,255,18,0,3,255,18,0,3,255,17,209,0,11,12,203,255,6,232,30,0,10,5,184,255,6,247,55,0,10,1,163,255,7,88,0,11,140,255,7,128,0,11,115,255,7,167,0,11,91,254,255,6,200,8,0,10,70,250,255,6,225,23,0,10,51,243,255,6,243,46,0,10,36,233,255,6,253,77,0,10,23,221,255,7,115,0,11,206,255,17,0,3,255,18,0,3,255,18,0,3,255,18,0,3,255,18,0,190,
43,25,0,182,40,115,172,207,234,245,253,243,228,193,144,67,2,0,10,32,183,255,12,221,77,0,8,32,234,255,15,0,8,165,255,16,0,8,234,255,16,0,8,245,255,5,98,25,6,2,9,15,34,55,91,138,214,0,8,197,255,5,169,87,44,15,0,15,70,253,255,8,240,190,130,51,0,12,83,235,255,11,207,83,0,10,77,230,255,13,178,15,0,7,95,253,255,15,200,14,0,5,57,249,255,6,214,207,249,255,8,155,0,4,2,212,255,5,232,77,0,2,5,50,148,252,255,5,253,45,0,3,86,255,5,237,37,0,6,67,248,255,5,130,0,3,169,255,5,116,0,8,128,255,5,199,0,3,224,255,5,35,0,8,41,255,5,228,0,3,247,255,5,6,0,8,7,255,5,248,0,3,242,255,5,13,0,8,12,255,5,239,0,3,221,255,5,56,0,8,56,255,5,218,0,3,179,255,5,148,0,8,152,255,5,173,0,3,108,255,5,252,71,0,6,77,253,255,5,102,0,3,22,243,255,5,250,141,48,9,10,50,145,252,255,5,239,16,0,4,129,255,18,119,0,5,5,188,255,16,177,2,0,6,14,180,255,14,172,11,0,8,1,106,227,255,10,225,101,0,12,4,81,147,204,229,247,247,230,204,148,81,4,0,231,
43,29,0,185,84,92,92,92,92,92,30,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,21,2,237,255,5,87,0,17,4,79,156,210,247,255,6,254,226,182,110,27,0,12,69,218,255,14,248,139,5,0,9,81,251,255,17,181,2,0,7,24,238,255,19,111,0,7,154,255,6,241,251,255,5,236,255,6,243,15,0,5,16,245,255,5,234,32,236,255,5,85,161,255,6,110,0,5,89,255,6,92,0,1,236,255,5,84,13,232,255,5,193,0,5,148,255,5,231,4,0,1,236,255,5,84,0,1,131,255,5,245,4,0,4,186,255,5,165,0,2,236,255,5,84,0,1,62,255,6,33,0,4,204,255,5,132,0,2,236,255,5,84,0,1,29,255,6,51,0,4,208,255,5,125,0,2,236,255,5,84,0,1,22,255,6,56,0,4,188,255,5,144,0,2,236,255,5,84,0,1,41,255,6,35,0,4,159,255,5,195,0,2,236,255,5,84,0,1,92,255,5,251,10,0,4,92,255,5,254,45,0,1,236,255,5,84,1,195,255,5,195,0,5,20,246,255,5,221,38,236,255,5,88,151,255,6,114,0,6,139,255,6,243,249,255,5,237,255,6,232,10,0,6,16,218,255,18,254,84,0,8,37,234,255,17,122,0,10,31,201,255,14,242,96,0,12,1,90,196,254,255,9,229,138,22,0,16,23,77,244,255,5,144,46,2,0,20,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,114,124,124,124,124,124,40,0,40, 43,29,0,185,84,92,92,92,92,92,30,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,21,2,237,255,5,87,0,17,4,79,156,210,247,255,6,254,226,182,110,27,0,12,69,218,255,14,248,139,5,0,9,81,251,255,17,181,2,0,7,24,238,255,19,111,0,7,154,255,6,241,251,255,5,236,255,6,243,15,0,5,16,245,255,5,234,32,236,255,5,85,161,255,6,110,0,5,89,255,6,92,0,1,236,255,5,84,13,232,255,5,193,0,5,148,255,5,231,4,0,1,236,255,5,84,0,1,131,255,5,245,4,0,4,186,255,5,165,0,2,236,255,5,84,0,1,62,255,6,33,0,4,204,255,5,132,0,2,236,255,5,84,0,1,29,255,6,51,0,4,208,255,5,125,0,2,236,255,5,84,0,1,22,255,6,56,0,4,188,255,5,144,0,2,236,255,5,84,0,1,41,255,6,35,0,4,159,255,5,195,0,2,236,255,5,84,0,1,92,255,5,251,10,0,4,92,255,5,254,45,0,1,236,255,5,84,1,195,255,5,195,0,5,20,246,255,5,221,38,236,255,5,88,151,255,6,114,0,6,139,255,6,243,249,255,5,237,255,6,232,10,0,6,16,218,255,18,254,84,0,8,37,234,255,17,122,0,10,31,201,255,14,242,96,0,12,1,90,196,254,255,9,229,138,22,0,16,23,77,244,255,5,144,46,2,0,20,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,236,255,5,84,0,22,114,124,124,124,124,124,40,0,40,
43,25,0,6,255,4,0,3,255,4,0,14,255,4,0,3,255,4,0,14,255,4,0,3,255,4,0,14,255,4,0,3,255,4,0,111,255,19,0,6,255,19,0,6,255,19,0,6,255,19,0,6,255,19,0,6,255,6,0,19,255,6,0,19,255,6,0,19,255,6,0,19,255,6,0,19,255,18,0,7,255,18,0,7,255,18,0,7,255,18,0,7,255,18,0,7,255,6,0,19,255,6,0,19,255,6,0,19,255,6,0,19,255,6,0,19,255,6,0,19,255,19,0,6,255,19,0,6,255,19,0,6,255,19,0,6,255,19,0,228, 43,25,0,6,255,4,0,3,255,4,0,14,255,4,0,3,255,4,0,14,255,4,0,3,255,4,0,14,255,4,0,3,255,4,0,111,255,19,0,6,255,19,0,6,255,19,0,6,255,19,0,6,255,19,0,6,255,6,0,19,255,6,0,19,255,6,0,19,255,6,0,19,255,6,0,19,255,18,0,7,255,18,0,7,255,18,0,7,255,18,0,7,255,18,0,7,255,6,0,19,255,6,0,19,255,6,0,19,255,6,0,19,255,6,0,19,255,6,0,19,255,19,0,6,255,19,0,6,255,19,0,6,255,19,0,6,255,19,0,228,
43,28,0,233,77,255,8,76,0,18,174,255,8,173,0,17,21,250,255,8,250,20,0,16,113,255,10,112,0,16,210,255,10,209,0,15,52,255,12,51,0,14,149,255,5,214,214,255,5,148,0,13,8,238,255,5,117,118,255,5,238,7,0,12,88,255,5,252,24,25,252,255,5,87,0,12,185,255,5,179,0,2,180,255,5,184,0,11,29,253,255,5,81,0,2,82,255,5,253,28,0,10,124,255,5,235,5,0,2,5,235,255,5,123,0,10,220,255,5,143,0,4,144,255,5,219,0,9,63,255,6,46,0,4,47,255,6,62,0,8,160,255,5,205,0,6,206,255,5,159,0,7,13,244,255,5,108,0,6,109,255,5,244,12,0,6,99,255,20,98,0,6,196,255,20,195,0,5,38,255,22,37,0,4,135,255,22,134,0,3,3,229,255,22,228,3,0,2,74,255,6,36,0,10,36,255,6,73,0,2,171,255,5,193,0,12,194,255,5,170,0,1,19,249,255,5,95,0,12,96,255,5,248,18,110,255,5,242,11,0,12,11,243,255,5,109,207,255,5,156,0,14,157,255,5,207,0,252, 43,28,0,233,77,255,8,76,0,18,174,255,8,173,0,17,21,250,255,8,250,20,0,16,113,255,10,112,0,16,210,255,10,209,0,15,52,255,12,51,0,14,149,255,5,214,214,255,5,148,0,13,8,238,255,5,117,118,255,5,238,7,0,12,88,255,5,252,24,25,252,255,5,87,0,12,185,255,5,179,0,2,180,255,5,184,0,11,29,253,255,5,81,0,2,82,255,5,253,28,0,10,124,255,5,235,5,0,2,5,235,255,5,123,0,10,220,255,5,143,0,4,144,255,5,219,0,9,63,255,6,46,0,4,47,255,6,62,0,8,160,255,5,205,0,6,206,255,5,159,0,7,13,244,255,5,108,0,6,109,255,5,244,12,0,6,99,255,20,98,0,6,196,255,20,195,0,5,38,255,22,37,0,4,135,255,22,134,0,3,3,229,255,22,228,3,0,2,74,255,6,36,0,10,36,255,6,73,0,2,171,255,5,193,0,12,194,255,5,170,0,1,19,249,255,5,95,0,12,96,255,5,248,18,110,255,5,242,11,0,12,11,243,255,5,109,207,255,5,156,0,14,157,255,5,207,0,252,
@ -223,6 +224,7 @@ unsigned char fonttable[] = {
43,35,0,255,0,238,255,6,0,8,16,103,161,211,232,248,246,228,204,149,86,6,0,9,255,6,0,6,10,144,245,255,10,231,115,2,0,7,255,6,0,5,32,216,255,14,191,20,0,6,255,6,0,4,23,221,255,16,199,9,0,5,255,6,0,4,177,255,18,143,0,5,255,6,0,3,63,255,6,244,127,44,10,8,42,126,243,255,5,248,30,0,4,255,6,0,3,165,255,5,243,48,0,6,48,244,255,5,117,0,4,255,6,0,3,225,255,5,126,0,8,126,255,5,187,0,4,255,6,252,244,236,255,6,42,0,8,43,255,5,223,0,4,255,15,8,0,8,9,255,5,245,0,4,255,15,8,0,8,9,255,5,245,0,4,255,6,220,220,220,254,255,5,42,0,8,43,255,5,223,0,4,255,6,0,3,219,255,5,125,0,8,125,255,5,187,0,4,255,6,0,3,157,255,5,243,46,0,6,45,243,255,5,117,0,4,255,6,0,3,56,255,6,243,125,43,8,8,41,123,242,255,5,249,30,0,4,255,6,0,4,171,255,18,143,0,5,255,6,0,4,21,219,255,16,200,9,0,5,255,6,0,5,31,215,255,14,192,20,0,6,255,6,0,6,10,143,245,255,10,232,116,2,0,7,255,6,0,8,16,103,162,211,233,248,247,230,205,150,86,7,0,255,0,66, 43,35,0,255,0,238,255,6,0,8,16,103,161,211,232,248,246,228,204,149,86,6,0,9,255,6,0,6,10,144,245,255,10,231,115,2,0,7,255,6,0,5,32,216,255,14,191,20,0,6,255,6,0,4,23,221,255,16,199,9,0,5,255,6,0,4,177,255,18,143,0,5,255,6,0,3,63,255,6,244,127,44,10,8,42,126,243,255,5,248,30,0,4,255,6,0,3,165,255,5,243,48,0,6,48,244,255,5,117,0,4,255,6,0,3,225,255,5,126,0,8,126,255,5,187,0,4,255,6,252,244,236,255,6,42,0,8,43,255,5,223,0,4,255,15,8,0,8,9,255,5,245,0,4,255,15,8,0,8,9,255,5,245,0,4,255,6,220,220,220,254,255,5,42,0,8,43,255,5,223,0,4,255,6,0,3,219,255,5,125,0,8,125,255,5,187,0,4,255,6,0,3,157,255,5,243,46,0,6,45,243,255,5,117,0,4,255,6,0,3,56,255,6,243,125,43,8,8,41,123,242,255,5,249,30,0,4,255,6,0,4,171,255,18,143,0,5,255,6,0,4,21,219,255,16,200,9,0,5,255,6,0,5,31,215,255,14,192,20,0,6,255,6,0,6,10,143,245,255,10,232,116,2,0,7,255,6,0,8,16,103,162,211,233,248,247,230,205,150,86,7,0,255,0,66,
43,23,0,255,0,72,8,90,163,206,236,247,255,10,0,6,63,227,255,15,0,5,38,246,255,16,0,5,161,255,17,0,5,228,255,17,0,5,250,255,5,151,39,8,0,3,255,6,0,5,235,255,5,17,0,5,255,6,0,5,173,255,5,152,38,7,0,3,255,6,0,5,58,254,255,16,0,6,125,255,16,0,7,136,254,255,14,0,8,128,255,14,0,7,4,216,255,14,0,7,105,255,6,113,0,2,255,6,0,6,13,233,255,5,221,6,0,2,255,6,0,6,132,255,6,86,0,3,255,6,0,5,27,245,255,5,200,0,4,255,6,0,5,159,255,6,60,0,4,255,6,0,4,46,253,255,5,175,0,5,255,6,0,4,185,255,5,251,39,0,5,255,6,0,209, 43,23,0,255,0,72,8,90,163,206,236,247,255,10,0,6,63,227,255,15,0,5,38,246,255,16,0,5,161,255,17,0,5,228,255,17,0,5,250,255,5,151,39,8,0,3,255,6,0,5,235,255,5,17,0,5,255,6,0,5,173,255,5,152,38,7,0,3,255,6,0,5,58,254,255,16,0,6,125,255,16,0,7,136,254,255,14,0,8,128,255,14,0,7,4,216,255,14,0,7,105,255,6,113,0,2,255,6,0,6,13,233,255,5,221,6,0,2,255,6,0,6,132,255,6,86,0,3,255,6,0,5,27,245,255,5,200,0,4,255,6,0,5,159,255,6,60,0,4,255,6,0,4,46,253,255,5,175,0,5,255,6,0,4,185,255,5,251,39,0,5,255,6,0,209,
43,24,0,150,255,4,0,3,255,4,0,13,255,4,0,3,255,4,0,13,255,4,0,3,255,4,0,13,255,4,0,3,255,4,0,110,9,92,155,209,231,248,242,221,179,112,24,0,11,3,122,236,255,9,246,140,8,0,8,22,195,255,13,202,25,0,6,10,201,255,15,202,8,0,5,145,255,5,246,129,41,7,14,74,206,255,5,140,0,4,31,249,255,4,252,67,0,5,9,203,255,4,246,24,0,3,118,255,5,146,0,7,69,255,5,112,0,3,188,255,5,60,0,7,11,255,5,179,0,3,225,255,19,221,0,3,246,255,19,242,0,3,246,255,20,0,3,225,255,20,0,3,190,255,5,25,0,17,120,255,5,109,0,17,34,251,255,4,238,45,0,9,15,103,205,0,5,150,255,5,245,137,55,15,3,15,33,75,123,191,251,255,2,0,5,13,206,255,17,0,6,24,198,255,16,0,7,3,120,233,255,14,0,9,6,85,148,202,228,245,253,246,236,216,192,159,122,76,25,0,218, 43,24,0,150,255,4,0,3,255,4,0,13,255,4,0,3,255,4,0,13,255,4,0,3,255,4,0,13,255,4,0,3,255,4,0,110,9,92,155,209,231,248,242,221,179,112,24,0,11,3,122,236,255,9,246,140,8,0,8,22,195,255,13,202,25,0,6,10,201,255,15,202,8,0,5,145,255,5,246,129,41,7,14,74,206,255,5,140,0,4,31,249,255,4,252,67,0,5,9,203,255,4,246,24,0,3,118,255,5,146,0,7,69,255,5,112,0,3,188,255,5,60,0,7,11,255,5,179,0,3,225,255,19,221,0,3,246,255,19,242,0,3,246,255,20,0,3,225,255,20,0,3,190,255,5,25,0,17,120,255,5,109,0,17,34,251,255,4,238,45,0,9,15,103,205,0,5,150,255,5,245,137,55,15,3,15,33,75,123,191,251,255,2,0,5,13,206,255,17,0,6,24,198,255,16,0,7,3,120,233,255,14,0,9,6,85,148,202,228,245,253,246,236,216,192,159,122,76,25,0,218,
43,17,0,113,9,12,12,12,2,0,12,196,255,3,56,0,12,196,255,3,56,0,12,196,255,3,56,0,8,2,0,3,196,255,3,56,0,5,75,193,247,252,219,128,9,196,255,3,56,0,4,122,255,6,204,211,255,3,56,0,3,63,254,255,3,202,144,178,254,255,4,56,0,3,181,255,3,167,1,0,2,104,255,4,56,0,3,245,255,3,51,0,3,3,237,255,3,56,0,2,14,255,4,17,0,4,206,255,3,56,0,2,6,255,4,30,0,4,219,255,3,56,0,3,219,255,3,93,0,3,32,251,255,3,56,0,3,130,255,3,230,74,16,49,199,255,4,56,0,3,14,221,255,6,254,242,255,3,56,0,4,31,203,255,4,241,92,196,255,3,56,0,5,1,66,121,127,92,17,0,1,49,64,64,64,14,0,255,0,86,
255 255
}; };

View File

@ -11,6 +11,8 @@ bool first;
bool fatborder; bool fatborder;
int poly_outline;
#define PSHIFT 0 #define PSHIFT 0
// #define STLSORT // #define STLSORT
@ -25,6 +27,10 @@ struct hpcshape {
hpcshape *last = NULL; hpcshape *last = NULL;
#ifndef GL
typedef float GLfloat;
#endif
struct qpoly { struct qpoly {
transmatrix V; transmatrix V;
GLfloat *tab; GLfloat *tab;
@ -36,9 +42,10 @@ struct qpoly {
struct qline { struct qline {
hyperpoint H1, H2; hyperpoint H1, H2;
int prf; int prf;
double width;
}; };
#define MAXQCHR 16 #define MAXQCHR 40
struct qchr { struct qchr {
char str[MAXQCHR]; char str[MAXQCHR];
@ -122,17 +129,17 @@ SDL_Surface *aux;
vector<polytodraw*> ptds2; vector<polytodraw*> ptds2;
#define POLYMAX 60000
#ifdef GL #ifdef GL
#define USEPOLY #define USEPOLY
GLuint shapebuffer; GLuint shapebuffer;
#define POLYMAX 60000
GLfloat glcoords[POLYMAX][3]; GLfloat glcoords[POLYMAX][3];
int qglcoords; int qglcoords;
extern void glcolor(int color); extern void glcolor(int color);
#endif
GLfloat *currentvertices; GLfloat *currentvertices;
@ -142,7 +149,25 @@ void activateVertexArray(GLfloat *f, int qty) {
glVertexPointer(3, GL_FLOAT, 0, f); glVertexPointer(3, GL_FLOAT, 0, f);
} }
extern GLfloat *ourshape;
void activateShapes() {
if(currentvertices != ourshape) {
activateVertexArray(ourshape, qhpc);
}
}
void activateGlcoords() {
activateVertexArray(glcoords[0], qglcoords);
}
#endif
#ifdef GFX
#define POLYMAX 60000
#define USEPOLY
#endif
#ifdef USEPOLY
GLfloat *ourshape = NULL; GLfloat *ourshape = NULL;
void initPolyForGL() { void initPolyForGL() {
@ -159,23 +184,10 @@ void initPolyForGL() {
ourshape[id++] = hpc[i][2]; ourshape[id++] = hpc[i][2];
} }
#ifdef GL
currentvertices = NULL; currentvertices = NULL;
#endif
} }
void activateShapes() {
if(currentvertices != ourshape) {
activateVertexArray(ourshape, qhpc);
}
}
void activateGlcoords() {
activateVertexArray(glcoords[0], qglcoords);
}
#ifdef GFX
#define POLYMAX 60000
#define USEPOLY
#endif #endif
int polyi; int polyi;
@ -189,6 +201,7 @@ hyperpoint gltopoint(GLfloat t[3]) {
} }
void addpoint(const hyperpoint& H) { void addpoint(const hyperpoint& H) {
#ifdef GL
if(vid.usingGL) { if(vid.usingGL) {
if(polyi >= POLYMAX) return; if(polyi >= POLYMAX) return;
if(pmodel) { if(pmodel) {
@ -211,6 +224,9 @@ void addpoint(const hyperpoint& H) {
} }
qglcoords++; qglcoords++;
} }
#else
if(0) {}
#endif
else { else {
if(polyi >= POLYMAX) return; if(polyi >= POLYMAX) return;
hyperpoint Hscr; hyperpoint Hscr;
@ -256,6 +272,7 @@ void filledPolygonColorI(SDL_Surface *s, int* polyx, int *polyy, int polyi, int
} }
#endif #endif
#ifdef GL
void glcolor2(int color) { void glcolor2(int color) {
unsigned char *c = (unsigned char*) (&color); unsigned char *c = (unsigned char*) (&color);
glColor4f(c[3] / 255.0, c[2] / 255.0, c[1]/255.0, c[0] / 255.0); glColor4f(c[3] / 255.0, c[2] / 255.0, c[1]/255.0, c[0] / 255.0);
@ -339,6 +356,21 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
if(useV) glPopMatrix(); if(useV) glPopMatrix();
} }
} }
#endif
double linewidthat(const hyperpoint& h) {
if(vid.antialias & AA_LINEWIDTH) {
double dz = h[2];
if(dz < 1 || abs(dz-vid.scrdist) < 1e-6) return vid.linewidth;
else {
double dx = sqrt(dz * dz - 1);
double dfc = dx/(dz+1);
dfc = 1 - dfc*dfc;
return dfc * vid.linewidth;
}
}
return vid.linewidth;
}
void drawpolyline(const transmatrix& V, GLfloat* tab, int cnt, int col, int outline) { void drawpolyline(const transmatrix& V, GLfloat* tab, int cnt, int col, int outline) {
#ifdef GL #ifdef GL
@ -348,6 +380,7 @@ void drawpolyline(const transmatrix& V, GLfloat* tab, int cnt, int col, int outl
if(currentvertices != tab) if(currentvertices != tab)
activateVertexArray(tab, pq); activateVertexArray(tab, pq);
const int ps=0; const int ps=0;
glLineWidth(linewidthat(tC0(V)));
gldraw(1, V, ps, pq, col, outline); gldraw(1, V, ps, pq, col, outline);
} }
else { else {
@ -388,7 +421,7 @@ void drawpolyline(const transmatrix& V, GLfloat* tab, int cnt, int col, int outl
filledPolygonColorI(s, polyx, polyy, polyi, col); filledPolygonColorI(s, polyx, polyy, polyi, col);
if(vid.goteyes) filledPolygonColorI(aux, polyxr, polyy, polyi, col); if(vid.goteyes) filledPolygonColorI(aux, polyxr, polyy, polyi, col);
(vid.usingAA?aapolylineColor:polylineColor)(s, polyx, polyy, polyi, outline); ((vid.antialias & AA_NOGL) ?aapolylineColor:polylineColor)(s, polyx, polyy, polyi, outline);
if(vid.goteyes) aapolylineColor(aux, polyxr, polyy, polyi, outline); if(vid.goteyes) aapolylineColor(aux, polyxr, polyy, polyi, outline);
if(vid.xres >= 2000 || fatborder) { if(vid.xres >= 2000 || fatborder) {
@ -448,6 +481,7 @@ void drawqueueitem(polytodraw& ptd) {
drawpolyline(ptd.u.poly.V, ptd.u.poly.tab, ptd.u.poly.cnt, ptd.col, ptd.u.poly.outline); drawpolyline(ptd.u.poly.V, ptd.u.poly.tab, ptd.u.poly.cnt, ptd.col, ptd.u.poly.outline);
} }
else if(ptd.kind == pkLine) { else if(ptd.kind == pkLine) {
dynamicval<ld> d(vid.linewidth, ptd.u.line.width);
prettyline(ptd.u.line.H1, ptd.u.line.H2, ptd.col, ptd.u.line.prf); prettyline(ptd.u.line.H1, ptd.u.line.H2, ptd.col, ptd.u.line.prf);
} }
else if(ptd.kind == pkString) { else if(ptd.kind == pkString) {
@ -456,13 +490,8 @@ void drawqueueitem(polytodraw& ptd) {
if(svg::in) if(svg::in)
svg::text(q.x, q.y, q.size, q.str, q.frame, ptd.col, q.align); svg::text(q.x, q.y, q.size, q.str, q.frame, ptd.col, q.align);
else { else {
if(q.frame) { int fr = q.frame & 255;
displaystr(q.x-q.frame, q.y, q.shift, q.size, q.str, 0, q.align); displayfrSP(q.x, q.y, q.shift, fr, q.size, q.str, ptd.col, q.align, q.frame >> 8);
displaystr(q.x+q.frame, q.y, q.shift, q.size, q.str, 0, q.align);
displaystr(q.x, q.y-q.frame, q.shift, q.size, q.str, 0, q.align);
displaystr(q.x, q.y+q.frame, q.shift, q.size, q.str, 0, q.align);
}
displaystr(q.x, q.y, q.shift, q.size, q.str, ptd.col, q.align);
} }
#else #else
displayfr(q.x, q.y, q.frame, q.size, q.str, ptd.col, q.align); displayfr(q.x, q.y, q.frame, q.size, q.str, ptd.col, q.align);
@ -489,6 +518,12 @@ void drawqueueitem(polytodraw& ptd) {
} }
SDL_UnlockSurface(aux); SDL_UnlockSurface(aux);
} }
#endif
}
void initquickqueue() {
ptds.clear();
poly_outline = OUTLINE_NONE;
} }
void quickqueue() { void quickqueue() {
@ -565,13 +600,13 @@ void drawqueue() {
drawqueueitem(ptd); drawqueueitem(ptd);
} }
#ifdef GL
if(vid.goteyes && vid.usingGL) selectEyeGL(0), selectEyeMask(0); if(vid.goteyes && vid.usingGL) selectEyeGL(0), selectEyeMask(0);
#endif
#endif #endif
setcameraangle(false); setcameraangle(false);
curvedata.clear(); curvestart = 0; curvedata.clear(); curvestart = 0;
#endif
} }
hpcshape hpcshape
@ -1574,8 +1609,6 @@ void initShape(int sg, int id) {
} }
} }
int poly_outline;
unsigned char& part(int& col, int i) { unsigned char& part(int& col, int i) {
unsigned char* c = (unsigned char*) &col; return c[i]; unsigned char* c = (unsigned char*) &col; return c[i];
} }
@ -1698,6 +1731,7 @@ void queueline(const hyperpoint& H1, const hyperpoint& H2, int col, int prf = 0,
ptd.u.line.H1 = H1; ptd.u.line.H1 = H1;
ptd.u.line.H2 = H2; ptd.u.line.H2 = H2;
ptd.u.line.prf = prf; ptd.u.line.prf = prf;
ptd.u.line.width = (linewidthat(H1) + linewidthat(H2)) / 2;
ptd.col = (darkened(col >> 8) << 8) + (col & 0xFF); ptd.col = (darkened(col >> 8) << 8) + (col & 0xFF);
ptd.prio = prio << PSHIFT; ptd.prio = prio << PSHIFT;
} }
@ -1713,7 +1747,7 @@ void queuestr(int x, int y, int shift, int size, string str, int col, int frame
ptd.u.chr.shift = shift; ptd.u.chr.shift = shift;
ptd.u.chr.size = size; ptd.u.chr.size = size;
ptd.col = darkened(col); ptd.col = darkened(col);
ptd.u.chr.frame = frame; ptd.u.chr.frame = frame ? (poly_outline & ~ 255) : 0;
ptd.prio = PPR_TEXT << PSHIFT; ptd.prio = PPR_TEXT << PSHIFT;
} }
@ -1728,7 +1762,7 @@ void queuechr(int x, int y, int shift, int size, char chr, int col, int frame =
ptd.u.chr.size = size; ptd.u.chr.size = size;
ptd.u.chr.align = align; ptd.u.chr.align = align;
ptd.col = col; ptd.col = col;
ptd.u.chr.frame = frame; ptd.u.chr.frame = frame ? (poly_outline & ~ 255) : 0;
ptd.prio = PPR_TEXT << PSHIFT; ptd.prio = PPR_TEXT << PSHIFT;
} }
@ -1912,6 +1946,7 @@ namespace svg {
dynamicval<videopar> v(vid, vid); dynamicval<videopar> v(vid, vid);
dynamicval<bool> v2(in, true); dynamicval<bool> v2(in, true);
dynamicval<int> v4(cheater, 0); dynamicval<int> v4(cheater, 0);
dynamicval<int> v5(ringcolor, 0x808080FF);
vid.usingGL = false; vid.usingGL = false;
vid.xres = vid.yres = svgsize ? svgsize : min(1 << (sightrange+7), 16384); vid.xres = vid.yres = svgsize ? svgsize : min(1 << (sightrange+7), 16384);

View File

@ -163,11 +163,26 @@ void createViz(int id, cell *c, transmatrix at) {
vd.m->at = at; vd.m->at = at;
} }
void notimpl() {
printf("Not implemented\n"); exit(1);
}
hyperpoint where(int i) {
auto m = vdata[i].m;
if(m->base == currentmap->gamestart()) return tC0(m->at);
else {
notimpl(); // actually probably that's a buug
return inverse(shmup::ggmatrix(currentmap->gamestart())) * (shmup::ggmatrix(m->base) * tC0(m->at));
}
}
void addedge(int i, int j, edgeinfo *ei) { void addedge(int i, int j, edgeinfo *ei) {
double d = hdist(vdata[i].m->at * C0, vdata[j].m->at * C0); hyperpoint hi = where(i);
hyperpoint hj = where(j);
double d = hdist(hi, hj);
if(d >= 4) { if(d >= 4) {
// printf("splitting %lf\n", d); // printf("splitting %lf\n", d);
hyperpoint h = mid(vdata[i].m->at * C0, vdata[j].m->at * C0); hyperpoint h = mid(hi, hj);
int id = size(vdata); int id = size(vdata);
vdata.resize(id+1); vdata.resize(id+1);
vertexdata& vd(vdata[id]); vertexdata& vd(vdata[id]);
@ -178,6 +193,7 @@ void addedge(int i, int j, edgeinfo *ei) {
addedge(i, id, ei); addedge(i, id, ei);
addedge(id, j, ei); addedge(id, j, ei);
shmup::virtualRebase(vd.m, true);
} }
else addedge0(i, j, ei); else addedge0(i, j, ei);
} }
@ -204,7 +220,14 @@ int dftcolor = 0x282828FF;
namespace spiral { namespace spiral {
void place(int N, ld mul) { ld mul;
transmatrix at(double d) {
return spin(log(d) * 2 * M_PI / log(mul)) * xpush(log(d));
}
void place(int N, ld _mul) {
mul = _mul;
init(); kind = kSpiral; init(); kind = kSpiral;
vdata.resize(N); vdata.resize(N);
@ -213,7 +236,7 @@ namespace spiral {
double d = i + 1; double d = i + 1;
transmatrix h = spin(log(d) * 2 * M_PI / log(mul)) * xpush(log(d)); transmatrix h = at(d);
createViz(i, cwt.c, h); createViz(i, cwt.c, h);
vd.name = its(i+1); vd.name = its(i+1);
@ -265,17 +288,35 @@ namespace collatz {
} }
} }
int readLabel(FILE *f) { string readLabel_s(FILE *f) {
char xlabel[10000]; char xlabel[10000];
if(fscanf(f, "%9500s", xlabel) <= 0) return -1; if(fscanf(f, "%9500s", xlabel) <= 0) return "";
return getid(xlabel); return xlabel;
}
int readLabel(FILE *f) {
string s = readLabel_s(f);
if(s == "") return -1;
return getid(s);
} }
namespace anygraph { namespace anygraph {
double R, alpha, T; double R, alpha, T;
vector<pair<double, double> > coords; vector<pair<double, double> > coords;
void read(string fn, bool subdiv = true, bool doRebase = true) { int N;
void fixedges() {
for(int i=N; i<size(vdata); i++) if(vdata[i].m) vdata[i].m->dead = true;
for(int i=0; i<size(vdata); i++) vdata[i].edges.clear();
vdata.resize(N);
for(auto e: edgeinfos) {
e->orig = NULL;
addedge(e->i, e->j, e);
}
}
void read(string fn, bool subdiv = true, bool doRebase = true, bool doStore = true) {
init(); kind = kAnyGraph; init(); kind = kAnyGraph;
fname = fn; fname = fn;
FILE *f = fopen((fn + "-coordinates.txt").c_str(), "rt"); FILE *f = fopen((fn + "-coordinates.txt").c_str(), "rt");
@ -285,17 +326,17 @@ namespace anygraph {
} }
printf("Reading coordinates...\n"); printf("Reading coordinates...\n");
char buf[100]; char buf[100];
int N;
int err; int err;
err = fscanf(f, "%s%s%s%s%d%lf%lf%lf", buf, buf, buf, buf, &N, err = fscanf(f, "%s%s%s%s%d%lf%lf%lf", buf, buf, buf, buf, &N,
&anygraph::R, &anygraph::alpha, &anygraph::T); &anygraph::R, &anygraph::alpha, &anygraph::T);
if(err < 8) { printf("Error: incorrect format of the first line\n"); exit(1); } if(err < 8) { printf("Error: incorrect format of the first line\n"); exit(1); }
vdata.reserve(N); vdata.reserve(N);
while(true) { while(true) {
int id = readLabel(f); string s = readLabel_s(f);
if(id < 0) break; if(s == "" || s == "-1") break;
int id = getid(s);
vertexdata& vd(vdata[id]); vertexdata& vd(vdata[id]);
vd.name = its(id); vd.name = s;
vd.cp = colorpair(dftcolor); vd.cp = colorpair(dftcolor);
double r, alpha; double r, alpha;
@ -333,6 +374,8 @@ namespace anygraph {
} }
printf("Done.\n"); printf("Done.\n");
} }
if(doStore) storeall();
} }
} }
@ -1031,7 +1074,6 @@ void drawVertex(const transmatrix &V, cell *c, shmup::monster *m) {
transmatrix& gm1 = shmup::ggmatrix(vd1.m->base); transmatrix& gm1 = shmup::ggmatrix(vd1.m->base);
transmatrix& gm2 = shmup::ggmatrix(vd2.m->base); transmatrix& gm2 = shmup::ggmatrix(vd2.m->base);
hyperpoint h1 = gm1 * vd1.m->at * C0; hyperpoint h1 = gm1 * vd1.m->at * C0;
hyperpoint h2 = gm2 * vd2.m->at * C0; hyperpoint h2 = gm2 * vd2.m->at * C0;
@ -1046,19 +1088,47 @@ void drawVertex(const transmatrix &V, cell *c, shmup::monster *m) {
} */ } */
int col = int col =
((hilite ? 0xFF0000 : backcolor ? 0x808080 : 0xFFFFFF) << 8) + xlalpha; ((hilite ? 0xFF0000 : forecolor) << 8) + xlalpha;
if(pmodel) { bool onspiral = kind == kSpiral && abs(ei->i - ei->j) == 1;
if(pmodel || onspiral) {
if(onspiral) {
const int prec = 20;
transmatrix T = shmup::ggmatrix(currentmap->gamestart());
hyperpoint l1 = T*tC0(spiral::at(1+ei->i));
for(int z=1; z<=prec; z++) {
hyperpoint l2 = T*tC0(spiral::at(1+ei->i+(ei->j-ei->i) * z / (prec+.0)));
queueline(l1, l2, col, 0);
l1 = l2;
lastptd().prio = PPR_STRUCT0;
}
}
else {
queueline(h1, h2, col, 2); queueline(h1, h2, col, 2);
lastptd().prio = PPR_STRUCT0; lastptd().prio = PPR_STRUCT0;
} }
}
else { else {
if(ei->orig && ei->orig->cpdist >= 3) ei->orig = NULL; if(ei->orig && ei->orig->cpdist >= 3) ei->orig = NULL;
if(!ei->orig) { if(!ei->orig) {
ei->orig = euclid ? cwt.c : viewctr.h->c7; // cwt.c; ei->orig = euclid ? cwt.c : viewctr.h->c7; // cwt.c;
ei->prec.clear(); ei->prec.clear();
transmatrix T = inverse(shmup::ggmatrix(ei->orig)); transmatrix T = inverse(shmup::ggmatrix(ei->orig));
if(kind == kSpiral && abs(ei->i - ei->j) == 1) {
ei->orig = currentmap->gamestart();
hyperpoint l1 = tC0(spiral::at(1+ei->i));
storevertex(ei->prec, l1);
const int prec = 20;
for(int z=1; z<=prec; z++) {
hyperpoint l2 = tC0(spiral::at(1+ei->i+(ei->j-ei->i) * z / (prec+.0)));
storeline(ei->prec, l1, l2);
l1 = l2;
}
}
else
storeline(ei->prec, T*h1, T*h2); storeline(ei->prec, T*h1, T*h2);
} }
queuetable(shmup::ggmatrix(ei->orig), &ei->prec[0], size(ei->prec)/3, col, 0, queuetable(shmup::ggmatrix(ei->orig), &ei->prec[0], size(ei->prec)/3, col, 0,
@ -1180,12 +1250,15 @@ void drawExtra() {
for(int i=0; i<size(named); i++) if(gmatrix.count(named[i])) { for(int i=0; i<size(named); i++) if(gmatrix.count(named[i])) {
string s = ""; s += 'A'+i; string s = ""; s += 'A'+i;
queuestr(gmatrix[named[i]], 1, s, backcolor ? 0 : 0xFFFFFF, 1); queuestr(gmatrix[named[i]], 1, s, forecolor, 1);
} }
canmove = true; items[itOrbAether] = true; canmove = true; items[itOrbAether] = true;
} }
#ifndef NORUG
if(!rug::rugged)
#endif
for(int i=0; i<size(legend); i++) { for(int i=0; i<size(legend); i++) {
int k = legend[i]; int k = legend[i];
vertexdata& vd = vdata[k]; vertexdata& vd = vdata[k];
@ -1199,7 +1272,8 @@ void drawExtra() {
poly_outline = OUTLINE_NONE; poly_outline = OUTLINE_NONE;
queuedisk(V, vd.cp, true); queuedisk(V, vd.cp, true);
queuestr(int(x-rad), int(y), 0, rad*(svg::in?5:3)/4, vd.name, backcolor ? 0 : 0xFFFFFF, 0, 16); poly_outline = OUTLINE_DEFAULT;
queuestr(int(x-rad), int(y), 0, rad*(svg::in?5:3)/4, vd.name, forecolor, 0, 16);
} }
} }
@ -1271,6 +1345,7 @@ void init() {
mapeditor::drawplayer = false; mapeditor::drawplayer = false;
firstland = euclidland = laCanvas; firstland = euclidland = laCanvas;
if(!shmup::on) restartGame('s'); if(!shmup::on) restartGame('s');
else restartGame();
#else #else
firstland = euclidland = laCanvas; firstland = euclidland = laCanvas;
restartGame(); restartGame();
@ -1310,6 +1385,7 @@ void fixparam() {
if(size(legend)) vid.xcenter = vid.ycenter; if(size(legend)) vid.xcenter = vid.ycenter;
} }
#ifndef NOSDL
void rvvideo(const char *fname) { void rvvideo(const char *fname) {
if(kind == kCollatz) { if(kind == kCollatz) {
pngformat = 2; pngformat = 2;
@ -1465,6 +1541,7 @@ struct storydata { int s; int e; const char *text; } story[] = {
saveHighQualityShot(buf); saveHighQualityShot(buf);
} }
} }
#endif
int readArgs() { int readArgs() {
using namespace arg; using namespace arg;
@ -1636,9 +1713,11 @@ int readArgs() {
else if(argis("-TURN")) { else if(argis("-TURN")) {
PHASE(3); shmup::turn(100); PHASE(3); shmup::turn(100);
} }
#ifndef NOSDL
else if(argis("-video")) { else if(argis("-video")) {
shift(); rvvideo(args()); shift(); rvvideo(args());
} }
#endif
else return 1; else return 1;
return 0; return 0;
} }
@ -1674,7 +1753,7 @@ void handleMenu(int sym, int uni) {
else if(uni == 'l') showlabels = !showlabels; else if(uni == 'l') showlabels = !showlabels;
else if(uni == 'v') rog3 = !rog3; else if(uni == 'v') rog3 = !rog3;
else if(uni == 'x') specialmark = !specialmark; else if(uni == 'x') specialmark = !specialmark;
else if(uni == 'b') backcolor ^= 0xFFFFFF; else if(uni == 'b') backcolor ^= 0xFFFFFF, bordcolor ^= 0xFFFFFF, forecolor ^= 0xFFFFFF;
else if(uni == 'g') { else if(uni == 'g') {
dialog::editNumber(ggamma, 0, 5, .01, 0.5, XLAT("gamma value for edges"), ""); dialog::editNumber(ggamma, 0, 5, .01, 0.5, XLAT("gamma value for edges"), "");
dialog::sidedialog = true; dialog::sidedialog = true;
@ -1739,8 +1818,26 @@ template<class T> function<void(presmode)> roguevizslide(char c, T t) {
}; };
} }
template<class T, class T1> function<void(presmode)> roguevizslide_action(char c, T t, T1 act) {
return [c,t,act] (presmode mode) {
mapeditor::canvasback = 0x101010;
setCanvas(mode, c);
if(mode == 1 || mode == pmGeometryStart) t();
if(mode == 3 || mode == pmGeometry || mode == pmGeometryReset) {
rogueviz::close();
shmup::clearMonsters();
if(mode == pmGeometryReset) t();
}
act(mode);
};
}
#define RVPATH HYPERPATH "rogueviz/"
slide rvslides[] = { slide rvslides[] = {
{"HyperRogue", 999, LEGAL_ANY, {"RogueViz", 999, LEGAL_ANY,
"This is a presentation of RogueViz, which " "This is a presentation of RogueViz, which "
"is an adaptation of HyperRogue as a visualization tool " "is an adaptation of HyperRogue as a visualization tool "
"rather than a game. Hyperbolic space is great " "rather than a game. Hyperbolic space is great "
@ -1751,6 +1848,7 @@ slide rvslides[] = {
, ,
[] (presmode mode) { [] (presmode mode) {
slidecommand = "the standard presentation"; slidecommand = "the standard presentation";
if(mode == pmStartAll) firstland = euclidland = laPalace;
if(mode == 4) { if(mode == 4) {
tour::slides = default_slides; tour::slides = default_slides;
while(tour::on) restartGame('T', false); while(tour::on) restartGame('T', false);
@ -1759,7 +1857,7 @@ slide rvslides[] = {
} }
} }
}, },
{"HyperRogue", 999, LEGAL_ANY, {"straight lines in the Palace", 999, LEGAL_ANY,
"One simple slide about HyperRogue. Press '5' to show some hyperbolic straight lines.", "One simple slide about HyperRogue. Press '5' to show some hyperbolic straight lines.",
[] (presmode mode) { [] (presmode mode) {
using namespace linepatterns; using namespace linepatterns;
@ -1812,9 +1910,9 @@ slide rvslides[] = {
drawthemap(); drawthemap();
gmatrix0 = gmatrix; gmatrix0 = gmatrix;
rogueviz::sag::read("rogueviz/roguelikes/edges.csv"); rogueviz::sag::read(RVPATH "roguelikes/edges.csv");
rogueviz::readcolor("rogueviz/roguelikes/color.csv"); rogueviz::readcolor(RVPATH "roguelikes/color.csv");
rogueviz::sag::loadsnake("rogueviz/roguelikes/" + cname()); rogueviz::sag::loadsnake(RVPATH "roguelikes/" + cname());
}) })
}, },
{"Programming languages of GitHub", 64, LEGAL_UNLIMITED, {"Programming languages of GitHub", 64, LEGAL_UNLIMITED,
@ -1832,9 +1930,9 @@ slide rvslides[] = {
drawthemap(); drawthemap();
gmatrix0 = gmatrix; gmatrix0 = gmatrix;
rogueviz::sag::read("rogueviz/lang/edges.csv"); rogueviz::sag::read(RVPATH "lang/edges.csv");
rogueviz::readcolor("rogueviz/lang/color.csv"); rogueviz::readcolor(RVPATH "lang/color.csv");
rogueviz::sag::loadsnake("rogueviz/lang/" + cname()); rogueviz::sag::loadsnake(RVPATH "lang/" + cname());
if(euclid) rogueviz::legend.clear(); if(euclid) rogueviz::legend.clear();
}) })
}, },
@ -1853,9 +1951,9 @@ slide rvslides[] = {
drawthemap(); drawthemap();
gmatrix0 = gmatrix; gmatrix0 = gmatrix;
rogueviz::sag::read("rogueviz/boardgames/edges.csv"); rogueviz::sag::read(RVPATH "boardgames/edges.csv");
rogueviz::readcolor("rogueviz/boardgames/color.csv"); rogueviz::readcolor(RVPATH "boardgames/color.csv");
rogueviz::sag::loadsnake("rogueviz/boardgames/" + cname()); rogueviz::sag::loadsnake(RVPATH "boardgames/" + cname());
}) })
}, },
{"Tree of Life", 61, LEGAL_UNLIMITED, {"Tree of Life", 61, LEGAL_UNLIMITED,
@ -1872,7 +1970,7 @@ slide rvslides[] = {
drawthemap(); drawthemap();
gmatrix0 = gmatrix; gmatrix0 = gmatrix;
rogueviz::tree::read("rogueviz/treeoflife/tol.txt"); rogueviz::tree::read(RVPATH "treeoflife/tol.txt");
})}, })},
{"THE END", 99, LEGAL_ANY | FINALSLIDE, {"THE END", 99, LEGAL_ANY | FINALSLIDE,
"Press '5' to leave the presentation.", "Press '5' to leave the presentation.",

16
rug.cpp
View File

@ -8,6 +8,7 @@
#define TEXTURESIZE (texturesize) #define TEXTURESIZE (texturesize)
#define HTEXTURESIZE (texturesize/2) #define HTEXTURESIZE (texturesize/2)
#ifdef AVOID_GLEW
#ifdef LINUX #ifdef LINUX
extern "C" { extern "C" {
GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
@ -27,6 +28,7 @@ GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers)
#ifdef MAC #ifdef MAC
#define glFramebufferTexture glFramebufferTextureEXT #define glFramebufferTexture glFramebufferTextureEXT
#endif #endif
#endif
namespace rug { namespace rug {
@ -389,7 +391,11 @@ void initTexture() {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
#ifdef TEX
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);
#else
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderedTexture, 0);
#endif
GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers); glDrawBuffers(1, DrawBuffers);
@ -467,6 +473,11 @@ void closeTexture() {
double xview, yview; double xview, yview;
void glcolorClear(int color) {
unsigned char *c = (unsigned char*) (&color);
glClearColor(c[3] / 255.0, c[2] / 255.0, c[1]/255.0, c[0] / 255.0);
}
void drawRugScene() { void drawRugScene() {
GLfloat light_ambient[] = { 3.5, 3.5, 3.5, 1.0 }; GLfloat light_ambient[] = { 3.5, 3.5, 3.5, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
@ -490,7 +501,10 @@ void drawRugScene() {
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
if(backcolor == 0)
glClearColor(0.05,0.05,0.05,1); glClearColor(0.05,0.05,0.05,1);
else
glcolorClear(backcolor << 8 | 0xFF);
glClearDepth(1.0f); glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -555,7 +569,7 @@ transmatrix rotmatrix(double rotation, int c0, int c1) {
transmatrix currentrot; transmatrix currentrot;
void init() { void init() {
#ifdef WINDOWS #ifndef AVOID_GLEW
if(!glew) { if(!glew) {
glew = true; glew = true;
GLenum err = glewInit(); GLenum err = glewInit();

View File

@ -573,9 +573,9 @@ void initConfig() {
char* t = vid.scfg.keyaction; char* t = vid.scfg.keyaction;
t['w'] = 16 + 4; t['w'] = 16 + 4;
t['s'] = 16 + 5; t['d'] = 16 + 5;
t['a'] = 16 + 6; t['s'] = 16 + 6;
t['d'] = 16 + 7; t['a'] = 16 + 7;
#ifndef MOBILE #ifndef MOBILE
t[SDLK_KP8] = 16 + 4; t[SDLK_KP8] = 16 + 4;
@ -2925,7 +2925,9 @@ void turn(int delta) {
} }
} }
for(monster *m: additional) active.push_back(m); additional.clear(); for(monster *m: additional)
active.push_back(m);
additional.clear();
// deactivate all monsters // deactivate all monsters
for(monster *m: active) for(monster *m: active)

View File

@ -69,9 +69,8 @@ void handlemusic() {
DEBB(DF_GRAPH, (debugfile,"handle music\n")); DEBB(DF_GRAPH, (debugfile,"handle music\n"));
if(audio && musicvolume) { if(audio && musicvolume) {
eLand id = getCurrentLandForMusic(); eLand id = getCurrentLandForMusic();
#ifdef LOCAL #ifdef EXTRA_MUSIC
extern bool local_changemusic(eLand& id); if(extra::changemusic(id)) return;
if(local_changemusic(id)) return;
#endif #endif
if(outoffocus) id = eLand(0); if(outoffocus) id = eLand(0);
if(musfname[id] == "LAST") id = cid; if(musfname[id] == "LAST") id = cid;
@ -154,6 +153,7 @@ bool loadMusicInfo(string dir) {
bool loadMusicInfo() { bool loadMusicInfo() {
return return
loadMusicInfo(musicfile) loadMusicInfo(musicfile)
|| loadMusicInfo(HYPERPATH "hyperrogue-music.txt")
|| loadMusicInfo("./hyperrogue-music.txt") || loadMusicInfo("./hyperrogue-music.txt")
|| loadMusicInfo("music/hyperrogue-music.txt") || loadMusicInfo("music/hyperrogue-music.txt")
// Destination set by ./configure (in the GitHub repository) // Destination set by ./configure (in the GitHub repository)
@ -187,7 +187,7 @@ map<string, Mix_Chunk*> chunks;
#ifdef SOUNDDESTDIR #ifdef SOUNDDESTDIR
string wheresounds = SOUNDDESTDIR; string wheresounds = SOUNDDESTDIR;
#else #else
string wheresounds = "sounds/"; string wheresounds = HYPERPATH "sounds/";
#endif #endif
void playSound(cell *c, const string& fname, int vol) { void playSound(cell *c, const string& fname, int vol) {

View File

@ -26,6 +26,8 @@ void initgame() {
firstland = safetyland; firstland = safetyland;
} }
if(peace::on) euclidland = firstland = peace::whichland;
if(tactic::on && (euclid || sphere)) euclidland = firstland; if(tactic::on && (euclid || sphere)) euclidland = firstland;
if(firstland == laNone || firstland == laBarrier) if(firstland == laNone || firstland == laBarrier)
@ -50,7 +52,7 @@ void initgame() {
setdist(cwt.c, BARLEV, NULL); setdist(cwt.c, BARLEV, NULL);
if((tactic::on || yendor::on) && isCyclic(firstland)) { if((tactic::on || yendor::on || peace::on) && isCyclic(firstland)) {
anthraxBonus = items[itHolyGrail]; anthraxBonus = items[itHolyGrail];
cwt.c->mov[0]->land = firstland; cwt.c->mov[0]->land = firstland;
if(firstland == laWhirlpool) cwt.c->mov[0]->wall = waSea; if(firstland == laWhirlpool) cwt.c->mov[0]->wall = waSea;
@ -149,6 +151,8 @@ void initgame() {
items[treasureType(firstland)] = 15; items[treasureType(firstland)] = 15;
yendor::init(3); yendor::init(3);
peace::simon::init();
multi::revive_queue.clear(); multi::revive_queue.clear();
#ifdef TOUR #ifdef TOUR
if(tour::on) tour::presentation(tour::pmRestart); if(tour::on) tour::presentation(tour::pmRestart);
@ -178,7 +182,10 @@ void initgame() {
timerghost = true; timerghost = true;
truelotus = 0; truelotus = 0;
survivalist = true; survivalist = true;
if(!randomPatternsMode && !tactic::on && !yendor::on) { #ifdef INV
if(inv::on) inv::init();
#endif
if(!randomPatternsMode && !tactic::on && !yendor::on && !peace::on) {
if(firstland != (princess::challenge ? laPalace : laIce)) cheater++; if(firstland != (princess::challenge ? laPalace : laIce)) cheater++;
} }
if(tactic::trailer) ; if(tactic::trailer) ;
@ -206,6 +213,7 @@ void initgame() {
addMessage(XLAT("You are playing %the1 in the Pure Tactics mode.", firstland)); addMessage(XLAT("You are playing %the1 in the Pure Tactics mode.", firstland));
else if(yendor::on) else if(yendor::on)
addMessage(XLAT("Welcome to the Yendor Challenge %1!", its(yendor::challenge))); addMessage(XLAT("Welcome to the Yendor Challenge %1!", its(yendor::challenge)));
else if(peace::on) ; // no welcome message
else if(shmup::on) ; // welcome message given elsewhere else if(shmup::on) ; // welcome message given elsewhere
else if(euclid) else if(euclid)
addMessage(XLAT("Welcome to the Euclidean mode!")); addMessage(XLAT("Welcome to the Euclidean mode!"));
@ -598,7 +606,7 @@ void loadBoxHigh() {
// certify that saves and achievements were received // certify that saves and achievements were received
// in an official version of HyperRogue // in an official version of HyperRogue
#ifdef CERTIFY #ifdef CERTIFY
#include "certify.cpp" #include "private/certify.cpp"
#else #else
namespace anticheat { namespace anticheat {
@ -636,6 +644,7 @@ void saveStats(bool emergency = false) {
if(tour::on) return; if(tour::on) return;
#endif #endif
if(randomPatternsMode) return; if(randomPatternsMode) return;
if(peace::on) return;
remove_emergency_save(); remove_emergency_save();
@ -718,6 +727,7 @@ void saveStats(bool emergency = false) {
if(purehepta) fprintf(f, "Heptagons only mode\n"); if(purehepta) fprintf(f, "Heptagons only mode\n");
if(chaosmode) fprintf(f, "Chaos mode\n"); if(chaosmode) fprintf(f, "Chaos mode\n");
if(shmup::on) fprintf(f, "Shoot-em up mode\n"); if(shmup::on) fprintf(f, "Shoot-em up mode\n");
if(inv::on) fprintf(f, "Inventory mode\n");
if(multi::players > 1) fprintf(f, "Multi-player (%d players)\n", multi::players); if(multi::players > 1) fprintf(f, "Multi-player (%d players)\n", multi::players);
fprintf(f, "Number of cells explored, by distance from the player:\n"); fprintf(f, "Number of cells explored, by distance from the player:\n");
{for(int i=0; i<10; i++) fprintf(f, " %d", explore[i]);} fprintf(f, "\n"); {for(int i=0; i<10; i++) fprintf(f, " %d", explore[i]);} fprintf(f, "\n");
@ -951,6 +961,16 @@ void restartGame(char switchWhat, bool push) {
cellcount = 0; cellcount = 0;
clearMemory(); clearMemory();
} }
if(switchWhat == 'P') {
peace::on = !peace::on;
tactic::on = yendor::on = princess::challenge =
randomPatternsMode = inv::on = false;
}
if(switchWhat == 'i') {
inv::on = !inv::on;
tactic::on = yendor::on = princess::challenge =
randomPatternsMode = peace::on = false;
}
if(switchWhat == 'C') { if(switchWhat == 'C') {
geometry = gNormal; geometry = gNormal;
yendor::on = tactic::on = princess::challenge = false; yendor::on = tactic::on = princess::challenge = false;
@ -960,7 +980,7 @@ void restartGame(char switchWhat, bool push) {
#ifdef TOUR #ifdef TOUR
if(switchWhat == 'T') { if(switchWhat == 'T') {
geometry = gNormal; geometry = gNormal;
yendor::on = tactic::on = princess::challenge = false; yendor::on = tactic::on = princess::challenge = peace::on = inv::on = false;
chaosmode = purehepta = randomPatternsMode = false; chaosmode = purehepta = randomPatternsMode = false;
shmup::on = false; shmup::on = false;
resetGeometry(); resetGeometry();
@ -982,6 +1002,8 @@ void restartGame(char switchWhat, bool push) {
if(switchWhat == 'y') { if(switchWhat == 'y') {
yendor::on = !yendor::on; yendor::on = !yendor::on;
tactic::on = false; tactic::on = false;
peace::on = false;
inv::on = false;
princess::challenge = false; princess::challenge = false;
randomPatternsMode = false; randomPatternsMode = false;
chaosmode = false; chaosmode = false;
@ -990,6 +1012,8 @@ void restartGame(char switchWhat, bool push) {
if(switchWhat == 't') { if(switchWhat == 't') {
tactic::on = !tactic::on; tactic::on = !tactic::on;
yendor::on = false; yendor::on = false;
peace::on = false;
inv::on = false;
randomPatternsMode = false; randomPatternsMode = false;
princess::challenge = false; princess::challenge = false;
chaosmode = false; chaosmode = false;
@ -1003,6 +1027,8 @@ void restartGame(char switchWhat, bool push) {
randomPatternsMode = !randomPatternsMode; randomPatternsMode = !randomPatternsMode;
tactic::on = false; tactic::on = false;
yendor::on = false; yendor::on = false;
peace::on = false;
inv::on = false;
princess::challenge = false; princess::challenge = false;
} }
if(switchWhat == 'p') { if(switchWhat == 'p') {
@ -1012,6 +1038,7 @@ void restartGame(char switchWhat, bool push) {
tactic::on = false; tactic::on = false;
yendor::on = false; yendor::on = false;
chaosmode = false; chaosmode = false;
inv::on = false;
} }
initcells(); initcells();
@ -1385,11 +1412,9 @@ bool applyCheat(char u, cell *c = NULL) {
cblind = !cblind; cblind = !cblind;
return true; return true;
} }
#ifdef LOCAL if(u == 'P'-64)
if(u == 'K'-64) { peace::on = !peace::on;
printf("viewctr = %p.%d\n", viewctr.h, viewctr.spin); #ifdef CHEAT_DISABLE_ALLOWED
display(View);
}
if(u == 'D'-64) { if(u == 'D'-64) {
cheater = 0; autocheat = 0; cheater = 0; autocheat = 0;
return true; return true;

View File

@ -72,7 +72,7 @@ void presentation(presmode mode) {
} }
void slidehelp() { void slidehelp() {
if(texts) { if(texts && slides[currentslide].help[0]) {
help = help =
helptitle(XLAT(slides[currentslide].name), 0xFF8000) + helptitle(XLAT(slides[currentslide].name), 0xFF8000) +
XLAT(slides[currentslide].help); XLAT(slides[currentslide].help);
@ -87,7 +87,10 @@ bool handleKeyTour(int sym, int uni) {
if(!normode) return false; if(!normode) return false;
int flags = slides[currentslide].flags; int flags = slides[currentslide].flags;
if((sym == SDLK_RETURN || sym == SDLK_KP_ENTER) && (cmode != emHelp || (flags & QUICKSKIP))) { if((sym == SDLK_RETURN || sym == SDLK_KP_ENTER) && (cmode != emHelp || (flags & QUICKSKIP))) {
if(geometry || purehepta) { restartGame(0, false); return true; } if(geometry || purehepta) {
restartGame(0, false);
if(!(flags & QUICKGEO)) return true;
}
if(flags & FINALSLIDE) return true; if(flags & FINALSLIDE) return true;
presentation(pmStop); presentation(pmStop);
currentslide++; currentslide++;
@ -96,7 +99,10 @@ bool handleKeyTour(int sym, int uni) {
return true; return true;
} }
if(sym == SDLK_BACKSPACE) { if(sym == SDLK_BACKSPACE) {
if(geometry || purehepta) { restartGame(0, false); return true; } if(geometry || purehepta) {
restartGame(0, false);
if(!(flags & QUICKGEO)) return true;
}
if(currentslide == 0) { slidehelp(); return true; } if(currentslide == 0) { slidehelp(); return true; }
presentation(pmStop); presentation(pmStop);
currentslide--; currentslide--;
@ -207,6 +213,10 @@ bool handleKeyTour(int sym, int uni) {
conformal::includeHistory = !conformal::includeHistory; conformal::includeHistory = !conformal::includeHistory;
return true; return true;
} }
if(sym == '9') {
cmode = emSlideshows;
return true;
}
return false; return false;
} }
@ -225,12 +235,76 @@ void checkGoodLand(eLand l) {
} }
} }
namespace ss {
vector<slide*> slideshows;
slide *wts;
void list(slide *ss) {
for(auto s: slideshows) if (s == ss) return;
slideshows.push_back(ss);
}
int sssize;
void showMenu() {
if(!wts) wts = slides;
dialog::init(XLAT("slides"), forecolor, 150, 100);
for(sssize=0;; sssize++) {
int i = sssize;
dialog::addBoolItem(XLAT(wts[i].name), wts == slides && i == currentslide, 'a'+i);
if(wts[i].flags & FINALSLIDE) break;
}
dialog::addBreak(50);
if(size(slideshows) > 1) dialog::addItem(XLAT("change slideshow"), '1');
dialog::addItem(XLAT("exit menu"), '0');
dialog::display();
}
void handleKey(int sym, int uni) {
if(uni >= 'a' && uni < 'a' + sssize) {
if(geometry || purehepta) {
restartGame(0, false);
presentation(pmGeometryReset);
}
if(slides != wts) {
while(tour::on) restartGame('T', false);
slides = wts;
tour::start();
}
presentation(pmStop);
currentslide = uni - 'a';
cmode = emNormal;
presentation(pmStart);
slidehelp();
}
else if(uni == '1') {
list(wts);
for(int i=0; i<size(slideshows)-1; i++) if(slideshows[i] == wts) {
wts = slideshows[i+1]; return;
}
wts = slideshows[0];
}
else if(doexiton(sym, uni)) { wts = NULL; cmode = emNormal; }
}
}
void start() { void start() {
ss::list(default_slides);
#ifdef ROGUEVIZ
ss::list(rogueviz::rvtour::rvslides);
#endif
currentslide = 0; currentslide = 0;
vid.scale = 1; vid.scale = 1;
vid.alpha = 1; vid.alpha = 1;
pmodel = mdDisk; pmodel = mdDisk;
presentation(pmStartAll); if(!tour::on) presentation(pmStartAll);
else {
presentation(pmStop);
firstland = euclidland = laIce;
}
restartGame('T'); restartGame('T');
if(tour::on) { if(tour::on) {
slidehelp(); slidehelp();
@ -249,6 +323,7 @@ slide default_slides[] = {
"press ESC to see a " "press ESC to see a "
"menu with other options.", "menu with other options.",
[] (presmode mode) { [] (presmode mode) {
if(mode == pmStartAll) firstland = euclidland = laIce;
if(mode == 1) { if(mode == 1) {
if(tour::texts) addMessage(XLAT("Welcome to the HyperRogue tutorial!")); if(tour::texts) addMessage(XLAT("Welcome to the HyperRogue tutorial!"));
else clearMessages(); else clearMessages();
@ -265,7 +340,6 @@ slide default_slides[] = {
if(mode == 4) { if(mode == 4) {
slides = rogueviz::rvtour::rvslides; slides = rogueviz::rvtour::rvslides;
while(tour::on) restartGame('T', false); while(tour::on) restartGame('T', false);
firstland = euclidland = laPalace;
tour::start(); tour::start();
} }
#endif #endif
@ -637,10 +711,12 @@ slide default_slides[] = {
centerpc(INF); centerpc(INF);
conformal::includeHistory = false; conformal::includeHistory = false;
} }
#ifndef NOSDL
slidecommand = "render spiral"; slidecommand = "render spiral";
if(mode == 4) conformal::createImage(true); if(mode == 4) conformal::createImage(true);
if(mode == 11) conformal::create(); if(mode == 11) conformal::create();
if(mode == 13) conformal::clear(); if(mode == 13) conformal::clear();
#endif
} }
}, },
{"Conformal square model", 46, LEGAL_HYPERBOLIC, {"Conformal square model", 46, LEGAL_HYPERBOLIC,

View File

@ -5,6 +5,8 @@
// Yendor Quest, together with the Yendor Challenge // Yendor Quest, together with the Yendor Challenge
// also, the Pure Tactics Mode // also, the Pure Tactics Mode
namespace peace { extern bool on; }
#define MODECODES 254 #define MODECODES 254
int hiitemsMax(eItem it) { int hiitemsMax(eItem it) {
@ -151,6 +153,7 @@ namespace yendor {
int yii = NOYENDOR; int yii = NOYENDOR;
int hardness() { int hardness() {
if(peace::on) return 15; // just to generate monsters
int thf = 0; int thf = 0;
for(int i=0; i<size(yi); i++) { for(int i=0; i<size(yi); i++) {
yendorinfo& ye ( yi[i] ); yendorinfo& ye ( yi[i] );
@ -522,6 +525,46 @@ namespace yendor {
} }
else if(doexiton(sym, uni)) cmode = emNormal; else if(doexiton(sym, uni)) cmode = emNormal;
} }
void collected(cell* c2) {
int pg = gold();
playSound(c2, "tada");
items[itOrbShield] += 31;
for(int i=0; i<size(yendor::yi); i++)
if(yendor::yi[i].path[0] == c2)
yendor::yi[i].foundOrb = true;
// Shielding always, so that we know that it protects!
for(int i=0; i<4; i++) switch(hrand(13)) {
case 0: items[itOrbSpeed] += 31; break;
case 1: items[itOrbLightning] += 78; break;
case 2: items[itOrbFlash] += 78; break;
case 3: items[itOrbTime] += 78; break;
case 4: items[itOrbWinter] += 151; break;
case 5: items[itOrbDigging] += 151; break;
case 6: items[itOrbTeleport] += 151; break;
case 7: items[itOrbThorns] += 151; break;
case 8: items[itOrbInvis] += 151; break;
case 9: items[itOrbPsi] += 151; break;
case 10: items[itOrbAether] += 151; break;
case 11: items[itOrbFire] += 151; break;
case 12: items[itOrbSpace] += 78; break;
}
items[itOrbYendor]++;
items[itKey]--;
yendor::everwon = true;
if(yendor::on) {
yendor::won = true;
if(!cheater) {
dynamicval<bool> c(chaosmode, false);
yendor::bestscore[modecode()][yendor::challenge] =
max(yendor::bestscore[modecode()][yendor::challenge], items[itOrbYendor]);
yendor::uploadScore();
}
}
addMessage(XLAT("CONGRATULATIONS!"));
achievement_collection(itOrbYendor, pg, gold());
achievement_victory(false);
}
}; };
#define MAXTAC 20 #define MAXTAC 20
@ -795,6 +838,7 @@ int modecode() {
#endif #endif
if(quotient) return 6; if(quotient) return 6;
#endif #endif
if(peace::on) return 6;
int xcode = 0; int xcode = 0;
if(shmup::on) xcode += 2; if(shmup::on) xcode += 2;
@ -859,3 +903,166 @@ void buildmodetable() {
for(int i=0; i<newmodecode; i++) if(!codeused[i]) printf("// unused code: %d\n", i); for(int i=0; i<newmodecode; i++) if(!codeused[i]) printf("// unused code: %d\n", i);
printf("int newmodecode = %d;\n", newmodecode); printf("int newmodecode = %d;\n", newmodecode);
} }
namespace peace {
bool on = false;
bool hint = false;
bool otherpuzzles;
eLand whichland;
eLand simonlevels[] = {
laCrossroads, laCrossroads2, laDesert, laCaves, laAlchemist, laRlyeh, laEmerald,
laWineyard, laDeadCaves, laRedRock, laPalace,
laLivefjord, laDragon,
laNone
};
eLand explorelevels[] = {
laBurial, laTortoise, laCamelot, laPalace,
laIce, laJungle, laMirror, laDryForest, laCaribbean, laOcean, laZebra,
laOvergrown, laWhirlwind, laWarpCoast, laReptile,
laElementalWall, laAlchemist,
laNone
};
eLand *levellist;
int qty;
eLand getNext(eLand last) {
if(isElemental(last) && hrand(100) < 90)
return laNone;
else if(createOnSea(last))
return getNewSealand(last);
else if(isCrossroads(last)) {
while(isCrossroads(last) || last == laCaribbean || last == laCamelot)
last = levellist[hrand(qty)];
if(last == laElementalWall) last = laEFire;
return last;
}
else return pick(laCrossroads, laCrossroads2);
}
bool isAvailable(eLand l) {
for(int i=0; explorelevels[i]; i++) if(explorelevels[i] == l) return true;
return false;
}
void showMenu() {
dialog::init(XLAT(otherpuzzles ? "hyperbolic puzzles" : "memory game"), 0x40A040, 150, 100);
levellist = otherpuzzles ? explorelevels : simonlevels;
for(qty = 0; levellist[qty]; qty++)
dialog::addItem(XLAT1(linf[levellist[qty]].name), 'a'+qty);
dialog::addBreak(100);
dialog::addItem(XLAT(otherpuzzles ? "memory game" : "other hyperbolic puzzles"), '1');
dialog::addBoolItem(XLAT("display hints"), hint, '2');
dialog::addItem(XLAT("Help"), SDLK_F1);
dialog::addItem(XLAT("Return to the normal game"), '0');
dialog::display();
}
const char *chelp = NODESCYET;
namespace simon {
vector<cell*> path;
int tobuild;
void build() {
if(otherpuzzles || !on) return;
while(size(path) < tobuild) {
cell *cp = path[size(path)-1];
cell *cp2 = path[size(path)-2];
vector<pair<cell*, cell*>> clister;
clister.emplace_back(cp, cp);
int id = 0;
sval++;
while(id < size(clister)) {
cell *c = clister[id].first;
cell *fr = clister[id].second;
setdist(c, 5, NULL);
forCellEx(c2,c)
if(!eq(c2->aitmp, sval) && passable(c2, c, 0) && (c2->land == whichland || c2->land == laTemple) && !c2->item) {
if(!id) fr = c2;
bool next;
if(whichland == laRlyeh)
next = c2->land == laTemple && (cp2->land == laRlyeh || celldistAlt(c2) < celldistAlt(cp2) - 8);
else
next = celldistance(c2, cp2) == 8;
if(next) {
path.push_back(fr);
fr->item = itDodeca;
goto again;
}
clister.emplace_back(c2, fr);
c2->aitmp = sval;
}
id++;
}
printf("Path broken, searched = %d\n", id);
for(auto t: clister) t.first->item = itPirate;
return;
again: ;
}
}
void extend() {
int i = 0;
while(i<size(path) && path[i]->item != itDodeca) i++;
if(tobuild == i+9)
addMessage("You must collect all the dodecahedra on the path!");
tobuild = i + 9;
build();
}
void init() {
tobuild = 0;
if(!on) return;
if(otherpuzzles) { items[itGreenStone] = 500; return; }
cell *c2 = cwt.c->mov[0];
makeEmpty(c2);
c2->item = itOrbYendor;
path.clear();
path.push_back(cwt.c);
path.push_back(c2);
extend();
}
void restore() {
for(int i=1; i<size(path); i++)
if(path[i]->item == itNone && items[itDodeca])
path[i]->item = itDodeca, items[itDodeca]--;
}
}
void handleKey(int sym, int uni) {
dialog::handleNavigation(sym, uni);
if(uni == '1') otherpuzzles = !otherpuzzles;
else if(uni >= 'a' && uni < 'a' + qty) {
whichland = levellist[uni - 'a'];
restartGame(peace::on ? 0 : 'P');
cmode = emNormal;
}
else if(uni == '2') { hint = !hint; cmode = emNormal; }
else if(uni == '0') {
firstland = laIce;
if(peace::on) restartGame('P');
cmode = emNormal;
}
else if(uni == 'h' || sym == SDLK_F1) {
lastmode = cmode;
cmode = emHelp;
help = chelp;
}
else if(doexiton(sym, uni)) cmode = emNormal;
}
};