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

View File

@ -72,20 +72,14 @@ struct celllister {
vector<int> tmps;
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) {
if(listed(c)) return;
c->aitmp = size(lst);
if(eq(c->aitmp, sval)) return;
c->aitmp = sval;
tmps.push_back(c->aitmp);
lst.push_back(c);
dists.push_back(d);
}
int getdist(cell *c) { return dists[c->aitmp]; }
~celllister() {
for(int i=0; i<size(lst); i++) lst[i]->aitmp = tmps[i];
}
@ -94,6 +88,7 @@ struct celllister {
lst.clear();
tmps.clear();
dists.clear();
sval++;
add(orig, 0);
cell *last = orig;
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 ---

View File

@ -767,7 +767,7 @@ genderswitch_t genderswitch[NUM_GS] = {
// --- items ---
const int ittypes = 110;
const int ittypes = 111;
struct itemtype {
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 "
"with this Orb." },
{ '$', 0xC060C0, "Spinel", bulldashdesc },
{ 'o', 0xC0C0FF, "Orb of the Mirror", NODESCYET },
};
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,
itRose, itCoral, itOrbBeauty, itOrb37, itOrbEnergy,
itBabyTortoise, itOrbShell, itApple, itDragon, itOrbDomination,
itOrbSword,
itKraken, itOrbSword2, itBarrow,
itTrollEgg, itWarning,
itOrbStone, itOrbNature, itTreat,
itSlime, itAmethyst,
itOrbRecall, itDodeca,
itOrbDash,
itGreenGrass,
itOrbHorns,
itOrbBull,
itBull
itOrbSword, itKraken, itOrbSword2, itBarrow,
itTrollEgg, itWarning, itOrbStone, itOrbNature, itTreat,
itSlime, itAmethyst, itOrbRecall, itDodeca, itOrbDash, itGreenGrass, itOrbHorns,
itOrbBull, itBull, itOrbMirror
};
// --- wall types ---
const int walltypes = 96;
const int walltypes = 97;
struct walltype {
char glyph;
@ -1375,6 +1369,7 @@ walltype winf[walltypes] = {
"Bushes block the movement of birds."},
{ '.', 0xFFFF00, "Reptile floor", reptiledesc},
{ '.', 0xFFFF00, "Reptile bridge", reptiledesc},
{ '.', 0xFFFF00, "invisible floor", NODESCYET},
};
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,
waPetrified, waTower,
waBigBush, waSmallBush,
waReptile, waReptileBridge
waReptile, waReptileBridge,
waInvisibleFloor
};
// --- land types ---
@ -1782,3 +1778,24 @@ eLand randlands[RANDLANDS] = {
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 == waFire) 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 == moGhost) c->aitmp += 10;
if(c->mov[j]->monst == moTentacleGhost) c->aitmp += 10;
@ -2024,7 +2024,7 @@ namespace tortoise {
void updateVals(int delta) {
int currbits = getBits(cwt.c);
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++)
update(currval[i], getBit(currbits, i), delta);
}

View File

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

View File

@ -86,7 +86,6 @@ namespace dialog {
it.color = 0xC0C0C0;
it.colork = 0x808080;
it.colorv = 0x80A040;
it.colors = 0xFFD500;
it.colorc = 0xFFD500;
it.colors = 0xFF8000;
if(value == ONOFF(true)) it.colorv = 0x40FF40;
@ -148,11 +147,12 @@ namespace dialog {
items.push_back(it);
}
void addBreak(int val) {
int addBreak(int val) {
item it;
it.type = diBreak;
it.scale = val;
items.push_back(it);
return items.size()-1;
}
void addTitle(string body, int color, int scale) {
@ -285,6 +285,7 @@ namespace dialog {
int top = tothei;
tothei += dfspace * I.scale / 100;
int mid = (top + tothei) / 2;
I.position = mid;
if(I.type == diTitle || I.type == diInfo) {
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++) {
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);
string rgt = ") "; rgt += "ABGR" [i];
@ -622,7 +623,10 @@ namespace dialog {
if(ne.editwhat == &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() {
@ -663,6 +667,9 @@ namespace dialog {
if(ne.editwhat == &ne.intbuf && ne.intval == &sightrange && cheater)
addBoolItem("overgenerate", overgenerate, 'o');
if(ne.editwhat == &vid.linewidth)
addBoolItem("finer lines at the boundary", vid.antialias & AA_LINEWIDTH, 'o');
display();
}
@ -710,6 +717,8 @@ namespace dialog {
}
else if(uni == 'o' && ne.editwhat == &ne.intbuf && ne.intval == &sightrange && cheater)
overgenerate = !overgenerate;
else if(uni == 'o' && ne.editwhat == &vid.linewidth)
vid.antialias ^= AA_LINEWIDTH;
else if(uni == 'p' && ne.editwhat == &vid.alpha) {
*ne.editwhat = 1; vid.scale = 1; ne.s = "1";
}

View File

@ -213,7 +213,7 @@ int main(int argc, char **argv) {
items[itGreenStone] = 100;
}
action = sym; */
extra ex;
eventtype ex;
mousing = false;
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 == waWeakBranch || w->wall == waCanopy || w->wall == waTower ||
w->wall == waSmallBush || w->wall == waBigBush ||
w->wall == waReptile || w->wall == waReptileBridge)
w->wall == waReptile || w->wall == waReptileBridge || w->wall == waInvisibleFloor)
return false;
if(isWatery(w) || isChasmy(w) || isFire(w)) return false;
return true;
@ -641,7 +641,7 @@ bool highwall(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(isWateryOrBoat(c)) return 1;
if(wmescher && c->wall == waBarrier && c->land == laOceanWall) return 1;

133
game.cpp
View File

@ -687,7 +687,7 @@ bool sharkpassable(cell *w, cell *c) {
bool canPushStatueOn(cell *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) {
@ -844,6 +844,8 @@ bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags) {
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_FBUG) && m2 != moPlayer && !isFriendlyOrBug(c2)) return false;
if((flags & AF_ONLY_ENEMY) && (m2 == moPlayer || isFriendlyOrBug(c2))) return false;
@ -1214,7 +1216,9 @@ int monstersnear2() {
}
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);
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
addMessage(XLAT("You pierce %the1.", victim)); // normal
}
else {
else if(!peace::on) {
playSound(NULL, "hit-sword"+pick123());
addMessage(XLAT("You kill %the1.", victim)); // normal
}
@ -2133,6 +2137,8 @@ bool attackMonster(cell *c, flagtype flags, eMonster killer) {
else
killMonster(c, killer, flags);
if(peace::on) return false;
int ntk = tkills();
int ntkt = killtypes();
@ -2318,6 +2324,8 @@ void calcTidalPhase() {
tidalphase = tide[
(shmup::on ? shmup::curtime/600 : turncount)
% tidalsize];
if(peace::on)
tidalphase = 5 + tidalphase / 6;
}
int tidespeed() {
@ -2587,7 +2595,7 @@ void bfs() {
c2->cpdist = d+1;
// 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 &&
(items[c2->item] >= (chaosmode?10:20) + currentLocalTreasure || getGhostcount() >= 2)) {
c2->item = itNone;
@ -2914,7 +2922,9 @@ void gainShard(cell *c2, const char *msg) {
invismove = false;
}
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]);
@ -3276,7 +3286,7 @@ int moveval(cell *c1, cell *c2, int d, int mf) {
else if(isFriendlyOrBug(c2)) return 500;
else return 2000;
}
if(isPlayerOn(c2)) return 2500;
if(isPlayerOn(c2)) return peace::on ? -1700 : 2500;
else if(isFriendlyOrBug(c2)) return 2000;
else return 500;
}
@ -3338,7 +3348,7 @@ int moveval(cell *c1, cell *c2, int d, int mf) {
if(m == moRagingBull && c1->mondir != NODIR)
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
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
if(c->monst == moViking && c->wall == waBoat)
return 750;
// in peaceful, all monsters are wandering
if(peace::on && c->monst != moTortoise) return 750;
if(isWorm(c->monst)) return 550;
if(c->monst == moRagingBull) return -1690; // worse than to stay in place
if(c->monst == moBat && batsAfraid(c)) return 575;
@ -3871,7 +3883,7 @@ void moveivy() {
raiseBuggyGeneration(c, "wrong mondir!");
for(int j=0; j<c->type; j++) {
if(c->mov[j] && canAttack(c, c->monst, c->mov[j], c->mov[j]->monst, AF_ONLY_FRIEND | AF_GETPLAYER)) {
if(isPlayerOn(c->mov[j]))
if(isPlayerOn(c->mov[j]))
killThePlayerAt(c->monst, c->mov[j], 0);
else {
if(attackJustStuns(c->mov[j]))
@ -4033,7 +4045,7 @@ void groupmove(eMonster movtype, flagtype mf) {
}
}
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++) {
cell *c = playerpos(i);
@ -4387,6 +4399,7 @@ void swordAttackStatic() {
}
void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) {
if(peace::on) return;
int numsh = 0, numflail = 0, numlance = 0, numslash = 0;
int backdir = neighborId(mt, mf);
@ -4727,7 +4740,7 @@ void specialMoves() {
eMonster m = c->monst;
if(m == moSleepBull) {
if(m == moSleepBull && !peace::on) {
bool wakeup = false;
forCellEx(c2, c) if(c2->monst == moGadfly) {
addMessage(XLAT("%The1 wakes up %the2.", c2->monst, m));
@ -4957,6 +4970,17 @@ void moverefresh(bool turn = true) {
c->monst = moReptile;
c->hitpoints = 3;
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");
}
}
@ -5521,7 +5545,8 @@ void gainLife() {
void collectMessage(cell *c2, eItem which) {
bool specialmode =
yendor::on || tactic::on || princess::challenge || euclid || sphere;
if(which == itDodeca && peace::on) return;
if(which == itTreat) ;
else if(isElementalShard(which)) {
int tsh =
@ -5536,8 +5561,9 @@ void collectMessage(cell *c2, eItem which) {
addMessage(t);
}
}
else if(which == itKey)
else if(which == itKey) {
addMessage(XLAT("You have found the Key! Now unlock this Orb of Yendor!"));
}
else if(which == itGreenStone && !items[itGreenStone])
addMessage(XLAT("This orb is dead..."));
else if(which == itGreenStone)
@ -5632,6 +5658,7 @@ bool collectItem(cell *c2, bool telekinesis) {
princess::forceVizier = true;
if(!cantGetGrimoire(c2, false)) collectMessage(c2, c2->item);
if(c2->item == itDodeca) peace::simon::extend();
}
if(isRevivalOrb(c2->item) && multi::revive_queue.size()) {
@ -5861,47 +5888,21 @@ bool collectItem(cell *c2, bool telekinesis) {
playSound(c2, "pickup-orb");
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) {
dopickup = false;
}
else if(c2->item == itOrbYendor) {
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);
}
else if(c2->item == itOrbYendor)
yendor::collected(c2);
else if(c2->item == itHolyGrail) {
playSound(c2, "tada");
int v = newRoundTableRadius() + 12;
@ -5993,7 +5994,7 @@ bool collectItem(cell *c2, bool telekinesis) {
if(pg < 75 && g2 >= 75)
addMessage(XLAT("Kill monsters and collect treasures, and you may get access to Hell..."));
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) {
addMessage(XLAT("Abandon all hope, the gates of Hell are opened!"));
addMessage(XLAT("And the Orbs of Yendor await!"));
@ -6467,6 +6468,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
if(d >= 0) {
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(checkonly) return false;
@ -6652,7 +6654,8 @@ bool movepcto(int d, int subdir, bool checkonly) {
knightFlavorMessage(c2);
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));
@ -6731,7 +6734,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
!c2->item);
} */
if(c2->monst == moTortoise && tortoise::seek() && !tortoise::diff(tortoise::getb(c2)) && !c2->item) {
if(goodTortoise) {
items[itBabyTortoise] += 4;
updateHi(itBabyTortoise, items[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?");
return false;
}
if(c2->item == itOrbYendor && !boatmove && !checkonly && yendor::check(c2)) {
if(c2->item == itOrbYendor && !boatmove && !checkonly && !peace::on && yendor::check(c2)) {
return false;
}
if(monstersnear(c2, NULL, moPlayer, NULL, cwt.c)) {
@ -6888,8 +6891,20 @@ bool movepcto(int d, int subdir, bool checkonly) {
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;
if(c2->monst == moMouse)
princess::mouseSqueak(c2);
@ -6907,11 +6922,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
c2->monst = moNone;
switchplaces = true;
}
else if(isMimic(c2->monst)) {
addMessage(XLAT("You rejoin %the1.", c2->monst));
playSound(c2, "click");
killMonster(c2, moNone);
}
}
mountjump:
lastmovetype = lmMove; lastmove = cwt.c;

657
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 {
// automaton state
hstate s : 8;
hstate s : 6;
int dm4: 2;
// we are spin[i]-th neighbor of move[i]
uint32_t spintable;
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(h);
if(pard == 0) {
h->dm4 = parent->dm4+1;
if(purehepta) h->distance = parent->distance + 1;
else if(parent->s == hsOrigin) h->distance = 2;
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;
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;
}

View File

@ -119,6 +119,12 @@ int arg::readCommon() {
else if(argis("-back")) {
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")) {
shift(); cheatdest = readland(args()); autocheat = true;
}
@ -168,6 +174,8 @@ int arg::readCommon() {
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("-mm")) { PHASEFROM(2); vid.monmode = argi(); }
@ -379,7 +387,11 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { if(curphase ==
return 0;
}
#ifndef NOMAIN
int main(int argc, char **argv) {
#ifdef EXTRA_MAIN
if(extra::main(argc, argv)) return 0;
#endif
#ifndef WEB
#ifdef LINUX
moreStack();
@ -394,6 +406,7 @@ int main(int argc, char **argv) {
profile_info();
return 0;
}
#endif
#ifdef USE_COMMANDLINE
namespace arg {
@ -401,11 +414,14 @@ namespace arg {
void read(int phase) {
curphase = phase;
#ifdef EXTRA_CONFIG
extra::config();
#endif
while(argc) {
int r;
r = readCommon(); if(r == 2) return; if(r == 0) { lshift(); continue; }
#ifdef LOCAL
r = readLocal(); if(r == 2) return; if(r == 0) { lshift(); continue; }
#ifdef EXTRA_ARG
r = extra::arg(); if(r == 2) return; if(r == 0) { lshift(); continue; }
#endif
#ifdef ROGUEVIZ
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;
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 displayfrSP(int x, int y, int sh, int b, int size, const string &s, int color, int align, int p);
bool outofmap(hyperpoint h);
void applymodel(hyperpoint H, hyperpoint& Hscr);
@ -262,6 +263,7 @@ void resetview(); extern heptspin viewctr; extern cell *centerover;
void drawthemap();
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 string& str, int color, int align);
extern int darken;
void calcparam();
@ -322,7 +324,14 @@ struct videopar {
float scrdist;
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;
ld joypanspeed;
@ -344,7 +353,7 @@ extern videopar vid;
enum emtype {emNormal, emHelp,
emMenu,
emVisual1, emVisual2,
emBasicConfig, emGraphConfig, emDisplayMode,
emChangeMode, emCustomizeChar,
emQuit, emDraw, emScores, emPickEuclidean,
emPickScores,
@ -360,7 +369,9 @@ enum emtype {emNormal, emHelp,
emJoyConfig,
emColor, emNumber,
em3D, emRogueviz,
emLinepattern
emLinepattern,
emPeace, emInventory,
emSlideshows
};
extern emtype cmode, lastmode;
@ -704,6 +715,7 @@ template<class T> struct dynamicval {
T& where;
T backup;
dynamicval(T& wh, T val) : where(wh) { backup = wh; wh = val; }
dynamicval(T& wh) : where(wh) { backup = wh; }
~dynamicval() { where = backup; }
};
@ -790,6 +802,7 @@ namespace dialog {
int color, colorv, colork, colors, colorc;
int scale;
double param;
int position;
};
item& lastItem();
@ -801,7 +814,7 @@ namespace dialog {
void addHelp(string body);
void addInfo(string body, int color = 0xC0C0C0);
void addItem(string body, int key);
void addBreak(int val);
int addBreak(int val);
void addTitle(string body, int color, int scale);
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_DEAD 0x800000FF
#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 string musiclicense;
@ -1023,7 +1039,7 @@ extern cell *recallCell;
extern eLand cheatdest;
void cheatMoveTo(eLand l);
extern int backcolor;
extern int backcolor, bordcolor, forecolor;
extern bool overgenerate;
void doOvergenerate();
@ -1131,6 +1147,7 @@ namespace tour {
extern bool on;
extern string tourhelp;
extern string slidecommand;
extern int currentslide;
bool handleKeyTour(int sym, int uni);
@ -1167,9 +1184,18 @@ namespace tour {
static const int LEGAL_NONEUC=4;
static const int QUICKSKIP=8;
static const int FINALSLIDE=16;
static const int QUICKGEO=32;
static const int SIDESCREEN = 64;
extern slide slideHypersian;
extern slide slideExpansion;
namespace ss {
void showMenu();
void handleKey(int sym, int uni);
void list(slide*);
}
};
#endif
@ -1184,10 +1210,8 @@ namespace rogueviz {
extern bool doCross;
void optimizeview();
#ifndef NOPNG
extern int pngres;
extern int pngformat;
#endif
extern bool noGUI;
extern bool dronemode;
@ -1211,7 +1235,8 @@ namespace linepatterns {
patPower,
patNormal,
patTrihepta,
patBigTriangles
patBigTriangles,
patBigRings
};
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);
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"
1 VERSIONINFO
FILEVERSION 9,4,0,14
PRODUCTVERSION 9,4,0,14
FILEVERSION 9,4,0,15
PRODUCTVERSION 9,4,0,15
BEGIN
BLOCK "StringFileInfo"
BEGIN
@ -10,12 +10,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Zeno Rogue"
VALUE "FileDescription", "A roguelike in non-euclidean space"
VALUE "FileVersion", "94n"
VALUE "FileVersion", "94n1"
VALUE "InternalName", "hyper"
VALUE "LegalCopyright", "Zeno Rogue"
VALUE "OriginalFilename", "hyper.exe"
VALUE "ProductName", "HyperRogue"
VALUE "ProductVersion", "9.4n"
VALUE "ProductVersion", "9.4n1"
END
END

View File

@ -1,6 +1,6 @@
#define VER "9.4n"
#define VERNUM 9414
#define VERNUM_HEX 0x9414
#define VER "9.4n1"
#define VERNUM 9415
#define VERNUM_HEX 0x9415
#define GEN_M 0
#define GEN_F 1
@ -40,7 +40,9 @@
#define GFX
#endif
#ifndef NOGL
#define GL
#endif
#define PSEUDOKEY_WHEELDOWN 2501
#define PSEUDOKEY_WHEELUP 2502
@ -53,6 +55,8 @@
#define NOPNG
#endif
// #define INV
#ifndef MOBILE
#ifndef NOAUDIO
#define SDLAUDIO
@ -72,6 +76,10 @@ bool buttonclicked;
void gdpush(int t);
#endif
#ifndef HYPERPATH
#define HYPERPATH ""
#endif
#include <stdio.h>
#ifdef NOSDL
@ -151,7 +159,11 @@ typedef int SDL_Event;
#ifdef GL
#ifdef WINDOWS
#ifdef MAC
#define AVOID_GLEW
#endif
#ifndef AVOID_GLEW
#include <GL/glew.h>
#else
#define GL_GLEXT_PROTOTYPES 1
@ -251,6 +263,9 @@ const char *loadlevel = NULL;
#include "game.cpp"
#include "landgen.cpp"
#include "orbs.cpp"
#ifdef INV
#include "inventory.cpp"
#endif
#include "system.cpp"
#include "geometry.cpp"
#include "polygons.cpp"
@ -258,6 +273,9 @@ const char *loadlevel = NULL;
#ifndef MOBILE
#include "netgen.cpp"
#endif
#ifdef EXTRA
#include "extra/extra.cpp"
#endif
#include "graph.cpp"
#include "sound.cpp"
#include "achievement.cpp"
@ -592,7 +610,7 @@ void mobile_draw(MOBPAR_FORMAL) {
displayTexts();
#endif
if((cmode != emVisual1 && cmode != emScores)) {
if((cmode != emBasicConfig && cmode != emScores)) {
if(clicked && lclicked && andmode == 1 && !inmenu) {
if(!mouseout2() && mouseoh[2] < 50 && mouseh[2] < 50) {
@ -646,3 +664,35 @@ void mobile_draw(MOBPAR_FORMAL) {
#ifdef NOAUDIO
void playSound(cell*, const string &s, int vol) { printf("play sound: %s vol %d\n", s.c_str(), vol); }
#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");
fprintf(f, "%d %d\n", cells, t);
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);
}

View File

@ -388,6 +388,15 @@ eItem orbType(eLand l) {
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 {
olrForbidden, // never appears: forbidden
olrDangerous, // never appears: would be dangerous
@ -613,10 +622,10 @@ bool landUnlocked(eLand l) {
switch(l) {
case laOvergrown:
return gold() >= 60 && items[itRuby] >= 10;
return gold() >= R60 && items[itRuby] >= U10;
case laStorms: case laWhirlwind:
return gold() >= 60;
return gold() >= R60;
case laWildWest: case laHalloween:
return false;
@ -627,49 +636,49 @@ bool landUnlocked(eLand l) {
case laMirror: case laMinefield: case laPalace:
case laOcean: case laLivefjord:
return gold() >= 30;
return gold() >= R30;
case laCaribbean: case laWhirlpool:
return exploreland[0][laOcean] || items[itCoast] || items[itStatue];
case laRlyeh: case laDryForest: case laWineyard: case laCrossroads2:
return gold() >= 60;
return gold() >= R60;
case laDeadCaves:
return gold() >= 60 && items[itGold] >= 10;
return gold() >= R60 && items[itGold] >= U10;
case laGraveyard:
return tkills() >= 100;
return tkills() >= R100;
case laHive:
return tkills() >= 100 && gold() >= 60;
return tkills() >= R100 && gold() >= R60;
case laRedRock:
return gold() >= 60 && items[itSpice] >= 10;
return gold() >= R60 && items[itSpice] >= U10;
case laEmerald:
return (items[itFernFlower] >= 5 && items[itGold] >= 5) || kills[moVizier];
return (items[itFernFlower] >= U5 && items[itGold] >= U5) || kills[moVizier];
case laCamelot:
return items[itEmerald] >= 5;
return items[itEmerald] >= U5;
case laHell: case laCrossroads3:
return hellUnlocked();
case laPower:
return items[itHell] >= 10;
return items[itHell] >= U10;
case laCocytus:
return items[itHell] >= 10 && items[itDiamond] >= 10;
return items[itHell] >= U10 && items[itDiamond] >= U10;
case laTemple:
return items[itStatue] >= 5;
return items[itStatue] >= U5;
case laClearing:
return items[itMutant] >= 5;
return items[itMutant] >= U5;
case laIvoryTower: return gold() >= 30;
case laZebra: return gold() >= 30 && items[itFeather] >= 10;
case laIvoryTower: return gold() >= R30;
case laZebra: return gold() >= R30 && items[itFeather] >= U10;
case laEAir: case laEEarth: case laEWater: case laEFire: case laElementalWall:
return elementalUnlocked();
@ -678,52 +687,52 @@ bool landUnlocked(eLand l) {
return false;
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 laRose:
return gold() >= 60;
return gold() >= R60;
case laWarpCoast: case laWarpSea:
return gold() >= 30;
return gold() >= R30;
case laCrossroads4:
return gold() >= 200;
return gold() >= R200;
case laEndorian:
return items[itIvory] >= 10;
return items[itIvory] >= U10;
case laTortoise:
return tortoise::seek();
case laDragon:
return killtypes() >= 20;
return killtypes() >= R20;
case laKraken:
return items[itFjord] >= 10;
return items[itFjord] >= U10;
case laBurial:
return items[itKraken] >= 10;
return items[itKraken] >= U10;
case laTrollheim:
return trollUnlocked();
case laDungeon:
return items[itPalace] >= 5 && items[itIvory] >= 5;
return items[itPalace] >= U5 && items[itIvory] >= U5;
case laMountain:
return items[itRuby] >= 5 && items[itIvory] >= 5;
return items[itRuby] >= U5 && items[itIvory] >= U5;
case laReptile:
return gold() >= 30 && items[itElixir] >= 10;
return gold() >= R30 && items[itElixir] >= U10;
case laPrairie:
case laBull:
return gold() >= 90;
return gold() >= R90;
case laCrossroads5:
return gold() >= 300;
return gold() >= R300;
}
return false;
}
@ -731,7 +740,7 @@ bool landUnlocked(eLand l) {
int orbsUnlocked() {
int i = 0;
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++;
return i;
}
@ -745,7 +754,7 @@ void countHyperstoneQuest(int& i1, int& i2) {
for(int t=1; t<ittypes; t++)
if(t != itHyperstone && t != itBounty && t != itTreat &&
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) {
if(inv::on) return tr >= 50 ? 1 : 0;
if(tr < 10) return 0;
if(tr > 25) return 1;
return (tr*2 + 50) / 100.;
}
bool buildPrizeMirror(cell *c, int freq) {
if(inv::on) return false;
if(c->type == 7 && !purehepta) return false;
if(items[itShard] < 25) return false;
if(freq && hrand(freq * 100 / orbprizefun(items[itShard])) >= 100)
@ -1008,6 +1019,7 @@ bool buildPrizeMirror(cell *c, int freq) {
void placePrizeOrb(cell *c) {
eLand l = c->land;
if(isElemental(l)) l = laElementalWall;
if(peace::on) return;
// these two lands would have too much orbs according to normal rules
if(l == laPalace && hrand(100) >= 20) return;
@ -1021,6 +1033,7 @@ void placePrizeOrb(cell *c) {
l = laPrincessQuest;
for(int i=0; i<ORBLINES; i++) {
const orbinfo& oi(orbinfos[i]);
if(inv::on && oi.orb != itOrbYendor) return;
eOrbLandRelation olr = getOLR(oi.orb, l);
if(olr != olrPrize25 && olr != olrPrize3) continue;
int treas = items[treasureType(oi.l)];
@ -1051,10 +1064,12 @@ void placeLocalOrbs(cell *c) {
if(l == laZebra && c->wall == waTrapdoor) return;
if(isGravityLand(l) && cellEdgeUnstable(c)) return;
if(isElemental(l)) l = laElementalWall;
if(peace::on) return;
for(int i=0; i<ORBLINES; i++) {
const orbinfo& oi(orbinfos[i]);
if(oi.l != l) continue;
if(inv::on && (oi.orb != itOrbYendor)) continue;
if(yendor::on && (oi.orb == itOrbSafety || oi.orb == itOrbYendor))
continue;
if(!oi.lchance) continue;
@ -1074,9 +1089,11 @@ void placeLocalOrbs(cell *c) {
}
void placeCrossroadOrbs(cell *c) {
if(peace::on) return;
for(int i=0; i<ORBLINES; i++) {
const orbinfo& oi(orbinfos[i]);
if(!oi.gchance) continue;
if(inv::on && oi.orb != itOrbSafety && oi.orb != itOrbYendor) return;
int treas = items[treasureType(oi.l)] * landMultiplier(oi.l);
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)
@ -1097,8 +1114,10 @@ void placeCrossroadOrbs(cell *c) {
}
void placeOceanOrbs(cell *c) {
if(peace::on) return;
for(int i=0; i<ORBLINES; 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(!oi.gchance) continue;
if(oi.orb == itOrbLife) continue; // useless
@ -1136,8 +1155,7 @@ void raiseBuggyGeneration(cell *c, const char *s) {
}
// return;
#ifdef LOCAL
#ifdef DEBUG_LANDGEN
describeCell(c);
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++)
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) {
if(l == laOcean || l == laTemple) return false;
return
@ -1563,6 +1577,7 @@ eLand getNewSealand(eLand old) {
while(true) {
eLand p = pick(laOcean, pick(laCaribbean, laLivefjord, laWarpSea, laKraken));
if(p == laKraken && !landUnlocked(p)) continue;
if(p == laKraken && peace::on) continue;
if(incompatible(old, p)) continue;
if(p == old) continue;
if(chaosmode && noChaos(p)) continue;
@ -1574,52 +1589,34 @@ bool doEndorian = false;
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 landtab[10] = {
laWhirlwind, laRose, laEndorian, laRlyeh,
laPalace, laOcean, laEmerald, laStorms,
laGraveyard, laAlchemist
}; */
// return landtab[items[itStrongWind]++ % 10];
// if(old != laPrairie) return laRiver;
#ifdef EXTRA_NEWLAND
if(true) {
eLand l = extra::getNext(old);
if(l) return l;
}
#endif
#ifdef TOUR
if(tour::on) {
eLand l = tour::getNext(old);
if(l) return l;
}
if(peace::on) {
eLand l = peace::getNext(old);
if(l) return l;
}
#endif
#ifdef LOCAL
extern bool doAutoplay;
if(doAutoplay)
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
if(cheatdest != old) if(!isCyclic(cheatdest) && !isTechnicalLand(cheatdest)) return cheatdest;
if(old == laTortoise) return laDragon;
@ -1673,15 +1670,13 @@ eLand getNewLand(eLand old) {
if(isWarped(old) && (hrand(100) < 25) && chaosmode) return eLand(old ^ laWarpCoast ^ laWarpSea);
if(old == laWarpSea || old == laCaribbean || old == laKraken ||
(old == laLivefjord && hrand(2)) ||
(old == laOcean && (chaosmode ? hrand(2) : !generatingEquidistant)))
if(createOnSea(old))
return getNewSealand(old);
if(old == laGraveyard && generatingEquidistant)
return laHaunted;
if(old == laOcean && gold() >= 60 && hrand(100) < 75 && !rlyehComplete())
if(old == laOcean && gold() >= R60 && hrand(100) < 75 && !rlyehComplete())
return laRlyeh;
if(old == laRlyeh && !rlyehComplete())
@ -1708,7 +1703,7 @@ eLand getNewLand(eLand old) {
if(old != laDeadCaves) tab[cnt++] = laCaves;
// the intermediate lands
if(gold() >= 30) {
if(gold() >= R30) {
tab[cnt++] = laCrossroads;
tab[cnt++] = laMirror;
tab[cnt++] = laOcean;
@ -1717,15 +1712,15 @@ eLand getNewLand(eLand old) {
tab[cnt++] = laPalace;
if(old == laDragon) LIKELY tab[cnt++] = laReptile;
if(kills[moVizier]) tab[cnt++] = laEmerald;
if(items[itFeather] >= 10) tab[cnt++] = laZebra;
if(items[itFeather] >= U10) tab[cnt++] = laZebra;
tab[cnt++] = laWarpCoast;
if(euclid) tab[cnt++] = laWarpSea;
// Ivory Tower tends to crash while generating equidistant
if(!generatingEquidistant) tab[cnt++] = laIvoryTower;
if(items[itElixir] >= 10) tab[cnt++] = laReptile;
if(items[itIvory] >= 10 && !generatingEquidistant) tab[cnt++] = laEndorian;
if(items[itElixir] >= U10) tab[cnt++] = laReptile;
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)) {
@ -1734,29 +1729,29 @@ eLand getNewLand(eLand old) {
}
// the advanced lands
if(gold() >= 60) {
if(gold() >= R60) {
tab[cnt++] = laStorms;
tab[cnt++] = laWhirlwind;
tab[cnt++] = laCrossroads;
if(!generatingEquidistant) tab[cnt++] = laCrossroads2;
if(items[itRuby] >= 10) {
if(items[itRuby] >= U10) {
tab[cnt++] = laOvergrown;
if(old == laJungle) LIKELY tab[cnt++] = laOvergrown;
}
if(rlyehComplete()) tab[cnt++] = laRlyeh;
else if(chaosmode && (old == laWarpCoast || old == laLivefjord || old == laOcean))
tab[cnt++] = laRlyeh;
if(items[itStatue] >= 5 && chaosmode)
if(items[itStatue] >= U5 && chaosmode)
tab[cnt++] = laTemple;
if(old == laCrossroads || old == laCrossroads2) tab[cnt++] = laOcean;
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++] = laDryForest;
tab[cnt++] = laWineyard;
if(items[itGold] >= 10) tab[cnt++] = laDeadCaves;
if(items[itGold] >= U10) tab[cnt++] = laDeadCaves;
// tab[cnt++] = laCaribbean;
if(items[itSpice] >= 10) {
if(items[itSpice] >= U10) {
tab[cnt++] = laRedRock;
if(old == laDesert) LIKELY tab[cnt++] = laRedRock;
}
@ -1765,22 +1760,22 @@ eLand getNewLand(eLand old) {
tab[cnt++] = laRose;
}
if(gold() >= 90) {
if(gold() >= R90) {
if(!chaosmode) tab[cnt++] = laPrairie;
if(old == laPrairie) LIKELY tab[cnt++] = laBull;
tab[cnt++] = laBull;
if(old == laBull && !chaosmode) LIKELY tab[cnt++] = laPrairie;
}
if(gold() >= 300)
if(gold() >= R300)
tab[cnt++] = laCrossroads5;
if(tkills() >= 100) {
if(tkills() >= R100) {
tab[cnt++] = laGraveyard;
if(gold() >= 60) tab[cnt++] = laHive;
if(gold() >= R60) tab[cnt++] = laHive;
}
if(killtypes() >= 20) {
if(killtypes() >= R20) {
tab[cnt++] = laDragon;
if(old == laReptile) LIKELY tab[cnt++] = laDragon;
}
@ -1815,8 +1810,8 @@ eLand getNewLand(eLand old) {
tab[cnt++] = laHell;
}
if(items[itHell] >= 10) {
if(items[itDiamond] >= 10) {
if(items[itHell] >= U10) {
if(items[itDiamond] >= U10) {
tab[cnt++] = laCocytus;
if(old == laHell || old == laIce) LIKELY tab[cnt++] = laCocytus;
}
@ -1839,6 +1834,7 @@ eLand getNewLand(eLand old) {
}
bool notDippingFor(eItem i) {
if(peace::on) return false;
int v = items[i] - currentLocalTreasure;
if(v <= 10) return true;
if(v >= 20) return false;
@ -1846,6 +1842,7 @@ bool notDippingFor(eItem i) {
}
bool notDippingForExtra(eItem i, eItem x) {
if(peace::on) return false;
int v = items[i] - min(items[x], currentLocalTreasure);
if(v <= 10) return true;
if(v >= 20) return false;
@ -1932,25 +1929,28 @@ eLand showlist[10] = {
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) {
d %= 7;
cellwalker bb(c, d);
if(checkBarriersFront(bb) && checkBarriersBack(bb)) {
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);
}
if(checkBarriersFront(bb) && checkBarriersBack(bb))
buildBarrierForce(c, d, l);
}
bool buildBarrier4(cell *c, int d, int mode, eLand ll, eLand lr) {
@ -2138,21 +2138,13 @@ extern bool bugtrack;
bool generatingEquidistant = false;
void buildAnotherEquidistant(cell *c) {
//printf("building another coast\n");
if(yendor::on) return;
cell *buildAnotherEquidistant(cell *c, int radius) {
int gdir = -1;
for(int i=0; i<c->type; 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);
vector<cell*> coastpath;
while(size(coastpath) < radius || cw.c->type != 7) {
@ -2161,13 +2153,10 @@ void buildAnotherEquidistant(cell *c) {
#ifdef AUTOPLAY
if(doAutoplay) printf("avoiding the Crossroads II\n"); // todo
#endif
generatingEquidistant = false;
return;
}
if(cw.c->bardir != NODIR) {
generatingEquidistant = false;
return;
return NULL;
}
if(cw.c->bardir != NODIR) return NULL;
/* forCellEx(c2, cw.c) if(c2->bardir != NODIR) {
generatingEquidistant = false;
return;
@ -2176,21 +2165,21 @@ void buildAnotherEquidistant(cell *c) {
if(cw.c->land == laNone && cw.c->mpdist <= 7) {
raiseBuggyGeneration(cw.c, "landNone 1");
for(int i=0; i<size(coastpath); i++) coastpath[i]->item = itPirate;
return;
return NULL;
}
cwstep(cw); cwspin(cw, 3);
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);
// printf("setdists\n");
for(int i=1; i<size(coastpath) - 1; i++) {
if(coastpath[i-1]->land == laNone) {
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<size(coastpath); i++) coastpath[i]->item = itPirate;
return;
return NULL;
}
setdist(coastpath[i], BARLEV, coastpath[i-1]);
setdist(coastpath[i], BARLEV-1, coastpath[i-1]);
@ -2210,16 +2199,14 @@ void buildAnotherEquidistant(cell *c) {
if(c2->land == laNone) {
raiseBuggyGeneration(c2, "landNone 2");
for(int i=0; i<size(coastpath); i++) coastpath[i]->item = itPirate;
return;
return NULL;
}
if(c2->land != c->land) {
generatingEquidistant = false;
return; // prevent gravity anomalies
}
// prevent gravity anomalies
if(c2->land != c->land) return NULL;
// 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;
// raiseBuggyGeneration(c2, "check");
// return;
@ -2232,7 +2219,21 @@ void buildAnotherEquidistant(cell *c) {
for(int j=BARLEV; j>=6; j--)
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;
}
@ -2279,7 +2280,11 @@ eMonster crossroadsMonster() {
moWaterElemental, moAirElemental, moFireElemental,
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() {
@ -2535,7 +2540,7 @@ void buildRedWall(cell *c, int gemchance) {
c->wall = waRed3;
if(hrand(100+ki) < gemchance + ki)
c->item = itRedGem;
if(items[itRedGem] >= 10 && hrand(8000) < gemchance)
if(items[itRedGem] >= 10 && hrand(8000) < gemchance && !peace::on && !inv::on)
c->item = itOrbSpace;
else if(hrand(8000) < gemchance * PRIZEMUL)
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 &&
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) &&
(c->land != laRlyeh || rlyehComplete()) &&
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 &&
(quickfind(laCamelot) || (hrand(2000) < 200 &&
items[itEmerald] >= 5 && !tactic::on))) {
(quickfind(laCamelot) || peace::on || (hrand(2000) < 200 &&
items[itEmerald] >= U5 && !tactic::on))) {
int rtr = newRoundTableRadius();
heptagon *alt = createAlternateMap(c, rtr+14, hsOrigin);
if(alt) {
@ -2951,8 +2956,8 @@ void buildBigStuff(cell *c, cell *from) {
// buildbigstuff
if(c->land == laRlyeh && c->type == 7 &&
(quickfind(laTemple) || (hrand(2000) < 100 &&
items[itStatue] >= 5 && !randomPatternsMode &&
(quickfind(laTemple) || peace::on || (hrand(2000) < 100 &&
items[itStatue] >= U5 && !randomPatternsMode &&
!tactic::on && !yendor::on)))
createAlternateMap(c, 2, hsA);
@ -2963,7 +2968,7 @@ void buildBigStuff(cell *c, cell *from) {
if(c->land == laOvergrown && c->type == 7 &&
(quickfind(laClearing) || (hrand(2000) < 25 &&
!randomPatternsMode && items[itMutant] >= 5 &&
!randomPatternsMode && items[itMutant] >= U5 &&
!tactic::on && !yendor::on))) {
heptagon *h = createAlternateMap(c, 2, hsA);
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(c->land == laOcean && c->type == 7 && deepOcean && !generatingEquidistant &&
if(c->land == laOcean && c->type == 7 && deepOcean && !generatingEquidistant && !peace::on &&
(quickfind(laWhirlpool) || (
hrand(2000) < (purehepta ? 500 : 1000) && !tactic::on && !yendor::on)))
createAlternateMap(c, 2, hsA);
@ -2983,9 +2988,10 @@ void buildBigStuff(cell *c, cell *from) {
createAlternateMap(c, 2, hsA);
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 &&
(princess::challenge || kills[moVizier]) && !tactic::on && !yendor::on)
(princess::challenge || kills[moVizier] || peace::on) && !tactic::on && !yendor::on)
createAlternateMap(c, 141, hsOrigin, waPalace);
}
@ -3233,6 +3239,7 @@ bool redtrolls(cell *c) {
}
bool reptilecheat = false;
bool weaponless = false;
eMonster pickTroll(cell *c) {
if(redtrolls(c))
@ -3450,6 +3457,8 @@ void setdist(cell *c, int d, cell *from) {
cell *c2 = c->mov[hrand(c->type)];
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) {
@ -3641,7 +3650,7 @@ void setdist(cell *c, int d, cell *from) {
}
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;
forCellCM(c2, c) forCellCM(c3, c2) forCellCM(c4, c3) forCellCM(c5, c4) {
cell *cx = chaosmode ? c3 : c5;
@ -4252,7 +4261,7 @@ void setdist(cell *c, int d, cell *from) {
c2->hitpoints = 1;
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(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->wall = waNone;
for(int i=0; i<c->type; i++)
@ -4338,7 +4347,7 @@ void setdist(cell *c, int d, cell *from) {
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;
}
}
@ -4373,7 +4382,7 @@ void setdist(cell *c, int d, cell *from) {
}
if(coast && hrand(10) < 5) {
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;
else if(hrand(100) < 2*PRIZEMUL && !safety)
placePrizeOrb(c);
@ -4384,7 +4393,7 @@ void setdist(cell *c, int d, cell *from) {
c->monst = moSeep;
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;
else {
c->monst = moViking;
@ -4401,7 +4410,7 @@ void setdist(cell *c, int d, cell *from) {
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;
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) {
if(hrand(1000) < 5)
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;
if(hrand(15000) < 10 + 2 * items[itCoast] + 2 * hard)
c->monst = moAlbatross;
if(items[itCoast] >= 10 && hrand(10000) < 5)
if(items[itCoast] >= 10 && hrand(10000) < 5 && !peace::on && !inv::on)
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;
if(hrand(10000) < 5*PRIZEMUL)
placePrizeOrb(c);
@ -4539,13 +4548,13 @@ void setdist(cell *c, int d, cell *from) {
if(hrand(5000) < minefreq)
c->wall = waMineMine;
else if(hrand(5000) < tfreq && !safety) {
else if(hrand(5000) < tfreq && !safety && !peace::on) {
c->item = itBombEgg;
c->landparam = items[itBombEgg] + 5 + hrand(11);
}
else if(hrand(5000) < treas - 20 + yendor::hardness() && !safety)
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;
else if(hrand(5000) < 10*PRIZEMUL && !safety)
placePrizeOrb(c);
@ -4665,7 +4674,7 @@ void setdist(cell *c, int d, cell *from) {
else
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;
}
}
@ -4673,7 +4682,7 @@ void setdist(cell *c, int d, cell *from) {
if(c->land == laDungeon) {
int lp = c->landparam * c->landparam;
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;
}
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(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->hitpoints = 3;
}
int chance = 50 + items[itBabyTortoise]*2;
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;
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) &&
c->wall != waOpenGate && !lookingForPrincess0)
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;
if(hrand(5000) < 20*PRIZEMUL && c->wall != waOpenGate)
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))
c->item = itSpice;
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;
}
if(c->land == laRedRock) {
@ -4814,7 +4823,7 @@ void setdist(cell *c, int d, cell *from) {
int i = -1;
for(int t=0; t<6; t++) if(c->mov[t]->mpdist > c->mpdist && !pseudohept(c->mov[t]))
i = t;
if(i != -1) {
if(i != -1 && !peace::on) {
c->monst = moHexSnake;
preventbarriers(c);
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)
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;
// printf("dragon generated with dchance = %d\n", dchance);
vector<int> possi;
@ -4887,7 +4896,7 @@ void setdist(cell *c, int d, cell *from) {
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;
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))
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;
else if(hrand(5000) < 10*PRIZEMUL)
placePrizeOrb(c);
@ -4939,7 +4948,7 @@ void setdist(cell *c, int d, cell *from) {
c->stuntime = 7;
}
}
if(c->land == laBurial && !safety) {
if(c->land == laBurial && !safety && !peace::on) {
if(hrand(15000) < 5 + 3 * items[itBarrow] + 4 * hard)
c->monst = moDraugr;
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;
if(hardchance > 25) hardchance = 25;
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;
}
}
@ -5061,7 +5070,7 @@ void setdist(cell *c, int d, cell *from) {
if(c->land == laRlyeh) {
if(hrand(5000) < PT(30 + 2 * (kills[moCultist] + kills[moTentacle] + kills[moPyroCultist]), 100) && notDippingFor(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;
else if(hrand(12000) < 5 + items[itStatue] + hard)
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;
// remember: d is negative
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;
}
else {
// int d0 = d % TEMPLE_EACH;
// 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;
else if(hrand(20000) < -d)
c->monst = hrand(3) ? moCultist : moPyroCultist;
@ -5096,7 +5105,7 @@ void setdist(cell *c, int d, cell *from) {
c->monst = moCultistLeader;
else if(hrand(5000) < 250)
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;
}
}
@ -5116,7 +5125,7 @@ void setdist(cell *c, int d, cell *from) {
c->item = itFernFlower;
if(hrand(4000) < 40 + items[itFernFlower] + hard)
c->monst = moHedge;
else if(hrand(8000) < 2 * items[itFernFlower] + hard)
else if(hrand(8000) < 2 * items[itFernFlower] + hard && !peace::on)
c->monst = moFireFairy;
}
if(c->land == laHell) {
@ -5167,8 +5176,8 @@ void setdist(cell *c, int d, cell *from) {
c->monst = eMonster(moBug0 + hrand(3)); */
}
if(c->land == laCaribbean) {
// if(hrand(1500) < 60 && celldistAlt(c) <= -5)
// c->item = itCompass;
if(hrand(1500) < 4 && celldistAlt(c) <= -5 && peace::on)
c->item = itCompass;
if(hrand(16000) < 40 + (items[itPirate] + hard))
c->monst = moPirate;
}
@ -5227,6 +5236,7 @@ int getGhostTimer() {
}
int getGhostcount() {
if(peace::on) return 0;
int t = getGhostTimer();
int ghostcount = 0;
if(t > 80) ghostcount = (t-80 + hrand(20)) / 20;
@ -5383,12 +5393,12 @@ void wandering() {
playSeenSound(c);
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;
playSeenSound(c);
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);
if(sphere && (haveKraken() || !items[itOrbFish])) {
c->monst = moViking; c->wall = waBoat; c->item = itOrbFish;
@ -5427,13 +5437,13 @@ void wandering() {
c->monst = hrand(2) ? moWolf : moYeti;
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))
c->monst = moFireElemental;
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))
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)
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);
else if(c->land == laIvoryTower && wchance(items[itIvory], 20))

View File

@ -39,21 +39,21 @@ dictionary<noun> nouns[NUMLAN];
#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) {
int i = 0;
//printf("%s\n", w.c_str());
while(i < size(w)) {
if(((signed char)(w[i])) < 0) {
string z = w.substr(i, 2);
// 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++;
}
int siz = utfsize(w[i]);
s.insert(w.substr(i, siz));
i += siz;
}
}
@ -143,6 +143,8 @@ int main() {
plural.insert("Elemental Planes");
plural.insert("Crossroads IV");
plural.insert("Kraken Depths");
allchars.insert("");
allchars.insert("δ");
#define S(a,b) d[1].add(a,b);
#define N(a,b,c,d,e,f) \
@ -236,7 +238,7 @@ int main() {
//printf("ALL:");
for(set<string>::iterator it = allchars.begin(); it != allchars.end(); it++) {
// 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("\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("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("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("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.")
@ -367,11 +367,11 @@ S("GAME OVER", "KONEC HRY")
S("Your score: %1", "Tvé skóre: %1")
S("Enemies killed: %1", "Zabitých netvorů: %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 60 $$$ to access R'Lyeh and Dry Forest", "R'Lyeh a Suchý hvozd zpřístupníš sesbíráním 60 $$$")
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 %1 $$$ to access more worlds", "Další kraje zpřístupníš sesbíráním %1 $$$")
// 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 %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("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("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!")
@ -1009,7 +1009,7 @@ S("Periodic Editor", "Periodický editor")
// also translate this line:
// "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
// ------------
@ -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("Kills required: %1.\n", "Potřebuješ zabít %1 nepřátel.\n")
S("Finished lands required: %1 (collect 10 treasure)\n",
"Potřebuješ dokončit %1 krajů (získat v nich 10 pokladů)\n")
S("Finished lands required: %1 (collect %2 treasure)\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")
@ -3821,8 +3821,8 @@ S(
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("Hyperstone Quest: collect at least 10 points in %the2",
"Hyperkamový úkol: získej nejméně 10 bodů %abl2")
S("Hyperstone Quest: collect at least %3 points in %the2",
"Hyperkamový úkol: získej nejméně %3 bodů %abl2")
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.",
@ -5011,7 +5011,7 @@ N("Tortoise", GEN_F, "Želva", "Želvy", "Želva", "Želvou")
S("line patterns", "vzory čar")
S("1 turn", "1 kolo")
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("letters", "písmena")
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("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("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("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.")
@ -334,10 +334,10 @@ S("GAME OVER", "GAME OVER")
S("Your score: %1", "Punkte: %1")
S("Enemies killed: %1", "Getötete Gegner: %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 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 %1 $$$ to access more worlds", "Sammle %1 $$$ um mehr Länder betreten zu können")
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("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("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!")
@ -947,7 +947,7 @@ S("Periodic Editor", "Periodischer Editor")
// "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"
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
@ -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("Kills required: %1.\n", "Benötigte Kills: %1.\n")
S("Finished lands required: %1 (collect 10 treasure)\n",
"Abgeschlossene Länder benötigt: %1 (sammle 10 Schätze)\n")
S("Finished lands required: %1 (collect %2 treasure)\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")
@ -3427,7 +3427,8 @@ S("Dragon Scales are a prized material for armors. "
"wie sie einen Drachen getötet haben.\n\n"
"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 "
"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 "
"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 "
"fire (at range 3), losing the hitpoint. Killing the Dragon gives you "
"treasure.",
"fire (at range 3), losing the hitpoint. Killing the Dragon "
"while still in the Dragon Chasms gives you treasure.",
"Drachen sind mächtige Monster. Sie sind langsam, aber böse, "
"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 attacks your shell!", "%Der1 %1 attackiert deinen Panzer!")
S("Hyperstone Quest: collect at least 10 points in %the2",
"Hyperstein-Herausforderung: sammle mindestens 10 Punkte %abl2")
S("Hyperstone Quest: collect at least %3 points in %the2",
"Hyperstein-Herausforderung: sammle mindestens %3 Punkte %abl2")
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.",

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("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("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("And the Orbs of Yendor await!", "I sfery Yendoru czekają!")
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("Enemies killed: %1", "Potwory pokonane: %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 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 %1 $$$ to access more worlds", "Znajdź %1 $$$, by iść do nowych krain")
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("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("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!")
@ -994,7 +994,7 @@ S("Periodic Editor", "Edytor okresowy")
// also translate this line:
// "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
// ------------
@ -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("Kills required: %1.\n", "Wymagani pokonani przeciwnicy: %1.\n")
S("Finished lands required: %1 (collect 10 treasure)\n",
"Wymagane ukończone krainy: %1 (zdobądź 10 skarbów)\n")
S("Finished lands required: %1 (collect %2 treasure)\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")
@ -3737,8 +3737,8 @@ S(
S("%The1 scares %the2 a bit!", "%1 troszkę przestraszy%ł1 %a2!")
S("%The1 attacks your shell!", "%1 zaatakowa%ł1 Twoją skorupę!")
S("Hyperstone Quest: collect at least 10 points in %the2",
"Misja Hiperkamień: zdobądź co najmniej 10 punktów %abl2")
S("Hyperstone Quest: collect at least %3 points in %the2",
"Misja Hiperkamień: zdobądź co najmniej %3 punktów %abl2")
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.",
@ -4946,7 +4946,7 @@ N("Tortoise", GEN_M, "Żółw", "Żółwie", "Żółwia", "Żółwiem")
S("line patterns", "wzory linii")
S("1 turn", "1 kolejka")
S("%1 turns", "kolejek: %1")
S("items/kills mode", "tryb rzeczy/zabić")
S("inventory/kill mode", "tryb rzeczy/zabić")
S("images", "obrazki")
S("letters", "literki")
S("input", "sterowanie")
@ -5442,4 +5442,22 @@ S(
#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("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("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("And the Orbs of Yendor await!", "Шары Йендора ждут!")
S("You switch places with %the1.", "Вы поменялись местами с %abl1.")
@ -340,10 +340,10 @@ S("GAME OVER", "КОНЕЦ ИГРЫ")
S("Your score: %1", "Ваш счёт: %1")
S("Enemies killed: %1", "Врагов убито: %1")
S("Orbs of Yendor found: %1", "Собрано сфер Йендора: %1")
S("Collect 30 $$$ to access more worlds", "Соберите 30 $$$, чтобы открыть новые земли")
S("Collect at least 10 treasures in each of 9 types to access Hell", "Соберите хотя бы по 10 сокровищ 9 разных типов, чтобы попасть в Ад")
S("Collect %1 $$$ to access more worlds", "Соберите %1 $$$, чтобы открыть новые земли")
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("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("Look for the Orbs of Yendor in Hell or in the Crossroads!", "Ищите сферы Йендора в Аду и на Перекрёстке!")
S("Unlock the Orb of Yendor!", "Откройте сферу Йендора!")
@ -978,7 +978,7 @@ S("Periodic Editor", "Периодический редактор")
// also translate this line:
// "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
// ------------
@ -2169,6 +2169,18 @@ S("player 4 X", "игрок 4 X")
S("player 4 Y", "игрок 4 Y")
S("player 4 go", "игрок 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("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("Kills required: %1.\n", "УБийств нужно: %1 $$$.\n")
S("Finished lands required: %1 (collect 10 treasure)\n",
"Земель окончено: %1 (собрано 10 сокровищ)\n")
S("Finished lands required: %1 (collect %2 treasure)\n",
"Земель окончено: %1 (собрано %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 attacks your shell!", "%1 атакует вашу раковину!")
S("Hyperstone Quest: collect at least 10 points in %the2",
"Миссия Гиперкамней: собери не меньше 10 очков %abl2")
S("Hyperstone Quest: collect at least %3 points in %the2",
"Миссия Гиперкамней: собери не меньше %3 очков %abl2")
S("animals killed: %1", "животных убито: %1")
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("1 turn", "1 ход")
S("%1 turns", "ходов: %1")
S("items/kills mode", "режим предметов/убийств")
S("inventory/kill mode", "режим предметов/убийств")
S("images", "изображения")
S("letters", "буквы")
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("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("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("And the Orbs of Yendor await!", "Yendorun Küresi seni bekliyor!")
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("Enemies killed: %1", "Öldürülen Düşmanlar: %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 60 $$$ 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 %1 $$$ to access more worlds", "%1 $$$ toplayarak başka dünyalara eriş")
// S("Collect %1 $$$ to access R'Lyeh and Dry Forest", "60 $$$ toplayarak R'Lyeh ve Kara Ormana eriş.")
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("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("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ç!")
@ -921,7 +921,7 @@ S("Periodic Editor", "Periyodik Editör")
// "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"
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
// ------------
@ -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("Kills required: %1.\n", "Gereken leşler: %1 $$$.\n")
S("Finished lands required: %1 (collect 10 treasure)\n",
"Gereken bitirilmiş diyarlar: %1 (10 hazine toplananlar)\n")
S("Finished lands required: %1 (collect %2 treasure)\n",
"Gereken bitirilmiş diyarlar: %1 (%2 hazine toplananlar)\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
cell *drawcell;
#ifndef NOEDIT
int paintwhat = 0;
int painttype = 0;
@ -436,9 +438,7 @@ namespace mapeditor {
bool symRotation, sym01, sym02, sym03;
int whichpart;
cell *drawcell;
const char *mapeditorhelp =
"This mode allows you to edit the map.\n\n"
"NOTE: Use at your own risk. Combinations which never "
@ -547,7 +547,7 @@ namespace mapeditor {
bool editext = false;
#define CDIR 0xC0C0C0
#define CFILE 0xFFFFFF
#define CFILE forecolor
bool filecmp(const pair<string,int> &f1, const pair<string,int> &f2) {
if(f1.first == "../") return true;
@ -559,7 +559,7 @@ namespace mapeditor {
void drawFileDialog() {
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;
displayfr(vid.xres/2, 34 + vid.fsize * 2, 2, vid.fsize,
@ -748,7 +748,7 @@ namespace mapeditor {
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);
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]);
int state = 0;
int gstate = 0;
double dist2;
double dist2 = 0;
hyperpoint lpsm;
for(int a=0; a<ds.rots; a++)
@ -2029,6 +2029,7 @@ namespace linepatterns {
{patTrihepta, "triheptagonal tesselation", (int) 0x0000C000},
{patNormal, "normal tesselation", (int) 0x0000C000},
{patBigTriangles, "big triangular grid", (int) 0x00606000},
{patBigRings, "big triangles: rings", (int) 0x0000C000},
{patTree, "underlying tree", (int) 0x00d0d000},
{patAltTree, "circle/horocycle tree", (int) 0xd000d000},
@ -2060,7 +2061,176 @@ namespace linepatterns {
for(int k=0; patterns[k].lpname; k++)
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() {
if(any()) for(map<cell*, transmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) {
@ -2072,163 +2242,7 @@ namespace linepatterns {
if(!(col & 255)) continue;
int id = patterns[k].id;
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(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;
}
}
drawPattern(id, col, c, V);
}
}
}

734
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,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,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,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,
@ -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,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,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
};

View File

@ -11,6 +11,8 @@ bool first;
bool fatborder;
int poly_outline;
#define PSHIFT 0
// #define STLSORT
@ -25,6 +27,10 @@ struct hpcshape {
hpcshape *last = NULL;
#ifndef GL
typedef float GLfloat;
#endif
struct qpoly {
transmatrix V;
GLfloat *tab;
@ -36,9 +42,10 @@ struct qpoly {
struct qline {
hyperpoint H1, H2;
int prf;
double width;
};
#define MAXQCHR 16
#define MAXQCHR 40
struct qchr {
char str[MAXQCHR];
@ -122,17 +129,17 @@ SDL_Surface *aux;
vector<polytodraw*> ptds2;
#define POLYMAX 60000
#ifdef GL
#define USEPOLY
GLuint shapebuffer;
#define POLYMAX 60000
GLfloat glcoords[POLYMAX][3];
int qglcoords;
extern void glcolor(int color);
#endif
GLfloat *currentvertices;
@ -142,7 +149,25 @@ void activateVertexArray(GLfloat *f, int qty) {
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;
void initPolyForGL() {
@ -158,24 +183,11 @@ void initPolyForGL() {
ourshape[id++] = hpc[i][1];
ourshape[id++] = hpc[i][2];
}
#ifdef GL
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
int polyi;
@ -189,6 +201,7 @@ hyperpoint gltopoint(GLfloat t[3]) {
}
void addpoint(const hyperpoint& H) {
#ifdef GL
if(vid.usingGL) {
if(polyi >= POLYMAX) return;
if(pmodel) {
@ -211,6 +224,9 @@ void addpoint(const hyperpoint& H) {
}
qglcoords++;
}
#else
if(0) {}
#endif
else {
if(polyi >= POLYMAX) return;
hyperpoint Hscr;
@ -256,6 +272,7 @@ void filledPolygonColorI(SDL_Surface *s, int* polyx, int *polyy, int polyi, int
}
#endif
#ifdef GL
void glcolor2(int color) {
unsigned char *c = (unsigned char*) (&color);
glColor4f(c[3] / 255.0, c[2] / 255.0, c[1]/255.0, c[0] / 255.0);
@ -339,7 +356,22 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
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) {
#ifdef GL
if(vid.usingGL) {
@ -347,7 +379,8 @@ void drawpolyline(const transmatrix& V, GLfloat* tab, int cnt, int col, int outl
const int pq = cnt;
if(currentvertices != tab)
activateVertexArray(tab, pq);
const int ps=0;
const int ps=0;
glLineWidth(linewidthat(tC0(V)));
gldraw(1, V, ps, pq, col, outline);
}
else {
@ -388,7 +421,7 @@ void drawpolyline(const transmatrix& V, GLfloat* tab, int cnt, int col, int outl
filledPolygonColorI(s, polyx, 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.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);
}
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);
}
else if(ptd.kind == pkString) {
@ -456,13 +490,8 @@ void drawqueueitem(polytodraw& ptd) {
if(svg::in)
svg::text(q.x, q.y, q.size, q.str, q.frame, ptd.col, q.align);
else {
if(q.frame) {
displaystr(q.x-q.frame, q.y, q.shift, q.size, q.str, 0, q.align);
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);
int fr = q.frame & 255;
displayfrSP(q.x, q.y, q.shift, fr, q.size, q.str, ptd.col, q.align, q.frame >> 8);
}
#else
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);
}
#endif
}
void initquickqueue() {
ptds.clear();
poly_outline = OUTLINE_NONE;
}
void quickqueue() {
@ -565,13 +600,13 @@ void drawqueue() {
drawqueueitem(ptd);
}
#ifdef GL
if(vid.goteyes && vid.usingGL) selectEyeGL(0), selectEyeMask(0);
#endif
#endif
setcameraangle(false);
curvedata.clear(); curvestart = 0;
#endif
}
hpcshape
@ -1574,8 +1609,6 @@ void initShape(int sg, int id) {
}
}
int poly_outline;
unsigned char& part(int& col, int 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.H2 = H2;
ptd.u.line.prf = prf;
ptd.u.line.width = (linewidthat(H1) + linewidthat(H2)) / 2;
ptd.col = (darkened(col >> 8) << 8) + (col & 0xFF);
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.size = size;
ptd.col = darkened(col);
ptd.u.chr.frame = frame;
ptd.u.chr.frame = frame ? (poly_outline & ~ 255) : 0;
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.align = align;
ptd.col = col;
ptd.u.chr.frame = frame;
ptd.u.chr.frame = frame ? (poly_outline & ~ 255) : 0;
ptd.prio = PPR_TEXT << PSHIFT;
}
@ -1912,6 +1946,7 @@ namespace svg {
dynamicval<videopar> v(vid, vid);
dynamicval<bool> v2(in, true);
dynamicval<int> v4(cheater, 0);
dynamicval<int> v5(ringcolor, 0x808080FF);
vid.usingGL = false;
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;
}
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) {
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) {
// 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);
vdata.resize(id+1);
vertexdata& vd(vdata[id]);
@ -178,6 +193,7 @@ void addedge(int i, int j, edgeinfo *ei) {
addedge(i, id, ei);
addedge(id, j, ei);
shmup::virtualRebase(vd.m, true);
}
else addedge0(i, j, ei);
}
@ -204,7 +220,14 @@ int dftcolor = 0x282828FF;
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;
vdata.resize(N);
@ -213,7 +236,7 @@ namespace spiral {
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);
vd.name = its(i+1);
@ -265,17 +288,35 @@ namespace collatz {
}
}
int readLabel(FILE *f) {
string readLabel_s(FILE *f) {
char xlabel[10000];
if(fscanf(f, "%9500s", xlabel) <= 0) return -1;
return getid(xlabel);
if(fscanf(f, "%9500s", xlabel) <= 0) return "";
return xlabel;
}
int readLabel(FILE *f) {
string s = readLabel_s(f);
if(s == "") return -1;
return getid(s);
}
namespace anygraph {
double R, alpha, T;
vector<pair<double, double> > coords;
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) {
void read(string fn, bool subdiv = true, bool doRebase = true, bool doStore = true) {
init(); kind = kAnyGraph;
fname = fn;
FILE *f = fopen((fn + "-coordinates.txt").c_str(), "rt");
@ -285,17 +326,17 @@ namespace anygraph {
}
printf("Reading coordinates...\n");
char buf[100];
int N;
int err;
err = fscanf(f, "%s%s%s%s%d%lf%lf%lf", buf, buf, buf, buf, &N,
&anygraph::R, &anygraph::alpha, &anygraph::T);
if(err < 8) { printf("Error: incorrect format of the first line\n"); exit(1); }
vdata.reserve(N);
while(true) {
int id = readLabel(f);
if(id < 0) break;
string s = readLabel_s(f);
if(s == "" || s == "-1") break;
int id = getid(s);
vertexdata& vd(vdata[id]);
vd.name = its(id);
vd.name = s;
vd.cp = colorpair(dftcolor);
double r, alpha;
@ -333,6 +374,8 @@ namespace anygraph {
}
printf("Done.\n");
}
if(doStore) storeall();
}
}
@ -1030,8 +1073,7 @@ void drawVertex(const transmatrix &V, cell *c, shmup::monster *m) {
transmatrix& gm1 = shmup::ggmatrix(vd1.m->base);
transmatrix& gm2 = shmup::ggmatrix(vd2.m->base);
hyperpoint h1 = gm1 * vd1.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 =
((hilite ? 0xFF0000 : backcolor ? 0x808080 : 0xFFFFFF) << 8) + xlalpha;
if(pmodel) {
queueline(h1, h2, col, 2);
lastptd().prio = PPR_STRUCT0;
((hilite ? 0xFF0000 : forecolor) << 8) + xlalpha;
bool onspiral = kind == kSpiral && abs(ei->i - ei->j) == 1;
if(pmodel || onspiral) {
if(onspiral) {
const int prec = 20;
transmatrix T = shmup::ggmatrix(currentmap->gamestart());
hyperpoint l1 = T*tC0(spiral::at(1+ei->i));
for(int z=1; z<=prec; z++) {
hyperpoint l2 = T*tC0(spiral::at(1+ei->i+(ei->j-ei->i) * z / (prec+.0)));
queueline(l1, l2, col, 0);
l1 = l2;
lastptd().prio = PPR_STRUCT0;
}
}
else {
queueline(h1, h2, col, 2);
lastptd().prio = PPR_STRUCT0;
}
}
else {
@ -1058,8 +1114,22 @@ void drawVertex(const transmatrix &V, cell *c, shmup::monster *m) {
if(!ei->orig) {
ei->orig = euclid ? cwt.c : viewctr.h->c7; // cwt.c;
ei->prec.clear();
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,
PPR_STRUCT0);
@ -1180,12 +1250,15 @@ void drawExtra() {
for(int i=0; i<size(named); i++) if(gmatrix.count(named[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;
}
#ifndef NORUG
if(!rug::rugged)
#endif
for(int i=0; i<size(legend); i++) {
int k = legend[i];
vertexdata& vd = vdata[k];
@ -1199,7 +1272,8 @@ void drawExtra() {
poly_outline = OUTLINE_NONE;
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;
firstland = euclidland = laCanvas;
if(!shmup::on) restartGame('s');
else restartGame();
#else
firstland = euclidland = laCanvas;
restartGame();
@ -1310,6 +1385,7 @@ void fixparam() {
if(size(legend)) vid.xcenter = vid.ycenter;
}
#ifndef NOSDL
void rvvideo(const char *fname) {
if(kind == kCollatz) {
pngformat = 2;
@ -1465,6 +1541,7 @@ struct storydata { int s; int e; const char *text; } story[] = {
saveHighQualityShot(buf);
}
}
#endif
int readArgs() {
using namespace arg;
@ -1636,9 +1713,11 @@ int readArgs() {
else if(argis("-TURN")) {
PHASE(3); shmup::turn(100);
}
#ifndef NOSDL
else if(argis("-video")) {
shift(); rvvideo(args());
}
#endif
else return 1;
return 0;
}
@ -1674,7 +1753,7 @@ void handleMenu(int sym, int uni) {
else if(uni == 'l') showlabels = !showlabels;
else if(uni == 'v') rog3 = !rog3;
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') {
dialog::editNumber(ggamma, 0, 5, .01, 0.5, XLAT("gamma value for edges"), "");
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[] = {
{"HyperRogue", 999, LEGAL_ANY,
{"RogueViz", 999, LEGAL_ANY,
"This is a presentation of RogueViz, which "
"is an adaptation of HyperRogue as a visualization tool "
"rather than a game. Hyperbolic space is great "
@ -1751,15 +1848,16 @@ slide rvslides[] = {
,
[] (presmode mode) {
slidecommand = "the standard presentation";
if(mode == pmStartAll) firstland = euclidland = laPalace;
if(mode == 4) {
tour::slides = default_slides;
while(tour::on) restartGame('T', false);
firstland = euclidland = laIce;
firstland = euclidland = laIce;
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.",
[] (presmode mode) {
using namespace linepatterns;
@ -1812,9 +1910,9 @@ slide rvslides[] = {
drawthemap();
gmatrix0 = gmatrix;
rogueviz::sag::read("rogueviz/roguelikes/edges.csv");
rogueviz::readcolor("rogueviz/roguelikes/color.csv");
rogueviz::sag::loadsnake("rogueviz/roguelikes/" + cname());
rogueviz::sag::read(RVPATH "roguelikes/edges.csv");
rogueviz::readcolor(RVPATH "roguelikes/color.csv");
rogueviz::sag::loadsnake(RVPATH "roguelikes/" + cname());
})
},
{"Programming languages of GitHub", 64, LEGAL_UNLIMITED,
@ -1832,9 +1930,9 @@ slide rvslides[] = {
drawthemap();
gmatrix0 = gmatrix;
rogueviz::sag::read("rogueviz/lang/edges.csv");
rogueviz::readcolor("rogueviz/lang/color.csv");
rogueviz::sag::loadsnake("rogueviz/lang/" + cname());
rogueviz::sag::read(RVPATH "lang/edges.csv");
rogueviz::readcolor(RVPATH "lang/color.csv");
rogueviz::sag::loadsnake(RVPATH "lang/" + cname());
if(euclid) rogueviz::legend.clear();
})
},
@ -1853,9 +1951,9 @@ slide rvslides[] = {
drawthemap();
gmatrix0 = gmatrix;
rogueviz::sag::read("rogueviz/boardgames/edges.csv");
rogueviz::readcolor("rogueviz/boardgames/color.csv");
rogueviz::sag::loadsnake("rogueviz/boardgames/" + cname());
rogueviz::sag::read(RVPATH "boardgames/edges.csv");
rogueviz::readcolor(RVPATH "boardgames/color.csv");
rogueviz::sag::loadsnake(RVPATH "boardgames/" + cname());
})
},
{"Tree of Life", 61, LEGAL_UNLIMITED,
@ -1872,7 +1970,7 @@ slide rvslides[] = {
drawthemap();
gmatrix0 = gmatrix;
rogueviz::tree::read("rogueviz/treeoflife/tol.txt");
rogueviz::tree::read(RVPATH "treeoflife/tol.txt");
})},
{"THE END", 99, LEGAL_ANY | FINALSLIDE,
"Press '5' to leave the presentation.",

18
rug.cpp
View File

@ -8,6 +8,7 @@
#define TEXTURESIZE (texturesize)
#define HTEXTURESIZE (texturesize/2)
#ifdef AVOID_GLEW
#ifdef LINUX
extern "C" {
GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
@ -27,6 +28,7 @@ GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers)
#ifdef MAC
#define glFramebufferTexture glFramebufferTextureEXT
#endif
#endif
namespace rug {
@ -389,7 +391,11 @@ void initTexture() {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
#ifdef TEX
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};
glDrawBuffers(1, DrawBuffers);
@ -467,6 +473,11 @@ void closeTexture() {
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() {
GLfloat light_ambient[] = { 3.5, 3.5, 3.5, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
@ -490,7 +501,10 @@ void drawRugScene() {
glMatrixMode(GL_PROJECTION);
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);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -555,7 +569,7 @@ transmatrix rotmatrix(double rotation, int c0, int c1) {
transmatrix currentrot;
void init() {
#ifdef WINDOWS
#ifndef AVOID_GLEW
if(!glew) {
glew = true;
GLenum err = glewInit();

View File

@ -573,9 +573,9 @@ void initConfig() {
char* t = vid.scfg.keyaction;
t['w'] = 16 + 4;
t['s'] = 16 + 5;
t['a'] = 16 + 6;
t['d'] = 16 + 7;
t['d'] = 16 + 5;
t['s'] = 16 + 6;
t['a'] = 16 + 7;
#ifndef MOBILE
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
for(monster *m: active)

View File

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

View File

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

View File

@ -72,7 +72,7 @@ void presentation(presmode mode) {
}
void slidehelp() {
if(texts) {
if(texts && slides[currentslide].help[0]) {
help =
helptitle(XLAT(slides[currentslide].name), 0xFF8000) +
XLAT(slides[currentslide].help);
@ -87,7 +87,10 @@ bool handleKeyTour(int sym, int uni) {
if(!normode) return false;
int flags = slides[currentslide].flags;
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;
presentation(pmStop);
currentslide++;
@ -96,7 +99,10 @@ bool handleKeyTour(int sym, int uni) {
return true;
}
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; }
presentation(pmStop);
currentslide--;
@ -207,6 +213,10 @@ bool handleKeyTour(int sym, int uni) {
conformal::includeHistory = !conformal::includeHistory;
return true;
}
if(sym == '9') {
cmode = emSlideshows;
return true;
}
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() {
ss::list(default_slides);
#ifdef ROGUEVIZ
ss::list(rogueviz::rvtour::rvslides);
#endif
currentslide = 0;
vid.scale = 1;
vid.alpha = 1;
pmodel = mdDisk;
presentation(pmStartAll);
if(!tour::on) presentation(pmStartAll);
else {
presentation(pmStop);
firstland = euclidland = laIce;
}
restartGame('T');
if(tour::on) {
slidehelp();
@ -249,6 +323,7 @@ slide default_slides[] = {
"press ESC to see a "
"menu with other options.",
[] (presmode mode) {
if(mode == pmStartAll) firstland = euclidland = laIce;
if(mode == 1) {
if(tour::texts) addMessage(XLAT("Welcome to the HyperRogue tutorial!"));
else clearMessages();
@ -265,7 +340,6 @@ slide default_slides[] = {
if(mode == 4) {
slides = rogueviz::rvtour::rvslides;
while(tour::on) restartGame('T', false);
firstland = euclidland = laPalace;
tour::start();
}
#endif
@ -637,10 +711,12 @@ slide default_slides[] = {
centerpc(INF);
conformal::includeHistory = false;
}
#ifndef NOSDL
slidecommand = "render spiral";
if(mode == 4) conformal::createImage(true);
if(mode == 11) conformal::create();
if(mode == 13) conformal::clear();
#endif
}
},
{"Conformal square model", 46, LEGAL_HYPERBOLIC,

View File

@ -5,6 +5,8 @@
// Yendor Quest, together with the Yendor Challenge
// also, the Pure Tactics Mode
namespace peace { extern bool on; }
#define MODECODES 254
int hiitemsMax(eItem it) {
@ -151,6 +153,7 @@ namespace yendor {
int yii = NOYENDOR;
int hardness() {
if(peace::on) return 15; // just to generate monsters
int thf = 0;
for(int i=0; i<size(yi); i++) {
yendorinfo& ye ( yi[i] );
@ -522,6 +525,46 @@ namespace yendor {
}
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
@ -795,6 +838,7 @@ int modecode() {
#endif
if(quotient) return 6;
#endif
if(peace::on) return 6;
int xcode = 0;
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);
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;
}
};