1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-25 09:30:35 +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;

125
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,11 +6922,7 @@ 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:
lastmovetype = lmMove; lastmove = cwt.c; lastmovetype = lmMove; lastmove = cwt.c;

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,51 +1589,33 @@ 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
if(cheatdest != old) if(!isCyclic(cheatdest) && !isTechnicalLand(cheatdest)) return cheatdest; if(cheatdest != old) if(!isCyclic(cheatdest) && !isTechnicalLand(cheatdest)) return cheatdest;
@ -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,25 +1929,28 @@ eLand showlist[10] = {
laHell, laRlyeh, laAlchemist, laGraveyard, laCaves, laDesert, laIce, laJungle, laMotion, laMirror laHell, laRlyeh, laAlchemist, laGraveyard, laCaves, laDesert, laIce, laJungle, laMotion, laMirror
}; };
void buildBarrierForce(cell *c, int d, eLand l) {
c->bardir = d;
eLand oldland = c->land;
if(oldland == laNone) {
raiseBuggyGeneration(c, "oldland is NONE");
return;
}
eLand newland = l ? l : getNewLand(oldland);
if(showoff) newland = showlist[(showid++) % 10];
landcount[newland]++;
if(d == 4 || d == 5 || d == 6) c->barleft = oldland, c->barright = newland;
else c->barleft = newland, c->barright = oldland;
c->landparam = 40;
extendcheck(c);
}
void buildBarrier(cell *c, int d, eLand l) { void buildBarrier(cell *c, int d, eLand l) {
d %= 7; d %= 7;
cellwalker bb(c, d); cellwalker bb(c, d);
if(checkBarriersFront(bb) && checkBarriersBack(bb)) { if(checkBarriersFront(bb) && checkBarriersBack(bb))
c->bardir = d; buildBarrierForce(c, d, l);
eLand oldland = c->land;
if(oldland == laNone) {
raiseBuggyGeneration(c, "oldland is NONE");
return;
}
eLand newland = l ? l : getNewLand(oldland);
if(showoff) newland = showlist[(showid++) % 10];
landcount[newland]++;
if(d == 4 || d == 5 || d == 6) c->barleft = oldland, c->barright = newland;
else c->barleft = newland, c->barright = oldland;
c->landparam = 40;
extendcheck(c);
}
} }
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,6 +2062,175 @@ namespace linepatterns {
if(patterns[k].id == id) patterns[k].color ^= col; if(patterns[k].id == id) patterns[k].color ^= col;
} }
void drawPattern(int id, int col, cell *c, const transmatrix& V) {
switch(id) {
#define col1 \
lessalphaif(col, behindsphere(V))
#define col2 \
lessalphaif(col, behindsphere(V), behindsphere(gmatrix[c2]))
case patZebraTriangles:
if(zebra40(c) / 4 == 10) {
bool all = true;
hyperpoint tri[3];
for(int i=0; i<3; i++) {
cell *c2 = createMov(c, i*2);
if(!gmatrix.count(c2)) all = false;
else tri[i] = tC0(gmatrix[c2]);
}
if(all) for(int i=0; i<3; i++)
queueline(tri[i], tri[(i+1)%3], col, 3);
}
break;
case patZebraLines:
if(!pseudohept(c)) for(int i=0; i<c->type; i+=2) {
cell *c2 = createMov(c, i);
int fv1 = zebra40(c);
if(fv1/4 == 4 || fv1/4 == 6 || fv1/4 == 5 || fv1/4 == 10) fv1 ^= 2;
int fv2 = zebra40(c2);
if(fv2/4 == 4 || fv2/4 == 6 || fv2/4 == 5 || fv2/4 == 10) fv2 ^= 2;
if((fv1&1) == (fv2&1)) continue;
double x = sphere?.3651:euclid?.2611:.2849;
queueline(V * ddspin(c,i,-S14) * xpush0(x),
V * ddspin(c,i,+S14) * xpush0(x),
col, 1);
}
break;
case patNormal: {
double x = sphere?.401:euclid?.3 : .328;
if(euclid || !pseudohept(c)) for(int t=0; t<c->type; t++)
if(euclid ? c->mov[t]<c : (((t^1)&1) || c->mov[t] < c))
queueline(V * ddspin(c,t,-S7) * xpush0(x),
V * ddspin(c,t,+S7) * xpush0(x),
col1, 1);
break;
}
case patTrihepta:
if(!pseudohept(c)) for(int i=0; i<6; i++) {
cell *c2 = c->mov[i];
if(!c2 || !pseudohept(c2)) continue;
double x = sphere?.3651:euclid?.2611:.2849;
queueline(V * ddspin(c,i,-S14) * xpush0(x),
V * ddspin(c,i,+S14) * xpush0(x),
col2, 1);
}
break;
case patTriNet:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2)) if(celldist(c) != celldist(c2)) {
queueline(tC0(V), gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2),
2);
}
break;
case patTriRings:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && celldist(c) == celldist(c2))
queueline(tC0(V), gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2),
2);
break;
case patHepta:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) == pseudohept(c2))
queueline(tC0(V), gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2),
2);
break;
case patRhomb:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) != pseudohept(c2))
queueline(tC0(V), gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2),
2);
break;
case patPalace: {
int a = polarb50(c);
if(pseudohept(c)) for(int i=0; i<7; i++) {
cell *c1 = createMov(c, (i+3) % 7);
cell *c2 = createMov(c, (i+4) % 7);
if(polarb50(c1) != a && polarb50(c2) != a)
queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
col, 1);
}
break;
}
case patPalacelike:
if(pseudohept(c)) for(int i=0; i<7; i++)
queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
col1, 1);
break;
case patBigTriangles: {
if(pseudohept(c) && !euclid) for(int i=0; i<S7; i++)
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;
queueline(tC0(V), V*xspinpush0((purehepta?M_PI:0) -2*M_PI*i/S7, tessf), col2, 2);
}
break;
}
case patTree:
if(c->type != 6 && !euclid)
queueline(tC0(V), V*ddi0(purehepta?S42:0, tessf), col1, 2);
break;
case patAltTree:
if(c->type != 6 && !euclid && c->master->alt) {
for(int i=0; i<S7; i++)
if(c->master->move[i] && c->master->move[i]->alt == c->master->alt->move[0])
queueline(tC0(V), V*xspinpush0((purehepta?M_PI:0) -2*M_PI*i/S7, tessf), col, 2);
}
break;
case patVine: {
int p = emeraldval(c);
double hdist = hdist0(heptmove[0] * heptmove[2] * C0);
if(pseudohept(c) && (p/4 == 10 || p/4 == 8))
for(int i=0; i<S7; i++) if(c->mov[i] && emeraldval(c->mov[i]) == p-4) {
queueline(tC0(V), V*tC0(heptmove[i]), col, 2);
queueline(tC0(V), V*tC0(spin(-i * ALPHA) * xpush(-hdist/2)), col, 2);
}
break;
}
case patPower: {
int a = emeraldval(c);
if(pseudohept(c) && a/4 == 8) for(int i=0; i<7; i++) {
heptagon *h1 = c->master->move[(i+1)%7];
heptagon *h2 = c->master->move[(i+6)%7];
if(!h1 || !h2) continue;
if(emeraldval(h1->c7)/4 == 8 && emeraldval(h2->c7)/4 == 8)
queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
col, 1);
}
break;
}
}
}
void drawAll() { void drawAll() {
if(any()) for(map<cell*, transmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) { if(any()) for(map<cell*, transmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) {
@ -2072,163 +2242,7 @@ namespace linepatterns {
if(!(col & 255)) continue; if(!(col & 255)) continue;
int id = patterns[k].id; int id = patterns[k].id;
switch(id) { drawPattern(id, col, c, V);
#define col1 \
lessalphaif(col, behindsphere(V))
#define col2 \
lessalphaif(col, behindsphere(V), behindsphere(gmatrix[c2]))
case patZebraTriangles:
if(zebra40(c) / 4 == 10) {
bool all = true;
hyperpoint tri[3];
for(int i=0; i<3; i++) {
cell *c2 = createMov(c, i*2);
if(!gmatrix.count(c2)) all = false;
else tri[i] = tC0(gmatrix[c2]);
}
if(all) for(int i=0; i<3; i++)
queueline(tri[i], tri[(i+1)%3], col, 3);
}
break;
case patZebraLines:
if(!pseudohept(c)) for(int i=0; i<c->type; i+=2) {
cell *c2 = createMov(c, i);
int fv1 = zebra40(c);
if(fv1/4 == 4 || fv1/4 == 6 || fv1/4 == 5 || fv1/4 == 10) fv1 ^= 2;
int fv2 = zebra40(c2);
if(fv2/4 == 4 || fv2/4 == 6 || fv2/4 == 5 || fv2/4 == 10) fv2 ^= 2;
if((fv1&1) == (fv2&1)) continue;
double x = sphere?.3651:euclid?.2611:.2849;
queueline(V * ddspin(c,i,-S14) * xpush0(x),
V * ddspin(c,i,+S14) * xpush0(x),
col, 1);
}
break;
case patNormal: {
double x = sphere?.401:euclid?.3 : .328;
if(euclid || !pseudohept(c)) for(int t=0; t<c->type; t++)
if(euclid ? c->mov[t]<c : (((t^1)&1) || c->mov[t] < c))
queueline(V * ddspin(c,t,-S7) * xpush0(x),
V * ddspin(c,t,+S7) * xpush0(x),
col1, 1);
break;
}
case patTrihepta:
if(!pseudohept(c)) for(int i=0; i<6; i++) {
cell *c2 = c->mov[i];
if(!c2 || !pseudohept(c2)) continue;
double x = sphere?.3651:euclid?.2611:.2849;
queueline(V * ddspin(c,i,-S14) * xpush0(x),
V * ddspin(c,i,+S14) * xpush0(x),
col2, 1);
}
break;
case patTriNet:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2)) if(celldist(c) != celldist(c2)) {
queueline(it->second*C0, gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2),
2);
}
break;
case patTriRings:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && celldist(c) == celldist(c2))
queueline(it->second*C0, gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2),
2);
break;
case patHepta:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) == pseudohept(c2))
queueline(it->second*C0, gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2),
2);
break;
case patRhomb:
forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) != pseudohept(c2))
queueline(it->second*C0, gmatrix[c2]*C0,
darkena(backcolor ^ 0xFFFFFF, 0, col2),
2);
break;
case patPalace: {
int a = polarb50(c);
if(pseudohept(c)) for(int i=0; i<7; i++) {
cell *c1 = createMov(c, (i+3) % 7);
cell *c2 = createMov(c, (i+4) % 7);
if(polarb50(c1) != a && polarb50(c2) != a)
queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
col, 1);
}
break;
}
case patPalacelike:
if(pseudohept(c)) for(int i=0; i<7; i++)
queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
col1, 1);
break;
case patBigTriangles: {
if(pseudohept(c) && !euclid) for(int i=0; i<S7; i++)
if(c->master->move[i] < c->master) {
cell *c2 = c->master->move[i]->c7;
queueline(tC0(V), V*xspinpush0((purehepta?M_PI:0) -2*M_PI*i/S7, tessf), col2, 2);
}
break;
}
case patTree:
if(c->type != 6 && !euclid)
queueline(tC0(V), V*ddi0(purehepta?S42:0, tessf), col1, 2);
break;
case patAltTree:
if(c->type != 6 && !euclid && c->master->alt) {
for(int i=0; i<S7; i++)
if(c->master->move[i] && c->master->move[i]->alt == c->master->alt->move[0])
queueline(tC0(V), V*xspinpush0((purehepta?M_PI:0) -2*M_PI*i/S7, tessf), col, 2);
}
break;
case patVine: {
int p = emeraldval(c);
double hdist = hdist0(heptmove[0] * heptmove[2] * C0);
if(pseudohept(c) && (p/4 == 10 || p/4 == 8))
for(int i=0; i<S7; i++) if(c->mov[i] && emeraldval(c->mov[i]) == p-4) {
queueline(tC0(V), V*tC0(heptmove[i]), col, 2);
queueline(tC0(V), V*tC0(spin(-i * ALPHA) * xpush(-hdist/2)), col, 2);
}
break;
}
case patPower: {
int a = emeraldval(c);
if(pseudohept(c) && a/4 == 8) for(int i=0; i<7; i++) {
heptagon *h1 = c->master->move[(i+1)%7];
heptagon *h2 = c->master->move[(i+6)%7];
if(!h1 || !h2) continue;
if(emeraldval(h1->c7)/4 == 8 && emeraldval(h2->c7)/4 == 8)
queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
col, 1);
}
break;
}
}
} }
} }
} }

710
menus.cpp

File diff suppressed because it is too large Load Diff

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,11 +1088,25 @@ 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;
queueline(h1, h2, col, 2); if(pmodel || onspiral) {
lastptd().prio = PPR_STRUCT0; 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);
lastptd().prio = PPR_STRUCT0;
}
} }
else { else {
@ -1058,8 +1114,22 @@ void drawVertex(const transmatrix &V, cell *c, shmup::monster *m) {
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));
storeline(ei->prec, T*h1, T*h2);
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);
} }
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,
PPR_STRUCT0); PPR_STRUCT0);
@ -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,15 +1848,16 @@ 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);
firstland = euclidland = laIce; firstland = euclidland = laIce;
tour::start(); tour::start();
} }
} }
}, },
{"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.",

18
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();
glClearColor(0.05,0.05,0.05,1); if(backcolor == 0)
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;
}
};