1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-06-25 22:53:19 +00:00

unified the land lists

This commit is contained in:
Zeno Rogue 2017-11-03 19:31:42 +01:00
parent 8498ae7af8
commit f38cf14110
10 changed files with 347 additions and 227 deletions

View File

@ -1566,119 +1566,9 @@ const landtype linf[landtypes] = {
{ 0x80FF00, "Crystal World", crystaldesc}
};
#define LAND_OVER 57
#define LAND_OVERX 60
eLand land_over[LAND_OVERX] = {
laIce, laCaves, laDesert, laHunting, laMotion, laJungle, laAlchemist,
laCrossroads,
laMirror, laMinefield, laPalace, laPrincessQuest, laZebra, laReptile,
laOcean, laWarpCoast, laLivefjord, laKraken, laCaribbean, laWhirlpool, laRlyeh, laTemple,
laIvoryTower, laEndorian, laDungeon, laMountain,
laCrossroads2,
laDryForest, laWineyard, laDeadCaves, laGraveyard, laHaunted, laHive,
laRedRock, laVolcano,
laDragon, laTortoise,
laOvergrown, laClearing, laStorms, laRose, laBurial, laWhirlwind,
laBlizzard,
laEmerald, laCamelot,
laPrairie, laBull, laTerracotta,
laElementalWall, laTrollheim,
laHell, laCrossroads3, laCocytus, laPower, laCrossroads4,
laCrossroads5,
// EXTRA
laWildWest, laHalloween, laDual
};
#define LAND_EUC 54
eLand land_euc[LAND_EUC] = {
laIce, laCaves, laDesert, laMotion, laJungle,
laCrossroads,
laMirrorOld, laMinefield, laAlchemist, laZebra, laPalace, laPrincessQuest,
laOcean, laLivefjord, laWarpCoast, laCaribbean, laKraken, laWhirlpool, laRlyeh, laTemple,
laElementalWall, laTrollheim,
laDryForest, laWineyard, laDeadCaves, laGraveyard, laHive, laRedRock, laIvoryTower,
laOvergrown, laClearing, laStorms, laWhirlwind, laRose, laBurial,
laEmerald, laCamelot, laDragon, laTortoise,
laHell, laCrossroads3, laCocytus, laPower,
laCrossroads4,
laWildWest,
laReptile, laMountain, laBull, laPrairie,
laVolcano, laHunting, laBlizzard, laTerracotta,
laDual
};
// MISSING: laCrossroads2
#define LAND_SPH 40
eLand land_sph[LAND_SPH] = {
laHalloween,
laIce, laCaves, laDesert, laMotion, laJungle,
laCrossroads,
laMirrorOld, laMinefield, laAlchemist,
laLivefjord, laWarpCoast, laKraken, laRlyeh,
laTrollheim,
laDryForest, laDeadCaves, laGraveyard, laHive, laRedRock,
laOvergrown, laStorms, laWhirlwind, laRose, laBurial,
laEmerald, laDragon, laTortoise,
laHell, laCrossroads3, laCocytus, laPower, laElementalWall,
laCrossroads4,
laWildWest, laPalace, laBull, laPrairie, laCA,
laDual
};
#define LAND_OCT 36
eLand land_oct[LAND_OCT] = {
laWarpCoast, laIce, laDesert, laCaves, laJungle, laAlchemist,
laGraveyard, laTemple, laHell, laCocytus, laMotion,
laDryForest, laDeadCaves, laRedRock, laMinefield, laLivefjord,
laStorms, laOvergrown, laRose, laKraken, laBurial,
laTrollheim, laBull, laHunting,
laCaribbean, laCamelot, laPalace, laMirrorOld,
laVolcano, laBlizzard, laTerracotta,
laWineyard, laPower, laEmerald, laWhirlpool,
laDual
};
#define LAND_HYP 51
eLand land_hyp[LAND_HYP] = {
laHell, laCocytus, laGraveyard,
laWineyard, laDryForest, laCaves,
laPalace, laEmerald, laHive, laDeadCaves, laPower,
laOcean, laLivefjord, laRlyeh, laTemple, laIce,
laDesert, laRedRock,
laWhirlpool, laOvergrown, laClearing, laStorms,
laCaribbean, laJungle, laAlchemist, laMotion, laMirror, laMinefield,
laZebra, laElementalWall, laIvoryTower, laHaunted, laWhirlwind,
laWarpCoast, laRose, laDragon, laEndorian,
laReptile, laDungeon, laMountain,
laTortoise,
laKraken, laBurial, laTrollheim,
laPrairie, laBull,
laVolcano, laHunting, laBlizzard, laTerracotta,
// always must be last
laCrossroads
};
#define LAND_SCAPE 32
eLand land_scape[LAND_SCAPE] = {
laHell, laCocytus, laGraveyard,
laWineyard, laDryForest, laCaves,
laPalace, laEmerald, laDeadCaves, laPower,
laOcean, laLivefjord, laRlyeh, laTemple, laIce,
laDesert, laRedRock,
laOvergrown, laStorms,
laJungle, laAlchemist, laMotion, laMirror, laMinefield,
laZebra, laWhirlwind, laCrossroads,
laWarpCoast, laRose,
laCrossroads, laCrossroads2, laCrossroads3
};
#define LAND_TAC 56
struct landtacinfo { eLand l; int tries, multiplier; };
landtacinfo land_tac[LAND_TAC] = {
vector<landtacinfo> land_tac = {
{laIce, 10, 1}, {laDesert, 10, 1},
{laHunting, 5, 2},
{laMotion, 10, 1}, {laCaves, 10, 1}, {laAlchemist, 10, 1},
@ -1708,8 +1598,7 @@ landtacinfo land_tac[LAND_TAC] = {
{laWildWest, 10, 1}
};
#define RANDLANDS 17
eLand randlands[RANDLANDS] = {
vector<eLand> randlands = {
laIce, laDesert, laCaves, laAlchemist, laGraveyard, laPower, laLivefjord, laZebra,
laRlyeh, laDryForest, laEmerald, laWineyard, laDeadCaves, laRedRock,
laOvergrown, laWildWest, laWarpCoast

View File

@ -80,7 +80,7 @@ void updatesort() {
void preparesort() {
for(int i=0; i<glyphs; i++) glyphorder[i] = i;
for(int i=0; i<LAND_OVERX; i++) {
for(int i=0; i<size(land_over); i++) {
eLand l = land_over[i];
ikland[treasureType(l)] = i+1;
for(int mi=0; mi<motypes; mi++)

View File

@ -1923,6 +1923,7 @@ int getHemisphere(cell *c, int which);
#define torus (ginf[geometry].quotientstyle & 8)
#define doall (ginf[geometry].quotientstyle)
#define smallbounded (sphere || quotient == 1 || torus)
#define bounded (sphere || quotient || torus)
namespace tactic {
extern bool on;
@ -2101,3 +2102,7 @@ void runGeometryExperiments();
// z to close to this limit => do not draw
#define BEHIND_LIMIT 1e-6
extern vector<eLand> landlist;
template<class T> void generateLandList(T t);
int isLandValid(eLand l);

View File

@ -517,12 +517,14 @@ bool landUnlocked(eLand l) {
void countHyperstoneQuest(int& i1, int& i2) {
i1 = 0; i2 = 0;
for(int t=1; t<ittypes; t++)
if(t != itHyperstone && t != itBounty && t != itTreat &&
itemclass(eItem(t)) == IC_TREASURE) {
i2++; if(items[t] >= R10) i1++;
generateLandList(isLandValid);
for(eLand l: landlist) {
eItem ttype = treasureType(l);
if(ttype != itHyperstone) {
i2++; if(items[ttype] >= R10) i1++;
}
}
}
}
bool hyperstonesUnlocked() {
int i1, i2;
@ -535,7 +537,7 @@ bool hyperstonesUnlocked() {
int isRandland(eLand l) {
if(l == laIce || l == laDesert || l == laCaves || l == laWildWest)
return 2;
for(int i=0; i<RANDLANDS; i++) if(randlands[i] == l) return 1;
for(eLand ll: randlands) if(l == ll) return 1;
return 0;
}
@ -607,7 +609,7 @@ bool lchance(eLand l) {
eLand pickLandRPM(eLand old) {
while(true) {
eLand n = randlands[hrand(RANDLANDS)];
eLand n = randlands[hrand(size(randlands))];
if(incompatible(n, old)) continue;
if(isRandland(n) == 2) return n;
if(hiitemsMax(treasureType(n)) < 10)
@ -902,3 +904,269 @@ eLand getNewLand(eLand old) {
return n;
}
vector<eLand> land_over = {
laIce, laCaves, laDesert, laHunting, laMotion, laJungle, laAlchemist,
laCrossroads,
laMirror, laMinefield, laPalace, laPrincessQuest, laZebra, laReptile,
laOcean, laWarpCoast, laLivefjord, laKraken, laCaribbean, laWhirlpool, laRlyeh, laTemple,
laIvoryTower, laEndorian, laDungeon, laMountain,
laCrossroads2,
laDryForest, laWineyard, laDeadCaves, laGraveyard, laHaunted, laHive,
laRedRock, laVolcano,
laDragon, laTortoise,
laOvergrown, laClearing, laStorms, laRose, laBurial, laWhirlwind,
laBlizzard,
laEmerald, laCamelot,
laPrairie, laBull, laTerracotta,
laElementalWall, laTrollheim,
laHell, laCrossroads3, laCocytus, laPower, laCrossroads4,
laCrossroads5,
// EXTRA
laWildWest, laHalloween, laDual, laCA
};
vector<eLand> landlist;
template<class T> void generateLandList(T t) {
landlist.clear();
for(auto l: land_over) if(t(l)) landlist.push_back(l);
}
eLand getLandForList(cell *c) {
eLand l = c->land;
if(isElemental(l)) return laElementalWall;
if(l == laWarpSea) return laWarpCoast;
if(l == laMercuryRiver) return laTerracotta;
if(l == laBarrier) return laCrossroads;
if(l == laOceanWall) return laOcean;
if(l == laPalace && princess::dist(cwt.c) < OUT_OF_PRISON)
l = laPrincessQuest;
// princess?
return l;
}
// check if the given land should appear in lists
int isLandValid(eLand l) {
// Random Pattern allowed only in some specific lands
if(randomPatternsMode && !isRandland(l))
return 0;
bool stdeuc = geometry == gNormal || geometry == gEuclid;
bool a38 = geometry == gOctagon;
bool a4 = S3 == 4;
bool a45 = geometry == g45;
bool a46 = geometry == g46;
bool a47 = geometry == g47;
bool smallsphere = S7 < 5;
bool bigsphere = S7 == 5;
if(isElemental(l)) {
if(l != laElementalWall)
return 0;
// not good in Field quotient
if(quotient == 2)
return 0;
}
// does not agree with the pattern
if(l == laStorms && quotient == 2)
return 0;
// available only in weird geometries
if(l == laMirrorOld && !geometry)
return 0;
// available only in standard geometry
if(l == laMirror && geometry)
return 0;
// Halloween needs bounded world (can be big bounded)
if(l == laHalloween && !bounded)
return 0;
// these don't appear in normal game, but do appear in special modes
bool normalgame = !geometry && !tactic::on;
if((l == laWildWest || l == laDual) && normalgame)
return 0;
// Crystal World is designed for truncated geometries
if(l == laDual && nontruncated)
return 0;
// standard, non-PTM specific
if(l == laCrossroads5 && tactic::on)
return 0;
// standard non-PTM non-chaos specific
if((l == laCrossroads5 || l == laCrossroads2) && (geometry || chaosmode))
return 0;
// equidistant-based lands -- only in standard geometry
if((l == laDungeon || l == laEndorian) && (geometry || chaosmode))
return 0; //CHECKMORE
// has a special construction in Chaos mode
if(l == laOcean && (!stdeuc && !chaosmode))
return 0;
// equidistant-based lands, but also implemented in Euclidean
if((l == laIvoryTower || l == laMountain) && (!stdeuc || chaosmode))
return 0;
if(l == laPrincessQuest && (!stdeuc || chaosmode || tactic::on))
return 0;
// works correctly only in some geometries
if(l == laClearing)
if(chaosmode || !(stdeuc || a38 || (a45 && !nontruncated) || (a47 && !nontruncated)))
return 0;
// does not work in non-truncated a4
if(l == laOvergrown && a4 && nontruncated)
return 0;
// does not work in bounded either
if(l == laOvergrown && bounded)
return 0;
// horocycle-based lands, not available in bounded geometries nor in Chaos mode
if((l == laWhirlpool || l == laCamelot || l == laCaribbean || l == laTemple) && (bounded || chaosmode))
return 0;
// Temple and Hive has a special Chaos Mode variant, but they are still essentially unbounded
if((l == laTemple || l == laHive) && bounded)
return 0;
// this pattern does not work on elliptic and small spheres
if((l == laBlizzard || l == laVolcano) || elliptic || S7 < 5)
return 0;
// Kraken does not really work in odd non-truncated geometries
// (but we do have to allow it in Standard)
if(l == laKraken && nontruncated && (S7&1) && !geometry)
return 0;
// needs standard/Euclidean (needs vineyard pattern)
if(l == laWineyard && !stdeuc)
return 0;
// works in most spheres, Zebra quotient, and stdeuc
if(l == laWhirlwind)
if(!(stdeuc || quotient == 1 || (sphere && !nontruncated) || (bigsphere && nontruncated && !elliptic)))
return 0;
// needs standard/Euclidean (needs fractal landscape)
if(l == laTortoise && !stdeuc)
return 0;
// technical lands do not count
if(l != laCA && isTechnicalLand(l))
return 0;
// only in bounded geometry, and not in PTM
if(l == laCA && !bounded)
return 0;
if(l == laCA && tactic::on)
return 0;
// Dragon Chasm requires unbounded space [partial]
if(l == laDragon && bounded)
return 0;
// Graveyard pattern does not work on non-truncated weird geometries
if(l == laGraveyard && weirdhyperbolic && nontruncated)
return 0;
// Warped Coast does not work on non-truncated S3s (except standard heptagonal where we have to keep it)
if(l == laWarpCoast && geometry && (S3==3) && nontruncated)
return 0;
// laPower and laEmerald and laPalace -> [partial] in quotients and weirdhyperbolic
if((l == laPower || l == laEmerald || l == laPalace) && !stdeuc && !(bigsphere && !elliptic))
return 1;
if(l == laDragon && geometry)
return 1;
if(l == laTrollheim && quotient == 2)
return 0;
if(l == laTrollheim && geometry)
return 1;
if(l == laReptile && (geometry || nontruncated))
return 1;
if(l == laCrossroads && weirdhyperbolic)
return 0;
if(l == laCrossroads && smallsphere)
return 0;
if(l == laCrossroads3 && !stdeuc && !bigsphere)
return 0;
// OK in small bounded worlds, and in Euclidean
if(l == laCrossroads4 && !(euclid || smallbounded))
return 0;
if(l == laZebra && !(stdeuc || (a4 && nontruncated) || a46 || quotient == 1))
return 0;
if(l == laCrossroads3 && euclid)
return 1; // because it is not accurate
if(l == laPrairie) {
if(stdeuc || (bigsphere && !nontruncated && !elliptic) || (quotient == 2)) ;
else if(!bounded) return 1;
else return 0;
}
if(l == laTerracotta && !stdeuc && !(bigsphere))
return 1;
// highlight Crossroads on Euclidean
if(euclid && (l == laCrossroads || l == laCrossroads4))
return 3;
// highlight Zebra-based lands on Zebra Quotient!
if((l == laZebra || l == laWhirlwind || l == laStorms) && quotient == 1)
return 3;
// highlight FP-based lands on Field Quotient!
if((l == laPrairie || l == laVolcano || l == laBlizzard) && quotient == 2)
return 3;
// these are highlighted whenever allowed
if(l == laHalloween || l == laDual)
return 3;
return 2;
}
/*
int checkLands() {
for(int i=0; i<landtypes; i++) {
eLand l = eLand(i);
char inover = 'N';
for(int i=0; i<LAND_OVERX; i++) if(land_over[i] == l) inover = 'X';
for(int i=0; i<LAND_OVER; i++) if(land_over[i] == l) inover = 'Y';
char ineuc = 'N';
for(int i=0; i<LAND_EUC; i++) if(land_euc[i] == l) ineuc = 'Y';
char insph = 'N';
for(int i=0; i<LAND_SPH; i++) if(land_sph[i] == l) insph = 'Y';
char inoct = 'N';
for(int i=0; i<LAND_OCT; i++) if(land_oct[i] == l) inoct = 'Y';
char intac = 'N';
for(auto ti: land_tac) if(l == ti.l) intac = 'Y';
printf("%c %c %c %c %c %c %c :: %s\n",
isTechnicalLand(l) ? 'T' : 'R',
inover, ineuc, insph, inoct, intac, noChaos(l) ? 'N' : 'Y', linf[i].name);
}
exit(0);
}
auto hookcl = addHook(hooks_args, 100, checkLands); */

BIN
langen Executable file

Binary file not shown.

View File

@ -216,6 +216,7 @@ int main() {
allchars.insert("");
allchars.insert("δ");
allchars.insert("");
allchars.insert("½");
langPL(); langCZ(); langRU();
langTR(); langDE(); langPT();

View File

@ -37,45 +37,41 @@ void showOverview() {
bool pages;
int nl = LAND_OVER, nlm;
eLand *landtab = land_over;
if(randomPatternsMode) { nl = RANDLANDS; landtab = randlands; }
generateLandList(isLandValid);
if(mapeditor::infix != "") {
static eLand filteredLands[landtypes];
int nlid = 0;
for(int i=0; i<nl; i++) {
eLand l = landtab[i];
vector<eLand> filtered;
for(eLand l: landlist) {
string s = dnameof(l);
s += "@";
s += dnameof(treasureType(l));
s += "@";
s += dnameof(nativeOrbType(l));
if(mapeditor::hasInfix(s))
filteredLands[nlid++] = l;
}
if(nlid) {
nl = nlid; landtab = filteredLands;
filtered.push_back(l);
}
if(filtered.size())
landlist = filtered;
}
int nl = size(landlist), nlm;
int lstart = 0;
if(nl > 30) {
pages = true;
landtab += dialog::handlePage(nl, nlm, (nl+1)/2);
lstart += dialog::handlePage(nl, nlm, (nl+1)/2);
}
else nlm = nl;
int vf = min((vid.yres-64-vid.fsize*2) / nlm, vid.xres/40);
eLand curland = cwt.c->land;
if(curland == laPalace && princess::dist(cwt.c) < OUT_OF_PRISON)
curland = laPrincessQuest;
if(isElemental(curland)) curland = laElementalWall;
eLand curland = getLandForList(cwt.c);
getcstat = '0';
for(int i=0; i<nl; i++) {
eLand l = landtab[i];
eLand l = landlist[lstart + i];
int xr = vid.xres / 64;
int i0 = 56 + vid.fsize + i * vf;
int col;
@ -552,46 +548,6 @@ void showChangeMode() {
int eupage = 0;
int euperpage = 21;
// test all the floor patterns!
#ifdef SCALETUNER
#define LAND_SPHEUC 26
eLand land_spheuc[LAND_SPHEUC] = {
laDesert,
laBull,
laPalace,
laWildWest,
laPower,
laStorms,
laHell,
laWhirlwind,
laGraveyard,
laTrollheim,
laBurial,
laVolcano,
laRlyeh,
laTortoise,
laRose,
laCrossroads,
laCaves,
laOvergrown,
laAlchemist,
laJungle,
laMotion,
laIce,
laDragon,
laKraken,
laWarpCoast,
laCaribbean
};
#else
#define LAND_SPHEUC ((weirdhyperbolic) ? LAND_OCT : (geometry > 1) ? LAND_SPH : LAND_EUC)
#define land_spheuc ((weirdhyperbolic) ? land_oct : (geometry > 1) ? land_sph : land_euc)
#endif
const char *curvenames[8] = {
"0", "1", "2", "extremely hyperbolic", "strongly hyperbolic", "strongly hyperbolic", "moderately hyperbolic", "weakly hyperbolic"
};
@ -753,17 +709,22 @@ void showEuclideanMenu() {
dialog::addSelItem(XLAT("geometry"), XLAT(ginf[geometry].name) + XLAT(truncatenames[nontruncated]), '5');
dialog::addBreak(50);
generateLandList(isLandValid);
for(int i=0; i<euperpage; i++) {
if(euperpage * eupage + i >= LAND_SPHEUC) { dialog::addBreak(100); break; }
eLand l = land_spheuc[euperpage * eupage + i];
if(euperpage * eupage + i >= size(landlist)) { dialog::addBreak(100); break; }
eLand l = landlist[euperpage * eupage + i];
char ch;
if(i < 26) ch = 'a' + i;
else ch = 'A' + (i-26);
string validclasses[4] = {"", " (½)", "", " (!)"};
string s = XLAT1(linf[l].name) + validclasses[isLandValid(l)];
if(landvisited[l]) {
dialog::addBoolItem(XLAT1(linf[l].name), l == specialland, ch);
dialog::addBoolItem(s, l == specialland, ch);
}
else {
dialog::addSelItem(XLAT1(linf[l].name), XLAT("(locked)"), ch);
dialog::addSelItem(s, XLAT("(locked)"), ch);
}
}
dialog::addBreak(50);
@ -789,7 +750,7 @@ void showEuclideanMenu() {
ewhichscreen ^= 3;
else if(uni == '-' || uni == PSEUDOKEY_WHEELUP || uni == PSEUDOKEY_WHEELDOWN) {
eupage++;
if(eupage * euperpage >= LAND_SPHEUC) eupage = 0;
if(eupage * euperpage >= size(landlist)) eupage = 0;
}
else if(uni == '1') {
if(chaosUnlocked) {
@ -797,8 +758,8 @@ void showEuclideanMenu() {
pushScreen(showEuclideanMenu);
}
}
else if(lid >= 0 && lid < LAND_SPHEUC) {
eLand nland = land_spheuc[lid];
else if(lid >= 0 && lid < size(landlist)) {
eLand nland = landlist[lid];
if(landvisited[nland]) {
specialland = nland;
restartGame(tactic::on ? 't' : 0);
@ -813,7 +774,7 @@ void showEuclideanMenu() {
}
void runGeometryExperiments() {
specialland = cwt.c->land;
specialland = getLandForList(cwt.c);
pushScreen(showEuclideanMenu);
}

View File

@ -293,6 +293,15 @@ string contstr() {
return XLAT(canmove ? "continue" : "see how it ended");
}
eLand nextHyperstone() {
generateLandList(isLandValid);
for(eLand l: landlist)
if(items[treasureType(l)] < R10 && !isCrossroads(l))
return l;
if(items[itHyperstone] >= 10) return laNone;
return laCrossroads;
}
void showMission() {
cmode = sm::DOTOUR | sm::MISSION | sm::CENTER;
@ -361,17 +370,14 @@ void showMission() {
else if(items[itEmerald] < U5)
dialog::addInfo(XLAT("Collect 5 Emeralds to access Camelot"));
else if(hellUnlocked() && !chaosmode) {
bool b = true;
for(int i=0; i<LAND_HYP; i++)
if(b && items[treasureType(land_hyp[i])] < R10) {
eLand l = nextHyperstone();
if(l)
dialog::addInfo(
XLAT(
land_hyp[i] == laTortoise ? "Hyperstone Quest: collect at least %3 points in %the2" :
l ? "Hyperstone Quest: collect at least %3 points in %the2" :
"Hyperstone Quest: collect at least %3 %1 in %the2",
treasureType(land_hyp[i]), land_hyp[i], its(R10)));
b = false;
}
if(b)
treasureType(l), l, its(R10)));
else
dialog::addInfo(XLAT("Hyperstone Quest completed!"), iinf[itHyperstone].color);
}
else dialog::addInfo(XLAT("Some lands unlock at specific treasures or kills"));

View File

@ -124,18 +124,16 @@ bool handleKeyTour(int sym, int uni) {
}
if(sym == '2') {
bool ok = cwt.c->land == laCanvas;
for(int i=0; i<LAND_EUC; i++) if(land_euc[i] == cwt.c->land) ok = true;
if(!ok) {
dynamicval<eGeometry> g(geometry, gEuclid);
if(cwt.c->land != laCanvas && !isLandValid(cwt.c->land)) {
addMessage(XLAT("This land has no Euclidean version."));
return true;
}
}
if(sym == '1') {
bool ok = cwt.c->land == laCanvas;
for(int i=0; i<LAND_SPH; i++) if(land_sph[i] == cwt.c->land) ok = true;
if(!ok) {
dynamicval<eGeometry> g(geometry, gSphere);
if(cwt.c->land != laCanvas && !isLandValid(cwt.c->land)) {
addMessage(XLAT("This land has no spherical version."));
return true;
}

View File

@ -571,23 +571,22 @@ namespace tactic {
int chances(eLand l) {
if(modecode() != 0 && l != laCamelot) return 3;
for(int i=0; i<LAND_TAC; i++)
if(land_tac[i].l == l) {
return land_tac[i].tries;
}
for(auto& ti: land_tac)
if(ti.l == l)
return ti.tries;
return 0;
}
int tacmultiplier(eLand l) {
if(modecode() != 0 && l != laCamelot) return 1;
if(modecode() != 0 && l == laCamelot) return 3;
for(int i=0; i<LAND_TAC; i++)
if(land_tac[i].l == l) return land_tac[i].multiplier;
for(auto& ti: land_tac)
if(ti.l == l)
return ti.multiplier;
return 0;
}
bool tacticUnlocked(int i) {
eLand l = land_tac[i].l;
bool tacticUnlocked(eLand l) {
if(autocheat) return true;
if(l == laWildWest || l == laDual) return true;
return hiitemsMax(treasureType(l)) * landMultiplier(l) >= 20;
@ -642,23 +641,16 @@ namespace tactic {
uploadScoreCode(4, LB_PURE_TACTICS_COOP);
}
int nl;
eLand getLandById(int i) {
return
sphere ? land_sph[i] :
euclid ? land_euc[i] :
land_tac[i].l;
}
void showMenu() {
cmode = sm::ZOOMABLE;
mouseovers = XLAT("pure tactics mode") + " - " + mouseovers;
nl = LAND_TAC;
if(euclid) nl = LAND_EUC;
if(sphere) nl = LAND_SPH;
{
dynamicval<bool> t(tactic::on, true);
generateLandList(isLandValid);
}
int nl = size(landlist);
int nlm;
int ofs = dialog::handlePage(nl, nlm, nl/2);
@ -675,7 +667,7 @@ namespace tactic {
for(int i=0; i<nl; i++) {
int i1 = i + ofs;
eLand l = getLandById(i1);
eLand l = landlist[i1];
int i0 = 56 + i * vf;
int col;
@ -684,7 +676,7 @@ namespace tactic {
if(!ch) continue;
bool unlocked = tacticUnlocked(i1);
bool unlocked = tacticUnlocked(l);
if(unlocked) col = linf[l].color; else col = 0x202020;
@ -714,8 +706,8 @@ namespace tactic {
uploadScore();
if(on) unrecord(firstland);
if(getcstat >= 1000) {
int ld = land_tac[getcstat-1000].l;
if(getcstat >= 1000 && getcstat < 1000 + size(landlist)) {
int ld = landlist[getcstat-1000];
subscoreboard scorehere;
for(int i=0; i<size(scoreboard[xc]); i++) {
int sc = scoreboard[xc][i].scores[ld];
@ -727,8 +719,8 @@ namespace tactic {
}
keyhandler = [] (int sym, int uni) {
if(uni >= 1000 && uni < 1000 + LAND_TAC) {
firstland = specialland = getLandById(uni - 1000);
if(uni >= 1000 && uni < 1000 + size(landlist)) {
firstland = specialland = landlist[uni - 1000];
restartGame(tactic::on ? 0 : 't');
}
else if(uni == '0') {