mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 01:00:25 +00:00
work in progress for 10.0
This commit is contained in:
parent
13043dc417
commit
22c9217219
@ -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"))
|
||||
|
22
cell.cpp
22
cell.cpp
@ -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 ---
|
||||
|
45
classes.cpp
45
classes.cpp
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
17
dialogs.cpp
17
dialogs.cpp
@ -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";
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
133
game.cpp
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
20
hyper.cpp
20
hyper.cpp
@ -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
64
hyper.h
@ -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;
|
||||
|
8
hyper.rc
8
hyper.rc
@ -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
|
||||
|
||||
|
60
init.cpp
60
init.cpp
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
378
landgen.cpp
378
landgen.cpp
@ -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))
|
||||
|
26
langen.cpp
26
langen.cpp
@ -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");
|
||||
|
@ -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")
|
||||
|
@ -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.",
|
||||
|
@ -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.")
|
||||
*/
|
@ -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", "ввод")
|
||||
|
@ -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ı açı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")
|
||||
|
||||
|
344
mapeditor.cpp
344
mapeditor.cpp
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
103
polygons.cpp
103
polygons.cpp
@ -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);
|
||||
|
170
rogueviz.cpp
170
rogueviz.cpp
@ -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
18
rug.cpp
@ -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();
|
||||
|
10
shmup.cpp
10
shmup.cpp
@ -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)
|
||||
|
@ -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) {
|
||||
|
43
system.cpp
43
system.cpp
@ -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;
|
||||
|
86
tour.cpp
86
tour.cpp
@ -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,
|
||||
|
207
yendor.cpp
207
yendor.cpp
@ -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;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user