1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-24 17:10:36 +00:00

More detailed land validity reporting

This commit is contained in:
Zeno Rogue 2018-04-13 13:08:41 +02:00
parent 3ea4bd91a8
commit 210f9e80c7
7 changed files with 203 additions and 125 deletions

View File

@ -376,8 +376,8 @@ void showEuclideanMenu() {
dialog::addSelItem(XLAT("geometry"), XLAT(ginf[geometry].name) + XLAT(bitruncnames[nonbitrunc]), '5'); dialog::addSelItem(XLAT("geometry"), XLAT(ginf[geometry].name) + XLAT(bitruncnames[nonbitrunc]), '5');
dialog::addBreak(50); dialog::addBreak(50);
generateLandList(isLandValid); generateLandList([] (eLand l) { return land_validity(l).flags & lv::appears_in_geom_exp; });
stable_sort(landlist.begin(), landlist.end(), [] (eLand l1, eLand l2) { return isLandValid(l1) > isLandValid(l2); }); stable_sort(landlist.begin(), landlist.end(), [] (eLand l1, eLand l2) { return land_validity(l1).quality_level > land_validity(l2).quality_level; });
for(int i=0; i<euperpage; i++) { for(int i=0; i<euperpage; i++) {
if(euperpage * eupage + i >= size(landlist)) { dialog::addBreak(100); break; } if(euperpage * eupage + i >= size(landlist)) { dialog::addBreak(100); break; }
@ -396,7 +396,7 @@ void showEuclideanMenu() {
} }
dialog::lastItem().color = linf[l].color; dialog::lastItem().color = linf[l].color;
dialog::lastItem().value += validclasses[isLandValid(l)]; dialog::lastItem().value += validclasses[land_validity(l).quality_level];
} }
dialog::addBreak(50); dialog::addBreak(50);
if(chaosUnlocked && !quotient && !euclid && !sphere) if(chaosUnlocked && !quotient && !euclid && !sphere)

View File

@ -658,6 +658,10 @@ string generateHelpForLand(eLand l) {
"Avoid chopping trees, using Orbs, and non-graveyard monsters in the Haunted Woods." "Avoid chopping trees, using Orbs, and non-graveyard monsters in the Haunted Woods."
); );
} }
auto lv = land_validity(specialland);
if(lv.flags & lv::display_in_help)
s += "\n\n" + XLAT(lv.msg);
#if !ISMOBILE #if !ISMOBILE
if(l == laCA) if(l == laCA)

17
hyper.h
View File

@ -2505,10 +2505,23 @@ void runGeometryExperiments();
#define BEHIND_LIMIT 1e-6 #define BEHIND_LIMIT 1e-6
namespace lv {
static const flagtype appears_in_geom_exp = 1;
static const flagtype display_error_message = 2;
static const flagtype appears_in_full = 4;
static const flagtype appears_in_ptm = 8;
static const flagtype display_in_help = 16;
};
struct land_validity_t {
int quality_level; // 0 (dont show), 1 (1/2), 2 (ok), 3(1!)
flagtype flags;
string msg;
};
extern vector<eLand> landlist; extern vector<eLand> landlist;
template<class T> void generateLandList(T t); template<class T> void generateLandList(T t);
int isLandValid(eLand l); land_validity_t& land_validity(eLand l);
bool isLandValid2(eLand l);
bool isLandIngame(eLand l); bool isLandIngame(eLand l);
bool inmirrororwall(eLand l); bool inmirrororwall(eLand l);

View File

@ -1012,288 +1012,348 @@ eLand getLandForList(cell *c) {
bool isLandIngame(eLand l) { bool isLandIngame(eLand l) {
if(isElemental(l)) l = laElementalWall; if(isElemental(l)) l = laElementalWall;
if(isLandValid(l) < 1) return land_validity(l).flags & lv::appears_in_full;
return false; }
if(l == laWildWest)
return false; namespace lv {
return true;
flagtype q0 = lv::display_error_message | lv::display_in_help;
flagtype q1 = lv::display_error_message | lv::appears_in_geom_exp | lv::appears_in_full | lv::display_in_help;
flagtype q2 = lv::appears_in_geom_exp | lv::appears_in_full | lv::display_in_help;
flagtype q3 = lv::appears_in_geom_exp | lv::appears_in_full | lv::display_in_help;
land_validity_t no_randpattern_version = { 0, q0, "No random pattern version."};
land_validity_t no_great_walls = { 0, q0, "Great Walls not implemented."};
land_validity_t pattern_incompatibility = { 0, q0, "Pattern incompatible."};
land_validity_t pattern_not_implemented_random = { 1, q1, "Pattern not implemented -- using random."};
land_validity_t pattern_not_implemented_weird = { 1, q1, "Pattern not implemented."};
land_validity_t pattern_not_implemented_exclude = { 0, q1 & ~ lv::appears_in_full, "Pattern not implemented -- using random."};
land_validity_t not_enough_space = { 0, q0, "Not enough space."};
land_validity_t dont_work = { 0, q0, "Does not work in this geometry."};
land_validity_t bounded_only = { 0, q0, "This land is designed for bounded worlds."};
land_validity_t unbounded_only = { 0, q0, "This land is designed for infinite worlds."};
land_validity_t unbounded_only_except_bigsphere = { 0, q0, "This land is designed for infinite worlds or big spheres."};
land_validity_t out_of_theme = { 3, q2 &~ lv::appears_in_full, "Out of theme for the full game."};
land_validity_t no_game = { 2, q2 &~ lv::appears_in_full, "No game here."};
land_validity_t not_in_chaos = { 0, q0, "Does not work in chaos mode."};
land_validity_t special_chaos = { 2, q2, "Special construction in the Chaos mode." };
land_validity_t special_euclidean = { 2, q2, "Special construction in the Euclidean mode." };
land_validity_t special_geo = { 2, q2, "Special construction in this geometry." };
land_validity_t special_geo3 = { 2, q2, "Special construction in this geometry." };
land_validity_t not_implemented = {0, q0, "Not implemented."};
land_validity_t partially_implemented = {1, q1, "Partially implemented."};
land_validity_t ok = {2, q2 &~ lv::display_in_help, "No comments."};
land_validity_t not_in_ptm = {0, q0, "Does not work in pure tactics mode."};
land_validity_t technical = {0, q0, "Technical."};
land_validity_t full_game = {3, q3, "Full game."};
land_validity_t inaccurate = {1, q1, "Somewhat inaccurate."};
land_validity_t great_walls_missing = {1, q1, "Mercury rivers missing."};
land_validity_t pattern_compatibility = {3, q3, "Patterns compatible."};
land_validity_t specially_designed = {3, q3, "This land is specially designed for this geometry."};
land_validity_t needs_threecolor = {0, q0, "Three-colorability required."};
land_validity_t land_not_implemented = {0, q0, "Land not implemented."};
land_validity_t interesting = {3, q3, "Special interest."};
land_validity_t better_version_exists = {0, q0, "Better version exists."};
land_validity_t dont_work_but_ingame = {0, q0 | lv::appears_in_full, "Does not work in this geometry."};
land_validity_t ugly_version = {1, q1 | lv::appears_in_full, "Grid does not work in this geometry."};
land_validity_t bad_graphics = {1, q1, "Graphics not implemented in this geometry."};
land_validity_t some0 = {0, q0, "This land does not work in the current settings. Reason not available."};
land_validity_t some1 = {1, q1, "This land does not work well in the current settings. Reason not available."};
land_validity_t known_buggy = {1, q1, "This combination is known to be buggy at the moment."};
land_validity_t sloppy_pattern = {1, q1, "Somewhat sloppy pattern."};
} }
// check if the given land should appear in lists // check if the given land should appear in lists
int isLandValid(eLand l) { land_validity_t& land_validity(eLand l) {
using namespace lv;
// Random Pattern allowed only in some specific lands // Random Pattern allowed only in some specific lands
if(randomPatternsMode && !isRandland(l)) if(randomPatternsMode && !isRandland(l))
return 0; return no_randpattern_version;
if(isElemental(l)) { if(isElemental(l)) {
if(l != laElementalWall) if(l != laElementalWall)
return 0; return technical;
// not good in Field quotient // not good in Field quotient
if(quotient == 2) if(quotient == 2)
return 0; return no_great_walls;
else
return special_geo3;
if(weirdhyperbolic) if(weirdhyperbolic)
return 0; return no_great_walls;
// works nice on a big non-tetrahedron-based sphere // works nice on a big non-tetrahedron-based sphere
if(sphere && S3 != 3 && gp::on) if(sphere && S3 != 3 && gp::on)
return 3; return special_geo3;
} }
// does not agree with the pattern // does not agree with the pattern
if(l == laStorms && quotient == 2) if(l == laStorms && quotient == 2)
return 0; return pattern_incompatibility;
// pattern not implemented // pattern not implemented
if(l == laStorms && S7 == 8) if(l == laStorms && S7 == 8)
return 1; return pattern_not_implemented_random;
// not enough space // not enough space
if(l == laStorms && nonbitrunc && elliptic) if(l == laStorms && nonbitrunc && elliptic)
return 0; return not_enough_space;
if(l == laStorms && nonbitrunc && S3 == 3) if(l == laStorms && nonbitrunc && S3 == 3)
return 0; return not_enough_space;
// mirrors do not work in gp // mirrors do not work in gp
if(among(l, laMirror, laMirrorOld) && gp::on) if(among(l, laMirror, laMirrorOld) && gp::on)
return 0; return dont_work;
// available only in non-standard geometries // available only in non-standard geometries
if(l == laMirrorOld && !geometry) if(l == laMirrorOld && !geometry)
return 0; return better_version_exists;
// available only in standard geometry // available only in standard geometry
if(l == laMirror && geometry) if(l == laMirror && geometry)
return 0; return not_implemented;
// Halloween needs bounded world (can be big bounded) // Halloween needs bounded world (can be big bounded)
if(l == laHalloween && !bounded) if(l == laHalloween && !bounded)
return 0; return bounded_only;
// these don't appear in normal game, but do appear in special modes // these don't appear in normal game, but do appear in special modes
bool normalgame = !geometry && !tactic::on; if(l == laWildWest)
if((l == laWildWest || l == laDual) && normalgame) return out_of_theme;
return 0;
// Crystal World is designed for nice_dual geometries // Crystal World is designed for nice_dual geometries
if(l == laDual && !has_nice_dual()) if(l == laDual && !has_nice_dual())
return 0; return dont_work;
if(l == laHaunted && chaosmode) if(l == laHaunted && chaosmode)
return 0; return not_in_chaos;
// standard, non-PTM specific // standard, non-PTM specific
if(l == laCrossroads5 && tactic::on) if(l == laCrossroads5 && tactic::on)
return 0; return not_in_ptm;
// standard non-PTM non-chaos specific // standard non-PTM non-chaos specific
if((l == laCrossroads5 || l == laCrossroads2) && (geometry || chaosmode)) if((l == laCrossroads5 || l == laCrossroads2) && (geometry || chaosmode))
return 0; return some0;
// equidistant-based lands // equidistant-based lands
if(l == laDungeon || l == laEndorian || l == laIvoryTower || l == laMountain || l == laOcean) { if(l == laDungeon || l == laEndorian || l == laIvoryTower || l == laOcean) {
// special construction // special construction
if(chaosmode && l == laOcean) if(chaosmode && l == laOcean)
return 2; return special_chaos;
// no equidistants supported in chaos mode // no equidistants supported in chaos mode
if(chaosmode) if(chaosmode)
return 0; return not_in_chaos;
// no equidistants supported in these geometries (big sphere is OK though) // no equidistants supported in these geometries (big sphere is OK though)
if(quotient || elliptic || smallsphere || torus) if(quotient || elliptic || smallsphere || torus)
return 0; return unbounded_only_except_bigsphere;
// Yendorian only implemented in standard // Yendorian only implemented in standard
if(l == laEndorian && geometry) if(l == laEndorian && geometry)
return 0; return not_implemented;
// special Euclidean implementations // special Euclidean implementations
if(euclid && (l == laIvoryTower || l == laMountain || l == laOcean)) if(euclid && (l == laIvoryTower || l == laMountain || l == laOcean || l == laMountain))
return 2; return special_geo;
// in other geometries, it works // in other geometries, it works
if(geometry) if(geometry)
return 2; return ok;
} }
// equidistant-based lands, but also implemented in Euclidean if(l == laPrincessQuest && chaosmode)
if((l == laIvoryTower || l == laMountain) && (!stdeuc || chaosmode)) { return not_in_chaos;
if(quotient || euclid || elliptic || smallsphere || chaosmode)
return 0; //CHECKMORE if(l == laPrincessQuest && tactic::on)
if(l == laDungeon) return 1; return not_in_ptm;
return 0;
} if(l == laPrincessQuest && !stdeuc)
return not_implemented;
if(l == laPrincessQuest && (!stdeuc || chaosmode || tactic::on))
return 0;
// works correctly only in some geometries // works correctly only in some geometries
if(l == laClearing && chaosmode)
return not_in_chaos;
if(l == laClearing) if(l == laClearing)
if(chaosmode || !(stdeuc || a38 || (a45 && !nonbitrunc) || (a47 && !nonbitrunc)) || gp::on) if(!(stdeuc || a38 || (a45 && !nonbitrunc) || (a47 && !nonbitrunc)) || gp::on)
return 0; return not_implemented;
// does not work in non-bitrunc a4 // does not work in non-bitrunc a4
if(l == laOvergrown && a4 && nonbitrunc) if(l == laOvergrown && a4 && nonbitrunc)
return 0; return some0;
// does not work in bounded either // does not work in bounded either
if(l == laOvergrown && bounded) if(l == laOvergrown && bounded)
return 0; return some0;
// horocycle-based lands, not available in bounded geometries nor in Chaos mode // horocycle-based lands, not available in bounded geometries nor in Chaos mode
if((l == laWhirlpool || l == laCamelot || l == laCaribbean || l == laTemple) && (bounded || chaosmode)) if(l == laWhirlpool || l == laCamelot || l == laCaribbean || l == laTemple || l == laHive) {
return 0; if(chaosmode) {
if(l == laTemple || l == laHive)
return special_chaos;
return not_in_chaos;
}
if(bounded) return unbounded_only;
}
if(chaosmode && isCrossroads(l)) if(chaosmode && isCrossroads(l))
return 0; return not_in_chaos;
if(gp::on && !horo_ok() && isCyclic(l))
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 // this pattern does not work on elliptic and small spheres
if((l == laBlizzard || l == laVolcano) && elliptic && S7 < 5) if((l == laBlizzard || l == laVolcano) && elliptic && S7 < 5)
return 0; return not_enough_space;
// ... and it works in gp only partially // ... and it works in gp only partially
if((l == laBlizzard || l == laVolcano) && gp::on) if((l == laBlizzard || l == laVolcano) && gp::on)
return 1; return partially_implemented;
// Kraken does not really work on odd-sided cells; // Kraken does not really work on odd-sided cells;
// a nice football pattern will solve the problem by forbidding the Kraken to go there // a nice football pattern will solve the problem by forbidding the Kraken to go there
// (but we do have to allow it in non-bitrunc standard) // (but we do have to allow it in non-bitrunc standard)
if(l == laKraken && (S7&1) && !has_nice_dual()) { if(l == laKraken && (S7&1) && !has_nice_dual()) {
if(!geometry) return 1; return dont_work_but_ingame;
return 0;
} }
// works in most spheres, Zebra quotient, and stdeuc // works in most spheres, Zebra quotient, and stdeuc
if(l == laWhirlwind) { if(l == laWhirlwind) {
if(!(stdeuc || quotient == 1 || (S7 == 4 && !nonbitrunc) || (bigsphere && nonbitrunc && !elliptic))) if(quotient == 1)
return 0; return pattern_compatibility;
if(gp::on) if(stdeuc) ;
return 1; else if(S7 == 4 && !nonbitrunc) return special_geo;
else if(bigsphere && nonbitrunc && !elliptic) return special_geo;
else return dont_work;
} }
// needs standard/Euclidean (needs fractal landscape) // needs standard/Euclidean (needs fractal landscape)
if(l == laTortoise && !stdeuc) if(l == laTortoise && !stdeuc)
return 0; return not_implemented;
// technical lands do not count // technical lands do not count
if(l != laCA && isTechnicalLand(l)) if(l != laCA && isTechnicalLand(l))
return 0; return technical;
// only in bounded geometry, and not in PTM // only in bounded geometry, and not in PTM
if(l == laCA && !bounded) if(l == laCA && !bounded)
return 0; return bounded_only;
if(l == laCA && tactic::on) if(l == laCA && tactic::on)
return 0; return not_in_ptm;
if(l == laCA)
return no_game;
// Dragon Chasm requires unbounded space [partial] // Dragon Chasm requires unbounded space [partial]
if(l == laDragon && bounded) if(l == laDragon && bounded)
return 0; return unbounded_only;
// Graveyard pattern does not work on non-bitrunc weird geometries // Graveyard pattern does not work on non-bitrunc weird geometries
if(l == laGraveyard) if(l == laGraveyard) switch(geosupport_graveyard()) {
return geosupport_graveyard(); case 0:
return dont_work;
case 1:
return sloppy_pattern;
default: ;
}
// Warped Coast does not work on non-bitrunc S3s (except standard heptagonal where we have to keep it) // Warped Coast does not work on non-bitrunc S3s (except standard heptagonal where we have to keep it)
if(l == laWarpCoast && (S3==3) && !has_nice_dual()) { if(l == laWarpCoast && (S3==3) && !has_nice_dual()) {
if(!geometry) return 1; return ugly_version;
return 0;
} }
// laPower and laEmerald and laPalace -> [partial] in quotients and hyperbolic_non37 // laPower and laEmerald and laPalace -> [partial] in quotients and hyperbolic_non37
if((l == laPower || l == laEmerald || l == laPalace) && !euclid && !bigsphere && (quotient || !hyperbolic_37)) if(l == laPower || l == laEmerald || l == laPalace) {
return 1; if(euclid || bigsphere) ;
else if(!hyperbolic_37) return pattern_not_implemented_random;
else if(quotient) return pattern_incompatibility;
}
// ... wineyard pattern is GOOD only in the standard geometry or Euclidean // ... wineyard pattern is GOOD only in the standard geometry or Euclidean
if(l == laWineyard && (gp::on || sphere)) if(l == laWineyard && (gp::on || sphere))
return 1; return pattern_not_implemented_random;
if(l == laDragon && !stdeuc) if(l == laDragon && !stdeuc)
return 1; return not_implemented;
if(l == laTrollheim && quotient == 2) if(l == laTrollheim && quotient == 2)
return 0; return not_enough_space;
if(l == laTrollheim && !stdeuc) if(l == laTrollheim && !stdeuc && !bounded)
return 1; return some1;
if(l == laReptile && (!stdeuc || nonbitrunc)) if(l == laReptile && (!stdeuc || nonbitrunc || gp::on))
return 1; return bad_graphics;
if(l == laCrossroads && weirdhyperbolic)
return 0;
if(l == laCrossroads && smallsphere) if(l == laCrossroads && smallsphere)
return 0; return not_enough_space;
if(l == laCrossroads3 && !stdeuc && !bigsphere) if(l == laCrossroads3 && !stdeuc && !bigsphere)
return 0; return not_enough_space;
if(among(l, laCrossroads, laCrossroads2, laCrossroads3, laCrossroads5) && gp::on && hyperbolic) if(among(l, laCrossroads, laCrossroads2, laCrossroads3, laCrossroads5) && weirdhyperbolic)
return 0; return no_great_walls;
// Crossroads IV is great in weird hyperbolic // Crossroads IV is great in weird hyperbolic
if(l == laCrossroads4 && weirdhyperbolic) if(l == laCrossroads4 && weirdhyperbolic && !quotient)
return 3; return full_game;
// OK in small bounded worlds, and in Euclidean // OK in small bounded worlds, and in Euclidean
if(l == laCrossroads4 && !(stdeuc || smallbounded)) if(l == laCrossroads4 && quotient)
return 0; return some0;
if(l == laZebra && !(stdeuc || (a4 && nonbitrunc) || a46 || quotient == 1)) if(l == laZebra && !(stdeuc || (a4 && nonbitrunc) || a46 || quotient == 1))
return 0; return pattern_not_implemented_weird;
if(l == laCrossroads3 && euclid) if(l == laCrossroads3 && euclid)
return 1; // because it is not accurate return inaccurate; // because it is not accurate
if(l == laPrairie) { if(l == laPrairie) {
if(gp::on) return 0; if(gp::on) return not_implemented;
else if(stdeuc || (bigsphere && !nonbitrunc && !elliptic) || (quotient == 2)) ; else if(stdeuc || (bigsphere && !nonbitrunc && !elliptic) || (quotient == 2)) ;
else if(!bounded) return 1; else if(!bounded) return not_implemented;
else return 0; else return unbounded_only;
} }
if(l == laTerracotta && !stdeuc && !(bigsphere)) if(l == laTerracotta && !stdeuc && !(bigsphere))
return 1; return great_walls_missing;
// highlight Crossroads on Euclidean // highlight Crossroads on Euclidean
if(euclid && !torus && (l == laCrossroads || l == laCrossroads4)) if(euclid && !torus && (l == laCrossroads || l == laCrossroads4))
return 3; return full_game;
// highlight Zebra-based lands on Zebra Quotient! // highlight Zebra-based lands on Zebra Quotient!
if((l == laZebra || l == laWhirlwind || l == laStorms) && quotient == 1) if((l == laZebra || l == laWhirlwind || l == laStorms) && quotient == 1)
return 3; return pattern_compatibility;
// highlight FP-based lands on Field Quotient! // highlight FP-based lands on Field Quotient!
if((l == laPrairie || l == laVolcano || l == laBlizzard) && quotient == 2) if((l == laPrairie || l == laVolcano || l == laBlizzard) && quotient == 2)
return 3; return pattern_compatibility;
// these are highlighted whenever allowed // these are highlighted whenever allowed
if(l == laHalloween || l == laDual) if(l == laHalloween || l == laDual)
return 3; return specially_designed;
if(l == laSnakeNest) if(l == laSnakeNest) {
return geosupport_threecolor() >= 2 ? 3 : 0; if(geosupport_threecolor() < 2)
return needs_threecolor;
else return specially_designed;
}
if(l == laDocks && !randomPatternsMode) { if(l == laDocks && !randomPatternsMode) {
if(a38 && !gp::on) return 3; if(a38 && !gp::on) return specially_designed;
if(a38) return 1; if(a38) return pattern_not_implemented_weird;
return 0; return pattern_not_implemented_exclude;
} }
if(l == laStorms && torus) if(l == laStorms && torus)
return 3; return interesting;
if(l == laMagnetic) if(l == laMagnetic)
return 0; return land_not_implemented;
return 2; if(shmup::on && among(l, laMirror, laMirrorOld) && among(geometry, gElliptic, gQuotient))
return known_buggy;
return ok;
} }
bool isLandValid2(eLand l) { return isLandValid(l) >= 2; }
/* /*
int checkLands() { int checkLands() {
for(int i=0; i<landtypes; i++) { for(int i=0; i<landtypes; i++) {

View File

@ -62,8 +62,9 @@ void welcomeMessage() {
addMessage(XLAT("Welcome to HyperRogue!")); addMessage(XLAT("Welcome to HyperRogue!"));
} }
if(shmup::on && (specialland == laMirror || specialland == laMirrorOld) && (geometry == gElliptic || geometry == gQuotient)) auto lv = land_validity(specialland);
addMessage(XLAT("This combination is known to be buggy at the moment.")); if(lv.flags & lv::display_error_message)
addMessage(XLAT(lv.msg));
#if ISMAC #if ISMAC
addMessage(XLAT("Press F1 or right-shift-click things for help.")); addMessage(XLAT("Press F1 or right-shift-click things for help."));

View File

@ -125,7 +125,7 @@ bool handleKeyTour(int sym, int uni) {
if(sym == '2') { if(sym == '2') {
dynamicval<eGeometry> g(geometry, gEuclid); dynamicval<eGeometry> g(geometry, gEuclid);
if(cwt.c->land != laCanvas && !isLandValid(cwt.c->land)) { if(cwt.c->land != laCanvas && !land_validity(cwt.c->land).quality_level) {
addMessage(XLAT("This land has no Euclidean version.")); addMessage(XLAT("This land has no Euclidean version."));
return true; return true;
} }
@ -133,7 +133,7 @@ bool handleKeyTour(int sym, int uni) {
if(sym == '1') { if(sym == '1') {
dynamicval<eGeometry> g(geometry, gSphere); dynamicval<eGeometry> g(geometry, gSphere);
if(cwt.c->land != laCanvas && !isLandValid(cwt.c->land)) { if(cwt.c->land != laCanvas && !land_validity(cwt.c->land).quality_level) {
addMessage(XLAT("This land has no spherical version.")); addMessage(XLAT("This land has no spherical version."));
return true; return true;
} }

View File

@ -668,7 +668,7 @@ namespace tactic {
{ {
dynamicval<bool> t(tactic::on, true); dynamicval<bool> t(tactic::on, true);
generateLandList(isLandValid2); generateLandList([] (eLand l) { return land_validity(l).flags & lv::appears_in_ptm; });
} }
int nl = size(landlist); int nl = size(landlist);