diff --git a/README.md b/README.md index ceec1f5..a125112 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Cubiomes Viewer provides a graphical interface for the efficient and flexible seed-finding utilities provided by [cubiomes](https://github.com/Cubitect/cubiomes) and a map viewer for the Minecraft biomes and structure generation. -The tool is designed for high performance and is currently limited to overworld features for Minecraft 1.6 - 1.16. +The tool is designed for high performance and is currently supports Minecraft Java Edition 1.6 - 1.17. ## Download diff --git a/cubiomes b/cubiomes index 6fda1ca..bfbd421 160000 --- a/cubiomes +++ b/cubiomes @@ -1 +1 @@ -Subproject commit 6fda1caff80f7e350e0f9bf8e770199d7ea9ccb2 +Subproject commit bfbd421ef5edf9d286dac250723fadbee4bc9265 diff --git a/icons.qrc b/icons.qrc index e864de2..2383d47 100644 --- a/icons.qrc +++ b/icons.qrc @@ -57,5 +57,7 @@ icons/endcity.png icons/bastion_d.png icons/bastion.png + icons/gateway.png + icons/gateway_d.png diff --git a/icons/gateway.png b/icons/gateway.png new file mode 100644 index 0000000..486f081 Binary files /dev/null and b/icons/gateway.png differ diff --git a/icons/gateway_d.png b/icons/gateway_d.png new file mode 100644 index 0000000..c5fed70 Binary files /dev/null and b/icons/gateway_d.png differ diff --git a/src/aboutdialog.h b/src/aboutdialog.h index 30c4ec7..8ea7eb9 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -5,7 +5,7 @@ #define VERS_MAJOR 1 #define VERS_MINOR 8 -#define VERS_PATCH -1 // negative patch number designates a development version +#define VERS_PATCH -2 // negative patch number designates a development version // returns +1 if newer, -1 if older and 0 if equal inline int cmpVers(int major, int minor, int patch) diff --git a/src/cutil.h b/src/cutil.h index d44c454..63ab79f 100644 --- a/src/cutil.h +++ b/src/cutil.h @@ -13,81 +13,40 @@ extern unsigned char biomeColors[256][3]; extern unsigned char tempsColors[256][3]; -inline const char* mc2str(int mc) -{ - switch (mc) - { - case MC_1_6: return "1.6"; break; - case MC_1_7: return "1.7"; break; - case MC_1_8: return "1.8"; break; - case MC_1_9: return "1.9"; break; - case MC_1_10: return "1.10"; break; - case MC_1_11: return "1.11"; break; - case MC_1_12: return "1.12"; break; - case MC_1_13: return "1.13"; break; - case MC_1_14: return "1.14"; break; - case MC_1_15: return "1.15"; break; - case MC_1_16: return "1.16"; break; - default: return NULL; - } -} - -inline int str2mc(const char *s) -{ - if (!strcmp(s, "1.16")) return MC_1_16; - if (!strcmp(s, "1.15")) return MC_1_15; - if (!strcmp(s, "1.14")) return MC_1_14; - if (!strcmp(s, "1.13")) return MC_1_13; - if (!strcmp(s, "1.12")) return MC_1_12; - if (!strcmp(s, "1.11")) return MC_1_11; - if (!strcmp(s, "1.10")) return MC_1_10; - if (!strcmp(s, "1.9")) return MC_1_9; - if (!strcmp(s, "1.8")) return MC_1_8; - if (!strcmp(s, "1.7")) return MC_1_7; - if (!strcmp(s, "1.6")) return MC_1_6; - return -1; -} - inline const char* struct2str(int stype) { switch (stype) { - case Desert_Pyramid: return "Desert_Pyramid"; - case Jungle_Pyramid: return "Jungle_Pyramid"; - case Swamp_Hut: return "Swamp_Hut"; - case Igloo: return "Igloo"; - case Village: return "Village"; - case Ocean_Ruin: return "Ocean_Ruin"; - case Shipwreck: return "Shipwreck"; - case Monument: return "Monument"; - case Mansion: return "Mansion"; - case Outpost: return "Outpost"; - case Ruined_Portal: return "Ruined_Portal"; - case Treasure: return "Treasure"; - case Fortress: return "Fortress"; - case Bastion: return "Bastion"; - case End_City: return "End_City"; + case Desert_Pyramid: return "desert_pyramid"; + case Jungle_Pyramid: return "jungle_pyramid"; + case Swamp_Hut: return "swamp_hut"; + case Igloo: return "igloo"; + case Village: return "village"; + case Ocean_Ruin: return "ocean_ruin"; + case Shipwreck: return "shipwreck"; + case Monument: return "monument"; + case Mansion: return "mansion"; + case Outpost: return "outpost"; + case Ruined_Portal: return "ruined_portal"; + case Ruined_Portal_N: return "ruined_portal (nether)"; + case Treasure: return "treasure"; + case Fortress: return "fortress"; + case Bastion: return "bastion"; + case End_City: return "end_city"; + case End_Gateway: return "end_gateway"; } return "?"; } -inline int structDim(int stype) -{ - if (stype == Fortress || stype == Bastion) - return -1; - if (stype == End_City) - return 1; - return 0; -} // get a random 64-bit integer -static inline int64_t getRnd64() +static inline uint64_t getRnd64() { static QMutex mutex; static std::random_device rd; static std::mt19937_64 mt(rd()); static uint64_t x = (uint64_t) time(0); - int64_t ret = 0; + uint64_t ret = 0; mutex.lock(); if (rd.entropy()) { @@ -102,14 +61,14 @@ static inline int64_t getRnd64() x ^= x >> 32; x *= c; x ^= x >> 32; - ret = (int64_t) x; + ret = x; } mutex.unlock(); return ret; } enum { S_TEXT, S_NUMERIC, S_RANDOM }; -inline int str2seed(const QString &str, int64_t *out) +inline int str2seed(const QString &str, uint64_t *out) { if (str.isEmpty()) { @@ -118,7 +77,7 @@ inline int str2seed(const QString &str, int64_t *out) } bool ok = false; - *out = str.toLongLong(&ok); + *out = (uint64_t) str.toLongLong(&ok); if (ok) { return S_NUMERIC; diff --git a/src/formconditions.cpp b/src/formconditions.cpp index 9e11c86..176ad21 100644 --- a/src/formconditions.cpp +++ b/src/formconditions.cpp @@ -158,7 +158,7 @@ void FormConditions::editCondition(QListWidgetItem *item) { if (!(item->flags() & Qt::ItemIsSelectable)) return; - int mc = MC_1_16; + int mc = MC_NEWEST; parent->getSeed(&mc, 0); FilterDialog *dialog = new FilterDialog(this, mc, item, (Condition*)item->data(Qt::UserRole).data()); QObject::connect(dialog, SIGNAL(setCond(QListWidgetItem*,Condition)), this, SLOT(addItemCondition(QListWidgetItem*,Condition)), Qt::QueuedConnection); diff --git a/src/formgen48.cpp b/src/formgen48.cpp index 9d9de4c..3ea5c4c 100644 --- a/src/formgen48.cpp +++ b/src/formgen48.cpp @@ -57,8 +57,8 @@ bool FormGen48::setList48(QString path, bool quiet) slist48path = path; parent->prevdir = finfo.absolutePath(); - int64_t *l = NULL; - int64_t len; + uint64_t *l = NULL; + uint64_t len; QByteArray ba = path.toLatin1(); l = loadSavedSeeds(ba.data(), &len); if (l && len > 0) @@ -175,7 +175,7 @@ uint64_t FormGen48::estimateSeedCnt() uint64_t w = gen48.x2 - gen48.x1 + 1; uint64_t h = gen48.z2 - gen48.z1 + 1; uint64_t n = w*h * cnt; - if (cnt > 0 && n < PRECOMPUTE48_BUFSIZ*sizeof(int64_t) && n / cnt == w*h) + if (cnt > 0 && n < PRECOMPUTE48_BUFSIZ*sizeof(uint64_t) && n / cnt == w*h) cnt = n; else cnt = MASK48+1; @@ -242,10 +242,20 @@ void FormGen48::updateAutoUi() } if (ui->radioAuto->isChecked()) { - ui->lineEditX1->setText(QString::number(cond.x1)); - ui->lineEditZ1->setText(QString::number(cond.z1)); - ui->lineEditX2->setText(QString::number(cond.x2)); - ui->lineEditZ2->setText(QString::number(cond.z2)); + if (ui->tabWidget->currentIndex() == GEN48_LIST) + { + ui->lineEditX1->setText("0"); + ui->lineEditZ1->setText("0"); + ui->lineEditX2->setText("0"); + ui->lineEditZ2->setText("0"); + } + else + { + ui->lineEditX1->setText(QString::number(cond.x1)); + ui->lineEditZ1->setText(QString::number(cond.z1)); + ui->lineEditX2->setText(QString::number(cond.x2)); + ui->lineEditZ2->setText(QString::number(cond.z2)); + } } } emit changed(); @@ -272,7 +282,7 @@ void FormGen48::updateMode() { int mode = ui->tabWidget->currentIndex(); - if (mode == GEN48_AUTO) + //if (mode == GEN48_AUTO) { updateAutoUi(); } diff --git a/src/formgen48.h b/src/formgen48.h index 60b1df0..b1dbd98 100644 --- a/src/formgen48.h +++ b/src/formgen48.h @@ -25,7 +25,7 @@ public: Gen48Settings getSettings(bool resolveauto = false); bool setList48(QString path, bool quiet); - const std::vector& getList48() { return slist48; } + const std::vector& getList48() { return slist48; } uint64_t estimateSeedCnt(); void updateCount(); @@ -57,7 +57,7 @@ private: Condition cond; QString slist48path; - std::vector slist48; + std::vector slist48; }; #endif // FORMGEN48_H diff --git a/src/formsearchcontrol.cpp b/src/formsearchcontrol.cpp index 1cc4eae..ba269ba 100644 --- a/src/formsearchcontrol.cpp +++ b/src/formsearchcontrol.cpp @@ -20,6 +20,8 @@ FormSearchControl::FormSearchControl(MainWindow *parent) , stimer() , slist64path() , slist64() + , smin(0) + , smax(~(uint64_t)0) { ui->setupUi(this); @@ -51,13 +53,13 @@ FormSearchControl::~FormSearchControl() delete ui; } -QVector FormSearchControl::getResults() +QVector FormSearchControl::getResults() { int n = ui->listResults->rowCount(); - QVector results = QVector(n); + QVector results = QVector(n); for (int i = 0; i < n; i++) { - results[i] = ui->listResults->item(i, 0)->data(Qt::UserRole).toLongLong(); + results[i] = ui->listResults->item(i, 0)->data(Qt::UserRole).toULongLong(); } return results; } @@ -65,24 +67,26 @@ QVector FormSearchControl::getResults() SearchConfig FormSearchControl::getSearchConfig() { SearchConfig s; - s.searchmode = ui->comboSearchType->currentIndex(); + s.searchtype = ui->comboSearchType->currentIndex(); s.threads = ui->spinThreads->value(); s.slist64path = slist64path; s.startseed = ui->lineStart->text().toLongLong(); s.stoponres = ui->checkStop->isChecked(); + s.smin = smin; + s.smax = smax; return s; } bool FormSearchControl::setSearchConfig(SearchConfig s, bool quiet) { bool ok = true; - if (s.searchmode >= SEARCH_INC && s.searchmode <= SEARCH_LIST) - ui->comboSearchType->setCurrentIndex(s.searchmode); + if (s.searchtype >= SEARCH_INC && s.searchtype <= SEARCH_LIST) + ui->comboSearchType->setCurrentIndex(s.searchtype); else ok = false; ui->spinThreads->setValue(s.threads); - ui->lineStart->setText(QString::asprintf("%" PRId64, s.startseed)); + ui->lineStart->setText(QString::asprintf("%" PRId64, (int64_t)s.startseed)); ui->checkStop->setChecked(s.stoponres); return ok && setList64(s.slist64path, quiet); @@ -100,8 +104,8 @@ bool FormSearchControl::setList64(QString path, bool quiet) QFileInfo finfo(path); parent->prevdir = finfo.absolutePath(); slist64path = finfo.fileName(); - int64_t *l = NULL; - int64_t len; + uint64_t *l = NULL; + uint64_t len; QByteArray ba = path.toLatin1(); l = loadSavedSeeds(ba.data(), &len); if (l && len > 0) @@ -165,21 +169,22 @@ void FormSearchControl::on_buttonStart_clicked() { if (ui->buttonStart->isChecked()) { - int mc = MC_1_16; + int mc = MC_NEWEST; parent->getSeed(&mc, NULL); const Config& config = parent->config; const QVector& condvec = parent->formCond->getConditions(); - int64_t sstart = (int64_t) ui->lineStart->text().toLongLong(); - int searchtype = ui->comboSearchType->currentIndex(); - int threads = ui->spinThreads->value(); + SearchConfig sc = getSearchConfig(); int ok = true; + sc.smin = 1L << 47; + sc.smax = 2L << 48; + if (condvec.empty()) { QMessageBox::warning(this, "Warning", "Please define some constraints using the \"Add\" button.", QMessageBox::Ok); ok = false; } - if (searchtype == SEARCH_LIST && slist64.empty()) + if (sc.searchtype == SEARCH_LIST && slist64.empty()) { QMessageBox::warning(this, "Warning", "No seed list file selected.", QMessageBox::Ok); ok = false; @@ -194,19 +199,19 @@ void FormSearchControl::on_buttonStart_clicked() { Gen48Settings gen48 = parent->formGen48->getSettings(true); // the search can either use a full list or a 48-bit list - if (searchtype == SEARCH_LIST) + if (sc.searchtype == SEARCH_LIST) slist = slist64; else if (gen48.mode == GEN48_LIST) slist = parent->formGen48->getList48(); else slist.clear(); - ok = sthread.set(parent, searchtype, threads, gen48, slist, sstart, mc, condvec, config.seedsPerItem, config.queueSize); + ok = sthread.set(parent, mc, sc, gen48, config, slist, condvec); } if (ok) { - ui->lineStart->setText(QString::asprintf("%" PRId64, sstart)); + ui->lineStart->setText(QString::asprintf("%" PRId64, (int64_t)sc.startseed)); ui->buttonStart->setText("Abort search"); ui->buttonStart->setIcon(QIcon(":/icons/cancel.png")); sthread.start(); @@ -244,7 +249,7 @@ void FormSearchControl::on_listResults_itemSelectionChanged() int row = ui->listResults->currentRow(); if (row >= 0 && row < ui->listResults->rowCount()) { - int64_t s = ui->listResults->item(row, 0)->data(Qt::UserRole).toLongLong(); + uint64_t s = ui->listResults->item(row, 0)->data(Qt::UserRole).toULongLong(); emit selectedSeedChanged(s); } } @@ -303,7 +308,7 @@ int FormSearchControl::pasteList(bool dummy) { QClipboard *clipboard = QGuiApplication::clipboard(); QStringList slist = clipboard->text().split('\n'); - QVector seeds; + QVector seeds; for (QString s : slist) { @@ -311,7 +316,7 @@ int FormSearchControl::pasteList(bool dummy) if (s.isEmpty()) continue; bool ok = true; - int64_t seed = s.toLongLong(&ok); + uint64_t seed = (uint64_t) s.toLongLong(&ok); if (!ok) return 0; seeds.push_back(seed); @@ -325,7 +330,7 @@ int FormSearchControl::pasteList(bool dummy) } -int FormSearchControl::searchResultsAdd(QVector seeds, bool countonly) +int FormSearchControl::searchResultsAdd(QVector seeds, bool countonly) { const Config& config = parent->config; int ns = ui->listResults->rowCount(); @@ -337,16 +342,16 @@ int FormSearchControl::searchResultsAdd(QVector seeds, bool countonly) if (seeds.empty()) return 0; - QSet current; + QSet current; current.reserve(n + seeds.size()); for (int i = 0; i < n; i++) { - int64_t seed = ui->listResults->item(i, 0)->data(Qt::UserRole).toLongLong(); + uint64_t seed = ui->listResults->item(i, 0)->data(Qt::UserRole).toULongLong(); current.insert(seed); } ui->listResults->setSortingEnabled(false); - for (int64_t s : seeds) + for (uint64_t s : seeds) { if (current.contains(s)) continue; @@ -361,7 +366,7 @@ int FormSearchControl::searchResultsAdd(QVector seeds, bool countonly) s48item->setData(Qt::UserRole, QVariant::fromValue(s)); s48item->setText(QString::asprintf("%012llx|%04x", (qulonglong)(s & MASK48), (uint)(s >> 48) & 0xffff)); - seeditem->setData(Qt::DisplayRole, QVariant::fromValue(s)); + seeditem->setData(Qt::DisplayRole, QVariant::fromValue((int64_t)s)); ui->listResults->insertRow(n); ui->listResults->setItem(n, 0, s48item); ui->listResults->setItem(n, 1, seeditem); @@ -455,7 +460,7 @@ void FormSearchControl::copyResults() int n = ui->listResults->rowCount(); for (int i = 0; i < n; i++) { - int64_t seed = ui->listResults->item(i, 0)->data(Qt::UserRole).toLongLong(); + uint64_t seed = ui->listResults->item(i, 0)->data(Qt::UserRole).toULongLong(); text += QString::asprintf("%" PRId64 "\n", seed); } diff --git a/src/formsearchcontrol.h b/src/formsearchcontrol.h index 0adf8e8..fc3c80a 100644 --- a/src/formsearchcontrol.h +++ b/src/formsearchcontrol.h @@ -23,7 +23,7 @@ public: explicit FormSearchControl(MainWindow *parent); ~FormSearchControl(); - QVector getResults(); + QVector getResults(); SearchConfig getSearchConfig(); bool setSearchConfig(SearchConfig s, bool quiet); @@ -35,7 +35,7 @@ public: void setSearchMode(int mode); signals: - void selectedSeedChanged(int64_t seed); + void selectedSeedChanged(uint64_t seed); void searchStatusChanged(bool running); void resultsAdded(int cnt); @@ -53,7 +53,7 @@ public slots: void pasteResults(); int pasteList(bool dummy); - int searchResultsAdd(QVector seeds, bool countonly); + int searchResultsAdd(QVector seeds, bool countonly); void searchProgressReset(); void searchProgress(uint64_t last, uint64_t end, int64_t seed); void searchFinish(); @@ -69,10 +69,13 @@ private: // the seed list option is not stored in a widget but is loaded with the "..." button QString slist64path; - std::vector slist64; + std::vector slist64; // buffer for seed candidates while search is running - std::vector slist; + std::vector slist; + + // min and max seeds values + uint64_t smin, smax; }; #endif // FORMSEARCHCONTROL_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6f1669b..34d28ae 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -149,6 +149,7 @@ MainWindow::MainWindow(QWidget *parent) addMapAction(D_BASTION, "bastion", "Show bastions"); ui->toolBar->addSeparator(); addMapAction(D_ENDCITY, "endcity", "Show end cities"); + addMapAction(D_GATEWAY, "gateway", "Show end gateways"); saction[D_GRID]->setChecked(true); @@ -159,7 +160,7 @@ MainWindow::MainWindow(QWidget *parent) qRegisterMetaType< int64_t >("int64_t"); qRegisterMetaType< uint64_t >("uint64_t"); - qRegisterMetaType< QVector >("QVector"); + qRegisterMetaType< QVector >("QVector"); qRegisterMetaType< Config >("Config"); QIntValidator *intval = new QIntValidator(this); @@ -183,7 +184,7 @@ MainWindow::~MainWindow() delete ui; } -QAction *MainWindow::addMapAction(int stype, const char *iconpath, const char *tip) +QAction *MainWindow::addMapAction(int sopt, const char *iconpath, const char *tip) { QIcon icon; QString inam = QString(":icons/") + iconpath; @@ -192,10 +193,10 @@ QAction *MainWindow::addMapAction(int stype, const char *iconpath, const char *t QAction *action = new QAction(icon, tip, this); action->setCheckable(true); ui->toolBar->addAction(action); - if (stype >= 0) + if (sopt >= 0) { - action->connect(action, &QAction::toggled, [=](bool state){ this->onActionMapToggled(stype, state); }); - saction[stype] = action; + action->connect(action, &QAction::toggled, [=](bool state){ this->onActionMapToggled(sopt, state); }); + saction[sopt] = action; } return action; } @@ -206,7 +207,7 @@ MapView* MainWindow::getMapView() return ui->mapView; } -bool MainWindow::getSeed(int *mc, int64_t *seed, bool applyrand) +bool MainWindow::getSeed(int *mc, uint64_t *seed, bool applyrand) { bool ok = true; if (mc) @@ -215,7 +216,7 @@ bool MainWindow::getSeed(int *mc, int64_t *seed, bool applyrand) *mc = str2mc(mcs.c_str()); if (*mc < 0) { - *mc = MC_1_16; + *mc = MC_NEWEST; qDebug() << "Unknown MC version: " << *mc; ok = false; } @@ -225,13 +226,13 @@ bool MainWindow::getSeed(int *mc, int64_t *seed, bool applyrand) { int v = str2seed(ui->seedEdit->text(), seed); if (applyrand && v == S_RANDOM) - ui->seedEdit->setText(QString::asprintf("%" PRId64, *seed)); + ui->seedEdit->setText(QString::asprintf("%" PRId64, (int64_t)*seed)); } return ok; } -bool MainWindow::setSeed(int mc, int64_t seed, int dim) +bool MainWindow::setSeed(int mc, uint64_t seed, int dim) { const char *mcstr = mc2str(mc); if (!mcstr) @@ -244,7 +245,7 @@ bool MainWindow::setSeed(int mc, int64_t seed, int dim) dim = getDim(); ui->comboBoxMC->setCurrentText(mcstr); - ui->seedEdit->setText(QString::asprintf("%" PRId64, seed)); + ui->seedEdit->setText(QString::asprintf("%" PRId64, (int64_t)seed)); ui->mapView->setSeed(mc, seed, dim); return true; } @@ -273,8 +274,8 @@ void MainWindow::saveSettings() settings.setValue("config/queueSize", config.queueSize); settings.setValue("config/maxMatching", config.maxMatching); - int mc = MC_1_16; - int64_t seed = 0; + int mc = MC_NEWEST; + uint64_t seed = 0; getSeed(&mc, &seed, false); settings.setValue("map/mc", mc); settings.setValue("map/seed", (qlonglong)seed); @@ -319,11 +320,11 @@ void MainWindow::loadSettings() else dimactions[0]->setChecked(true); - int mc = MC_1_16; - int64_t seed = 0; + int mc = MC_NEWEST; + uint64_t seed = 0; getSeed(&mc, &seed, true); mc = settings.value("map/mc", mc).toInt(); - seed = settings.value("map/seed", QVariant::fromValue(seed)).toLongLong(); + seed = (uint64_t) settings.value("map/seed", QVariant::fromValue((qlonglong)seed)).toLongLong(); setSeed(mc, seed); qreal x = ui->mapView->getX(); @@ -334,13 +335,14 @@ void MainWindow::loadSettings() z = settings.value("map/z", z).toDouble(); scale = settings.value("map/scale", scale).toDouble(); - for (int stype = 0; stype < STRUCT_NUM; stype++) + for (int sopt = 0; sopt < STRUCT_NUM; sopt++) { - bool show = ui->mapView->getShow(stype); - QString sopt = QString("map/show_") + mapopt2str(stype); - show = settings.value(sopt, show).toBool(); - saction[stype]->setChecked(show); - ui->mapView->setShow(stype, show); + bool show = ui->mapView->getShow(sopt); + QString soptstr = QString("map/show_") + mapopt2str(sopt); + show = settings.value(soptstr, show).toBool(); + if (saction[sopt]) + saction[sopt]->setChecked(show); + ui->mapView->setShow(sopt, show); } mapGoto(x, z, scale); @@ -375,9 +377,9 @@ bool MainWindow::saveProgress(QString fnam, bool quiet) SearchConfig searchconf = formControl->getSearchConfig(); Gen48Settings gen48 = formGen48->getSettings(false); QVector condvec = formCond->getConditions(); - QVector results = formControl->getResults(); + QVector results = formControl->getResults(); - int mc = MC_1_16; + int mc = MC_NEWEST; getSeed(&mc, 0); QTextStream stream(&file); @@ -386,7 +388,7 @@ bool MainWindow::saveProgress(QString fnam, bool quiet) // MC version of the session should take priority over the one in the settings stream << "#MC: " << mc2str(mc) << "\n"; - stream << "#Search: " << searchconf.searchmode << "\n"; + stream << "#Search: " << searchconf.searchtype << "\n"; if (!searchconf.slist64path.isEmpty()) stream << "#List64: " << searchconf.slist64path.replace("\n", "") << "\n"; stream << "#Progress: " << searchconf.startseed << "\n"; @@ -413,8 +415,8 @@ bool MainWindow::saveProgress(QString fnam, bool quiet) for (Condition &c : condvec) stream << "#Cond: " << QByteArray((const char*) &c, sizeof(Condition)).toHex() << "\n"; - for (int64_t s : results) - stream << QString::asprintf("%" PRId64 "\n", s); + for (uint64_t s : results) + stream << QString::asprintf("%" PRId64 "\n", (int64_t)s); return true; } @@ -434,12 +436,12 @@ bool MainWindow::loadProgress(QString fnam, bool quiet) SearchConfig searchconf = formControl->getSearchConfig(); Gen48Settings gen48 = formGen48->getSettings(false); QVector condvec; - QVector seeds; + QVector seeds; char buf[4096]; int tmp; - int mc = MC_1_16; - int64_t seed; + int mc = MC_NEWEST; + uint64_t seed; getSeed(&mc, &seed, true); QTextStream stream(&file); @@ -462,7 +464,7 @@ bool MainWindow::loadProgress(QString fnam, bool quiet) if (line.startsWith("#Time:")) continue; else if (sscanf(p, "#MC: %8[^\n]", buf) == 1) { mc = str2mc(buf); if (mc < 0) return false; } // SearchConfig - else if (sscanf(p, "#Search: %d", &searchconf.searchmode) == 1) {} + else if (sscanf(p, "#Search: %d", &searchconf.searchtype) == 1) {} else if (sscanf(p, "#Progress: %" PRId64, &searchconf.startseed) == 1) {} else if (sscanf(p, "#Threads: %d", &searchconf.threads) == 1) {} else if (sscanf(p, "#ResStop: %d", &tmp) == 1) { searchconf.stoponres = tmp; } @@ -492,8 +494,8 @@ bool MainWindow::loadProgress(QString fnam, bool quiet) } else { - int64_t s; - if (sscanf(line.toLatin1().data(), "%" PRId64, &s) == 1) + uint64_t s; + if (sscanf(line.toLatin1().data(), "%" PRId64, (int64_t*)&s) == 1) seeds.push_back(s); else return false; } @@ -521,7 +523,7 @@ bool MainWindow::loadProgress(QString fnam, bool quiet) void MainWindow::updateMapSeed() { int mc; - int64_t seed; + uint64_t seed; if (getSeed(&mc, &seed)) setSeed(mc, seed); } @@ -563,7 +565,7 @@ void MainWindow::on_seedEdit_editingFinished() void MainWindow::on_seedEdit_textChanged(const QString &a) { - int64_t s; + uint64_t s; int v = str2seed(a, &s); switch (v) { @@ -645,7 +647,7 @@ void MainWindow::on_actionScan_seed_for_Quad_Huts_triggered() void MainWindow::on_actionOpen_shadow_seed_triggered() { int mc; - int64_t seed; + uint64_t seed; if (getSeed(&mc, &seed)) { setSeed(mc, getShadow(seed)); @@ -670,10 +672,10 @@ void MainWindow::on_actionPaste_triggered() void MainWindow::on_actionAddShadow_triggered() { - QVector results = formControl->getResults(); - QVector shadows; + QVector results = formControl->getResults(); + QVector shadows; shadows.reserve(results.size()); - for (int64_t s : results) + for (uint64_t s : results) shadows.push_back( getShadow(s) ); formControl->searchResultsAdd(shadows, false); } @@ -745,7 +747,7 @@ void MainWindow::on_buttonAnalysis_clicked() warning("Warning", "Invalid area for analysis"); return; } - if ((int64_t)(x2 - x1) * (int64_t)(z2 - z1) > 100000000LL) + if ((uint64_t)(x2 - x1) * (uint64_t)(z2 - z1) > 100000000LL) { QString msg = QString::asprintf( "Area for analysis is very large (%d, %d).\n" @@ -759,7 +761,7 @@ void MainWindow::on_buttonAnalysis_clicked() bool everything = ui->radioEverything->isChecked(); int mc; - int64_t seed; + uint64_t seed; if (!getSeed(&mc, &seed)) return; @@ -833,21 +835,29 @@ void MainWindow::on_buttonAnalysis_clicked() item->setData(1, Qt::DisplayRole, QVariant::fromValue(cnt)); } - tree->insertTopLevelItem(0, item_cat); + //tree->insertTopLevelItem(0, item_cat); std::vector st; for (int sopt = D_DESERT; sopt < D_SPAWN; sopt++) { - if (!everything && !getMapView()->getShow(sopt)) - continue; + int sdim = 0; + if (sopt == D_FORTESS || sopt == D_BASTION || sopt == D_PORTALN) + sdim = -1; + if (sopt == D_ENDCITY || sopt == D_GATEWAY) + sdim = 1; + if (!everything) + { + if (!getMapView()->getShow(sopt)) + continue; + if (sdim != dim) + continue; + } int stype = mapopt2stype(sopt); - if (dim != structDim(stype)) - continue; st.clear(); StructureConfig sconf; if (!getStructureConfig_override(stype, mc, &sconf)) continue; - getStructs(&st, sconf, mc, seed, x1, z1, x2, z2); + getStructs(&st, sconf, mc, sdim, seed, x1, z1, x2, z2); if (st.empty()) continue; @@ -868,7 +878,7 @@ void MainWindow::on_buttonAnalysis_clicked() item->setText(1, "Abandoned"); } } - tree->insertTopLevelItem(stype, item_cat); + //tree->insertTopLevelItem(stype, item_cat); } if (everything || (dim == 0 && getMapView()->getShow(D_SPAWN))) @@ -976,9 +986,11 @@ void MainWindow::onAutosaveTimeout() } } -void MainWindow::onActionMapToggled(int stype, bool show) +void MainWindow::onActionMapToggled(int sopt, bool show) { - ui->mapView->setShow(stype, show); + if (sopt == D_PORTAL) // overworld porals should also control nether + ui->mapView->setShow(D_PORTALN, show); + ui->mapView->setShow(sopt, show); } void MainWindow::onConditionsChanged() @@ -993,9 +1005,9 @@ void MainWindow::onGen48Changed() formControl->searchProgressReset(); } -void MainWindow::onSelectedSeedChanged(int64_t seed) +void MainWindow::onSelectedSeedChanged(uint64_t seed) { - ui->seedEdit->setText(QString::asprintf("%" PRId64, seed)); + ui->seedEdit->setText(QString::asprintf("%" PRId64, (int64_t)seed)); on_seedEdit_editingFinished(); } diff --git a/src/mainwindow.h b/src/mainwindow.h index c5efabb..373aa02 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -43,10 +43,10 @@ public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); - QAction *addMapAction(int stype, const char *iconpath, const char *tip); + QAction *addMapAction(int sopt, const char *iconpath, const char *tip); - bool getSeed(int *mc, int64_t *seed, bool applyrand = true); - bool setSeed(int mc, int64_t seed, int dim = INT_MAX); + bool getSeed(int *mc, uint64_t *seed, bool applyrand = true); + bool setSeed(int mc, uint64_t seed, int dim = INT_MAX); int getDim(); MapView *getMapView(); @@ -95,10 +95,10 @@ private slots: // internal events void onAutosaveTimeout(); - void onActionMapToggled(int stype, bool a); + void onActionMapToggled(int sopt, bool a); void onConditionsChanged(); void onGen48Changed(); - void onSelectedSeedChanged(int64_t seed); + void onSelectedSeedChanged(uint64_t seed); void onSearchStatusChanged(bool running); void onStyleChanged(int style); void copyCoord(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 6a7ae15..821f6f3 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -26,16 +26,7 @@ - - 0 - - - 0 - - - 0 - - + 0 @@ -88,6 +79,11 @@ Minecraft version + + + 1.17 + + 1.16 @@ -163,16 +159,7 @@ Search - - 0 - - - 0 - - - 0 - - + 0 @@ -218,8 +205,8 @@ QToolButton { 0 0 - 1232 - 699 + 1233 + 705 @@ -518,16 +505,7 @@ QSplitter { QFrame::Raised - - 0 - - - 0 - - - 0 - - + 0 @@ -594,7 +572,7 @@ QToolButton:checked { 0 0 1280 - 22 + 23 diff --git a/src/mapview.cpp b/src/mapview.cpp index b091a11..cacd1c9 100644 --- a/src/mapview.cpp +++ b/src/mapview.cpp @@ -72,7 +72,7 @@ MapView::~MapView() delete overlay; } -void MapView::setSeed(int mc, int64_t s, int dim) +void MapView::setSeed(int mc, uint64_t s, int dim) { prevx = focusx = getX(); prevz = focusz = getZ(); @@ -185,8 +185,8 @@ void MapView::paintEvent(QPaintEvent *) world->draw(painter, width(), height(), fx, fz, blocks2pix); QPoint cur = mapFromGlobal(QCursor::pos()); - qreal bx = (cur.x() - width()/2) / blocks2pix + fx; - qreal bz = (cur.y() - height()/2) / blocks2pix + fz; + qreal bx = (cur.x() - width()/2.0) / blocks2pix + fx; + qreal bz = (cur.y() - height()/2.0) / blocks2pix + fz; Pos p = {(int)bx, (int)bz}; overlay->pos = p; overlay->id = world->getBiome(p); diff --git a/src/mapview.h b/src/mapview.h index 5d8ccbf..d629992 100644 --- a/src/mapview.h +++ b/src/mapview.h @@ -36,7 +36,7 @@ public: qreal getZ(); qreal getScale() const { return 1.0 / blocks2pix; } - void setSeed(int mc, int64_t s, int dim); + void setSeed(int mc, uint64_t s, int dim); void setView(qreal x, qreal z, qreal scale = 0); bool getShow(int stype) { return stype >= 0 && stype < STRUCT_NUM ? sshow[stype] : false; } diff --git a/src/quad.cpp b/src/quad.cpp index 8185461..9245a88 100644 --- a/src/quad.cpp +++ b/src/quad.cpp @@ -28,7 +28,7 @@ Quad::~Quad() } void getStructs(std::vector *out, const StructureConfig sconf, - int mc, int64_t seed, int x0, int z0, int x1, int z1) + int mc, int dim, uint64_t seed, int x0, int z0, int x1, int z1) { union { LayerStack g; @@ -36,14 +36,8 @@ void getStructs(std::vector *out, const StructureConfig sconf, EndNoise en; } u; - int dim; - if (sconf.structType == Fortress || sconf.structType == Bastion) - dim = -1; - else if (sconf.structType == End_City) - dim = +1; - else + if (dim == 0) { - dim = 0; setupGenerator(&u.g, mc); } @@ -74,7 +68,7 @@ void getStructs(std::vector *out, const StructureConfig sconf, else if (dim == +1) { id = isViableEndStructurePos(sconf.structType, mc, &u.en, seed, p.x, p.z); - if (id) + if (id && sconf.structType == End_City) { SurfaceNoise sn; initSurfaceNoiseEnd(&sn, seed); @@ -139,7 +133,7 @@ void Quad::run() std::vector* st = new std::vector(); StructureConfig sconf; if (getStructureConfig_override(structureType, mc, &sconf)) - getStructs(st, sconf, mc, seed, x0, z0, x1, z1); + getStructs(st, sconf, mc, dim, seed, x0, z0, x1, z1); spos = st; } } @@ -215,9 +209,9 @@ int mapOceanMixMod(const Layer * l, int * out, int x, int z, int w, int h) return 0; } -void Level::init4map(int mcversion, int64_t ws, int dim, int pix, int layerscale) +void Level::init4map(int mc, uint64_t ws, int dim, int pix, int layerscale) { - this->mc = mcversion; + this->mc = mc; this->seed = ws; this->dim = dim; @@ -270,7 +264,7 @@ void Level::init4map(int mcversion, int64_t ws, int dim, int pix, int layerscale } } -void Level::init4struct(int mc, int64_t ws, int dim, int blocks, int sopt, int lv) +void Level::init4struct(int mc, uint64_t ws, int dim, int blocks, int sopt, int lv) { this->mc = mc; this->dim = dim; @@ -390,7 +384,7 @@ void Level::update(std::vector& cache, qreal bx0, qreal bz0, qreal bx1, q } -QWorld::QWorld(int mc, int64_t seed, int dim) +QWorld::QWorld(int mc, uint64_t seed, int dim) : mc(mc) , seed(seed) , dim(dim) @@ -435,9 +429,11 @@ QWorld::QWorld(int mc, int64_t seed, int dim) lvs[D_TREASURE] .init4struct(mc, seed, 0, 2048, D_TREASURE, 1); lvs[D_OUTPOST] .init4struct(mc, seed, 0, 2048, D_OUTPOST, 2); lvs[D_PORTAL] .init4struct(mc, seed, 0, 2048, D_PORTAL, 1); + lvs[D_PORTALN] .init4struct(mc, seed,-1, 2048, D_PORTALN, 1); lvs[D_FORTESS] .init4struct(mc, seed,-1, 2048, D_FORTESS, 1); lvs[D_BASTION] .init4struct(mc, seed,-1, 2048, D_BASTION, 1); - lvs[D_ENDCITY] .init4struct(mc, seed, 1, 2048, D_ENDCITY, 1); + lvs[D_ENDCITY] .init4struct(mc, seed, 1, 2048, D_ENDCITY, 2); + lvs[D_GATEWAY] .init4struct(mc, seed, 1, 2048, D_GATEWAY, 2); if (dim == 0) { @@ -473,11 +469,13 @@ QWorld::QWorld(int mc, int64_t seed, int dim) icons[D_TREASURE] = QPixmap(":/icons/treasure.png"); icons[D_OUTPOST] = QPixmap(":/icons/outpost.png"); icons[D_PORTAL] = QPixmap(":/icons/portal.png"); + icons[D_PORTALN] = QPixmap(":/icons/portal.png"); icons[D_SPAWN] = QPixmap(":/icons/spawn.png"); icons[D_STRONGHOLD] = QPixmap(":/icons/stronghold.png"); icons[D_FORTESS] = QPixmap(":/icons/fortress.png"); icons[D_BASTION] = QPixmap(":/icons/bastion.png"); icons[D_ENDCITY] = QPixmap(":/icons/endcity.png"); + icons[D_GATEWAY] = QPixmap(":/icons/gateway.png"); iconzvil = QPixmap(":/icons/zombie.png"); } @@ -596,9 +594,9 @@ struct SpawnStronghold : public QRunnable { QWorld *world; int mc; - int64_t seed; + uint64_t seed; - SpawnStronghold(QWorld *world, int mc, int64_t seed) : + SpawnStronghold(QWorld *world, int mc, uint64_t seed) : world(world),mc(mc),seed(seed) {} void run() @@ -728,9 +726,7 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz, for (int sopt = D_DESERT; sopt < D_SPAWN; sopt++) { Level& l = lvs[sopt]; - if (!sshow[sopt] || activelv > l.viewlv) - continue; - if (dim != l.dim) + if (!sshow[sopt] || dim != l.dim || activelv > l.viewlv) continue; std::vector frags; diff --git a/src/quad.h b/src/quad.h index a19951b..aa58799 100644 --- a/src/quad.h +++ b/src/quad.h @@ -26,9 +26,11 @@ enum { D_TREASURE, D_OUTPOST, D_PORTAL, + D_PORTALN, D_FORTESS, D_BASTION, D_ENDCITY, + D_GATEWAY, // non-recurring structures D_SPAWN, D_STRONGHOLD, @@ -53,11 +55,13 @@ inline const char *mapopt2str(int opt) case D_TREASURE: return "treasure"; case D_OUTPOST: return "outpost"; case D_PORTAL: return "portal"; + case D_PORTALN: return "portaln"; case D_SPAWN: return "spawn"; case D_STRONGHOLD: return "stronghold"; case D_FORTESS: return "fortress"; case D_BASTION: return "bastion"; case D_ENDCITY: return "endcity"; + case D_GATEWAY: return "gateway"; default: return ""; } } @@ -78,11 +82,13 @@ inline int str2mapopt(const char *s) if (!strcmp(s, "treasure")) return D_TREASURE; if (!strcmp(s, "outpost")) return D_OUTPOST; if (!strcmp(s, "portal")) return D_PORTAL; + if (!strcmp(s, "portaln")) return D_PORTALN; if (!strcmp(s, "spawn")) return D_SPAWN; if (!strcmp(s, "stronghold")) return D_STRONGHOLD; if (!strcmp(s, "fortress")) return D_FORTESS; if (!strcmp(s, "bastion")) return D_BASTION; if (!strcmp(s, "endcity")) return D_ENDCITY; + if (!strcmp(s, "gateway")) return D_GATEWAY; return D_NONE; } @@ -102,9 +108,11 @@ inline int mapopt2stype(int opt) case D_TREASURE: return Treasure; case D_OUTPOST: return Outpost; case D_PORTAL: return Ruined_Portal; + case D_PORTALN: return Ruined_Portal_N; case D_FORTESS: return Fortress; case D_BASTION: return Bastion; case D_ENDCITY: return End_City; + case D_GATEWAY: return End_Gateway; default: return -1; } @@ -119,7 +127,7 @@ struct VarPos }; void getStructs(std::vector *out, const StructureConfig sconf, - int mc, int64_t seed, int x0, int z0, int x1, int z1); + int mc, int dim, uint64_t seed, int x0, int z0, int x1, int z1); class Quad : public QRunnable { @@ -130,7 +138,7 @@ public: void run(); int mc; - int64_t seed; + uint64_t seed; int dim; const Layer *entry; int ti, tj; @@ -158,8 +166,8 @@ struct Level Level(); ~Level(); - void init4map(int mc, int64_t ws, int dim, int pix, int layerscale); - void init4struct(int mc, int64_t ws, int dim, int blocks, int sopt, int viewlv); + void init4map(int mc, uint64_t ws, int dim, int pix, int layerscale); + void init4struct(int mc, uint64_t ws, int dim, int blocks, int sopt, int viewlv); void resizeLevel(std::vector& cache, int x, int z, int w, int h); void update(std::vector& cache, qreal bx0, qreal bz0, qreal bx1, qreal bz1); @@ -167,7 +175,7 @@ struct Level std::vector cells; LayerStack g; Layer *entry; - int64_t seed; + uint64_t seed; int mc; int dim; int tx, tz, tw, th; @@ -181,7 +189,7 @@ struct Level struct QWorld { - QWorld(int mc, int64_t seed, int dim = 0); + QWorld(int mc, uint64_t seed, int dim = 0); ~QWorld(); void setDim(int dim); @@ -193,10 +201,10 @@ struct QWorld int getBiome(Pos p); int mc; - int64_t seed; + uint64_t seed; int dim; LayerStack g; - int64_t sha; + uint64_t sha; // the visible area is managed in Quads of different scales (for biomes and structures), // which are managed in rectangular sections as levels diff --git a/src/quadlistdialog.cpp b/src/quadlistdialog.cpp index 1599b1d..7fce0fe 100644 --- a/src/quadlistdialog.cpp +++ b/src/quadlistdialog.cpp @@ -37,11 +37,11 @@ QuadListDialog::~QuadListDialog() void QuadListDialog::loadSeed() { - ui->comboBoxMC->setCurrentText("1.16"); + ui->comboBoxMC->setCurrentText("1.17"); ui->lineSeed->clear(); int mc; - int64_t seed; + uint64_t seed; mainwindow->getSeed(&mc, &seed, false); const char *mcstr = mc2str(mc); @@ -52,10 +52,10 @@ void QuadListDialog::loadSeed() } ui->comboBoxMC->setCurrentText(mcstr); - ui->lineSeed->setText(QString::asprintf("%" PRId64, seed)); + ui->lineSeed->setText(QString::asprintf("%" PRId64, (int64_t)seed)); } -bool QuadListDialog::getSeed(int *mc, int64_t *seed) +bool QuadListDialog::getSeed(int *mc, uint64_t *seed) { const std::string& mcs = ui->comboBoxMC->currentText().toStdString(); *mc = str2mc(mcs.c_str()); @@ -67,7 +67,7 @@ bool QuadListDialog::getSeed(int *mc, int64_t *seed) int v = str2seed(ui->lineSeed->text(), seed); if (v == S_RANDOM) - ui->lineSeed->setText(QString::asprintf("%" PRId64, *seed)); + ui->lineSeed->setText(QString::asprintf("%" PRId64, (int64_t)*seed)); return true; } @@ -79,7 +79,7 @@ void QuadListDialog::refresh() ui->labelMsg->clear(); int mc; - int64_t seed; + uint64_t seed; if (!getSeed(&mc, &seed)) return; @@ -96,7 +96,7 @@ void QuadListDialog::refresh() qcnt = scanForQuads( sconf, 128, (seed) & MASK48, - low20QuadHutBarely, sizeof(low20QuadHutBarely) / sizeof(int64_t), 20, sconf.salt, + low20QuadHutBarely, sizeof(low20QuadHutBarely) / sizeof(uint64_t), 20, sconf.salt, -r, -r, 2*r, 2*r, qlist, maxq); if (qcnt >= maxq) @@ -151,10 +151,10 @@ void QuadListDialog::refresh() { getStructureConfig_override(Monument, mc, &sconf); // TODO: check salt delta - int64_t salt_delta = sconf.salt - MONUMENT_CONFIG.salt; + uint64_t salt_delta = sconf.salt - MONUMENT_CONFIG.salt; qcnt = scanForQuads( sconf, 160, seed & MASK48, - g_qm_90, sizeof(g_qm_90) / sizeof(int64_t), 48, salt_delta, + g_qm_90, sizeof(g_qm_90) / sizeof(uint64_t), 48, salt_delta, -r, -r, 2*r, 2*r, qlist, maxq); if (qcnt >= maxq) @@ -239,7 +239,7 @@ void QuadListDialog::gotoSwampHut() return; int mc; - int64_t seed; + uint64_t seed; if (!getSeed(&mc, &seed)) return; diff --git a/src/quadlistdialog.h b/src/quadlistdialog.h index c62da97..864fdb1 100644 --- a/src/quadlistdialog.h +++ b/src/quadlistdialog.h @@ -20,7 +20,7 @@ public: void loadSeed(); void refresh(); - bool getSeed(int *mc, int64_t *seed); + bool getSeed(int *mc, uint64_t *seed); private slots: void on_buttonGo_clicked(); diff --git a/src/quadlistdialog.ui b/src/quadlistdialog.ui index 3986076..1a80393 100644 --- a/src/quadlistdialog.ui +++ b/src/quadlistdialog.ui @@ -57,7 +57,7 @@ Structure - AlignLeading|AlignVCenter + AlignLeft|AlignVCenter @@ -68,7 +68,7 @@ distance to origin - AlignLeading|AlignVCenter + AlignLeft|AlignVCenter @@ -79,7 +79,7 @@ optimal AFK location - AlignLeading|AlignVCenter + AlignLeft|AlignVCenter @@ -90,7 +90,7 @@ distance to furthest spawning space from optimal AFK position - AlignLeading|AlignVCenter + AlignLeft|AlignVCenter @@ -122,6 +122,11 @@ Minecraft version + + + 1.17 + + 1.16 @@ -212,7 +217,8 @@ - .. + + diff --git a/src/search.cpp b/src/search.cpp index 062284f..255c2fb 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -39,7 +39,7 @@ static bool intersectRectLine(double rx1, double rz1, double rx2, double rz2, do return false; } -static bool isInnerRingOk(int mc, int64_t seed, int x1, int z1, int x2, int z2, int r1, int r2) +static bool isInnerRingOk(int mc, uint64_t seed, int x1, int z1, int x2, int z2, int r1, int r2) { StrongholdIter sh; Pos p = initFirstStronghold(&sh, mc, seed); @@ -61,7 +61,7 @@ static bool isInnerRingOk(int mc, int64_t seed, int x1, int z1, int x2, int z2, } -int testCond(StructPos *spos, int64_t seed, const Condition *cond, int mc, LayerStack *g, std::atomic_bool *abort) +int testCond(StructPos *spos, uint64_t seed, const Condition *cond, int mc, LayerStack *g, std::atomic_bool *abort) { int x1, x2, z1, z2; int rx1, rx2, rz1, rz2, rx, rz; @@ -105,7 +105,7 @@ int testCond(StructPos *spos, int64_t seed, const Condition *cond, int mc, Layer } if (scanForQuads( sconf, 128, (seed) & MASK48, low20QuadHutBarely, - sizeof(low20QuadHutBarely) / sizeof(int64_t), 20, sconf.salt, + sizeof(low20QuadHutBarely) / sizeof(uint64_t), 20, sconf.salt, rx1, rz1, rx2 - rx1 + 1, rz2 - rz1 + 1, &pc, 1) >= 1) { rx = pc.x; rz = pc.z; @@ -146,7 +146,7 @@ L_qm_any: } if (scanForQuads( sconf, 160, (seed) & MASK48, g_qm_90, - sizeof(g_qm_90) / sizeof(int64_t), 48, + sizeof(g_qm_90) / sizeof(uint64_t), 48, 0, // 0 for salt offset as g_qm_90 are not protobases rx1, rz1, rx2 - rx1 + 1, rz2 - rz1 + 1, &pc, 1) >= 1) { @@ -180,11 +180,13 @@ L_qm_any: case F_SHIPWRECK: case F_TREASURE: case F_PORTAL: + case F_PORTALN: case F_FORTRESS: case F_BASTION: case F_ENDCITY: + case F_GATEWAY: x1 = cond->x1; z1 = cond->z1; @@ -236,29 +238,31 @@ L_qm_any: continue; if (pc.x >= x1 && pc.x <= x2 && pc.z >= z1 && pc.z <= z2) { - if (g) + if (finfo.dim == 0 && g) { - if (finfo.dim == 0 && !isViableStructurePos(sconf.structType, mc, g, seed, pc.x, pc.z)) + if (!isViableStructurePos(sconf.structType, mc, g, seed, pc.x, pc.z)) continue; - if (finfo.dim == -1) + } + // TODO: add another search pass? + // (the g!=0 requirement for nether/end is artificial) + if (finfo.dim == -1 && g) + { + NetherNoise nn; + if (!isViableNetherStructurePos(sconf.structType, mc, &nn, seed, pc.x, pc.z)) + continue; + } + if (finfo.dim == +1 && g) + { + EndNoise en; + if (!isViableEndStructurePos(sconf.structType, mc, &en, seed, pc.x, pc.z)) + continue; + if (sconf.structType == End_City) { - NetherNoise nn; - if (!isViableNetherStructurePos(sconf.structType, mc, &nn, seed, pc.x, pc.z)) + SurfaceNoise sn; // TODO: store for reuse? + initSurfaceNoiseEnd(&sn, seed); + if (!isViableEndCityTerrain(&en, &sn, pc.x, pc.z)) continue; } - if (finfo.dim == +1) - { - EndNoise en; - if (!isViableEndStructurePos(sconf.structType, mc, &en, seed, pc.x, pc.z)) - continue; - if (sconf.structType == End_City) - { - SurfaceNoise sn; // TODO: store for reuse? - initSurfaceNoiseEnd(&sn, seed); - if (!isViableEndCityTerrain(&en, &sn, pc.x, pc.z)) - continue; - } - } } xt += pc.x; diff --git a/src/search.h b/src/search.h index 8e67722..01f8ae1 100644 --- a/src/search.h +++ b/src/search.h @@ -77,6 +77,8 @@ enum F_BIOME_END_4, F_BIOME_END_16, F_BIOME_END_64, + F_PORTALN, + F_GATEWAY, // new filters should be added here at the end to keep some downwards compatibility FILTER_MAX, }; @@ -222,21 +224,21 @@ static const struct FilterList ":icons/nether.png", "Nether biome filter 1:4", "Nether biomes with normal noise sampling at scale 1:4. (height: y = 0) " - "(Nether and End biomes only depend on the lower 48-bits of the seed.)" + "(The Nether and End depend only on the lower 48-bits of the seed.)" }; list[F_BIOME_NETHER_16] = FilterInfo{ CAT_NETHER, 1, 1, 0, 0, 16, 0, MC_1_16, -1, ":icons/nether.png", "Nether biome filter 1:16", "Nether biomes, but only sampled at scale 1:16. (height: y = 0) " - "(Nether and End biomes only depend on the lower 48-bits of the seed.)" + "(The Nether and End depend only on the lower 48-bits of the seed.)" }; list[F_BIOME_NETHER_64] = FilterInfo{ CAT_NETHER, 1, 1, 0, 0, 64, 0, MC_1_16, -1, ":icons/nether.png", "Nether biome filter 1:64", "Nether biomes, but only sampled at scale 1:64, (height: y = 0) " - "(Nether and End biomes only depend on the lower 48-bits of the seed.)" + "(The Nether and End depend only on the lower 48-bits of the seed.)" }; list[F_BIOME_END_1] = FilterInfo{ @@ -250,21 +252,21 @@ static const struct FilterList ":icons/the_end.png", "End biome filter 1:4", "End biomes sampled at scale 1:4. Note this is just a simple upscale of 1:16. " - "(Nether and End biomes only depend on the lower 48-bits of the seed.)" + "(The Nether and End depend only on the lower 48-bits of the seed.)" }; list[F_BIOME_END_16] = FilterInfo{ CAT_END, 1, 1, 0, 0, 16, 0, MC_1_9, +1, ":icons/the_end.png", "End biome filter 1:16", "End biomes with normal sampling at scale 1:16. " - "(Nether and End biomes only depend on the lower 48-bits of the seed.)" + "(The Nether and End depend only on the lower 48-bits of the seed.)" }; list[F_BIOME_END_64] = FilterInfo{ CAT_END, 1, 1, 0, 0, 64, 0, MC_1_9, +1, ":icons/the_end.png", "End biome filter 1:64", "End biomes with lossy sampling at scale 1:64. " - "(Nether and End biomes only depend on the lower 48-bits of the seed.)" + "(The Nether and End depend only on the lower 48-bits of the seed.)" }; list[F_SLIME] = FilterInfo{ @@ -372,25 +374,41 @@ static const struct FilterList "" }; + list[F_PORTALN] = FilterInfo{ + CAT_STRUCT, 1, 1, 0, Ruined_Portal_N, 1, 1, MC_1_16, -1, + ":icons/portal.png", + "Ruined portal (nether)", + "(The Nether and End depend only on the lower 48-bits of the seed.)" + }; + list[F_FORTRESS] = FilterInfo{ CAT_STRUCT, 1, 1, 0, Fortress, 1, 1, MC_1_0, -1, ":icons/fortress.png", "Nether fortress", - "" + "(The Nether and End depend only on the lower 48-bits of the seed.)" }; list[F_BASTION] = FilterInfo{ CAT_STRUCT, 1, 1, 0, Bastion, 1, 1, MC_1_16, -1, ":icons/bastion.png", "Bastion remnant", - "" + "(The Nether and End depend only on the lower 48-bits of the seed.)" }; list[F_ENDCITY] = FilterInfo{ CAT_STRUCT, 1, 1, 0, End_City, 1, 1, MC_1_9, +1, ":icons/endcity.png", "End city", - "" + "(The Nether and End depend only on the lower 48-bits of the seed.)" + }; + + list[F_GATEWAY] = FilterInfo{ + CAT_STRUCT, 1, 1, 0, End_Gateway, 1, 1, MC_1_13, +1, + ":icons/gateway.png", + "End gateway", + "Scattered end gateway return portals, not including those " + "generated when defeating the dragon. " + "(The Nether and End depend only on the lower 48-bits of the seed.)" }; } } @@ -417,7 +435,7 @@ struct StructPos }; -int testCond(StructPos *spos, int64_t seed, const Condition *cond, int mc, LayerStack *g, std::atomic_bool *abort); +int testCond(StructPos *spos, uint64_t seed, const Condition *cond, int mc, LayerStack *g, std::atomic_bool *abort); #endif // SEARCH_H diff --git a/src/searchitem.cpp b/src/searchitem.cpp index 85d1eb2..3a8f0fe 100644 --- a/src/searchitem.cpp +++ b/src/searchitem.cpp @@ -23,12 +23,12 @@ void SearchItem::run() LayerStack g; setupGenerator(&g, mc); StructPos spos[100] = {}; - QVector matches; + QVector matches; if (searchtype == SEARCH_LIST) { // seed = slist[..] - int64_t ie = idx+scnt < len ? idx+scnt : len; - for (int64_t i = idx; i < ie; i++) + uint64_t ie = idx+scnt < len ? idx+scnt : len; + for (uint64_t i = idx; i < ie; i++) { seed = slist[i]; if (testSeed(spos, seed, &g, true)) @@ -41,8 +41,8 @@ void SearchItem::run() { if (slist) { // seed = (high << 48) | slist[..] - int64_t high = (sstart >> 48) & 0xffff; - int64_t lowidx = idx; + uint64_t high = (sstart >> 48) & 0xffff; + uint64_t lowidx = idx; for (int i = 0; i < scnt; i++) { @@ -70,7 +70,7 @@ void SearchItem::run() if (testSeed(spos, seed, &g, true)) matches.push_back(seed); - if (seed == ~(int64_t)0) + if (seed == ~(uint64_t)0) { isdone = true; break; @@ -90,8 +90,8 @@ void SearchItem::run() break; } - int64_t high = (sstart >> 48) & 0xffff; - int64_t low; + uint64_t high = (sstart >> 48) & 0xffff; + uint64_t low; if (slist) low = slist[idx]; else @@ -127,38 +127,40 @@ void SearchItem::run() void SearchItemGenerator::init( - QObject *mainwin, int mc, const Condition *cond, int ccnt, - Gen48Settings gen48, const std::vector& seedlist, - int itemsize, int searchtype, int64_t sstart) + QObject *mainwin, int mc, + const SearchConfig& sc, const Gen48Settings& gen48, const Config& config, + const std::vector& slist, const QVector& cv) { this->mainwin = mainwin; - this->searchtype = searchtype; + this->searchtype = sc.searchtype; this->mc = mc; - this->cond = cond; - this->ccnt = ccnt; + this->condvec = cv; this->itemid = 0; - this->itemsiz = itemsize; - this->slist = seedlist; + this->itemsiz = config.seedsPerItem; + this->slist = slist; this->gen48 = gen48; this->idx = 0; this->scnt = ~(uint64_t)0; - this->seed = sstart; + this->seed = sc.startseed; + this->idxmin = 0; + this->smin = sc.smin; + this->smax = sc.smax; this->isdone = false; } -static int check(int64_t s48, void *data) +static int check(uint64_t s48, void *data) { (void) data; const StructureConfig sconf = {}; return isQuadBaseFeature24(sconf, s48, 7+1, 7+1, 9+1) != 0; } -static void genQHBases(QObject *qtobj, int qual, int64_t salt, std::vector& list48) +static void genQHBases(QObject *qtobj, int qual, uint64_t salt, std::vector& list48) { const char *lbstr = NULL; - const int64_t *lbset = NULL; - int64_t lbcnt = 0; + const uint64_t *lbset = NULL; + uint64_t lbcnt = 0; QString path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); if (path.isEmpty()) path = "protobases"; @@ -169,22 +171,22 @@ static void genQHBases(QObject *qtobj, int qual, int64_t salt, std::vector& slist, - Gen48Settings gen48, int64_t bufmax) +bool applyTranspose(std::vector& slist, + const Gen48Settings& gen48, uint64_t bufmax) { - std::vector list48; + std::vector list48; int x = gen48.x1; int z = gen48.z1; @@ -246,7 +248,7 @@ bool applyTranspose(std::vector& slist, int h = gen48.z2 - z + 1; // does the set of candidates for this condition fit in memory? - if ((int64_t)slist.size() * (int64_t)sizeof(int64_t) * w*h >= bufmax) + if ((uint64_t)slist.size() * sizeof(int64_t) * w*h >= bufmax) return false; try { @@ -255,10 +257,10 @@ bool applyTranspose(std::vector& slist, return false; } - int64_t *p = list48.data(); + uint64_t *p = list48.data(); for (int j = 0; j < h; j++) for (int i = 0; i < w; i++) - for (int64_t b : slist) + for (uint64_t b : slist) *p++ = moveStructure(b, x+i, z+j); std::sort(list48.begin(), list48.end()); @@ -270,13 +272,13 @@ bool applyTranspose(std::vector& slist, void SearchItemGenerator::presearch() { - int64_t sstart = seed; + uint64_t sstart = seed; if (searchtype != SEARCH_LIST) { if (gen48.mode == GEN48_QH) { - int64_t salt = 0; + uint64_t salt = 0; if (gen48.qual == IDEAL_SALTED) salt = gen48.salt; else @@ -290,11 +292,11 @@ void SearchItemGenerator::presearch() } else if (gen48.mode == GEN48_QM) { - const int64_t *qb = g_qm_90; - int64_t qn = sizeof(g_qm_90) / sizeof(int64_t); + const uint64_t *qb = g_qm_90; + uint64_t qn = sizeof(g_qm_90) / sizeof(uint64_t); slist.clear(); slist.reserve(qn); - for (int64_t i = 0; i < qn; i++) + for (uint64_t i = 0; i < qn; i++) if (qmonumentQual(qb[i]) >= gen48.qmarea) slist.push_back(qb[i]); } @@ -302,8 +304,8 @@ void SearchItemGenerator::presearch() { if (gen48.listsalt) { - for (auto& s : slist) - s += gen48.listsalt; + for (uint64_t& rs : slist) + rs += gen48.listsalt; } } @@ -326,24 +328,40 @@ void SearchItemGenerator::presearch() { if (!slist.empty()) { + seed = sstart; + if (seed < smin) + seed = smin; scnt = 0x10000 * slist.size(); - int64_t high = (sstart >> 48) & 0xffff; + uint64_t high = (seed >> 48) & 0xffff; for (idx = 0; idx < slist.size(); idx++) - if (slist[idx] >= (sstart & MASK48)) + if (slist[idx] >= (seed & MASK48)) break; if (idx == slist.size()) { - if (++high >= 0x10000) + if (high++ >= (smax >> 48)) isdone = true; idx = 0; } seed = (high << 48) | slist[idx]; + + for (idxmin = 0; idxmin < slist.size(); idxmin++) + if (slist[idxmin] >= (smin & MASK48)) + break; + for (scnt = 0; scnt < slist.size(); scnt++) + if (slist[scnt] >= (smax & MASK48)) + break; + high = ((smax >> 48) - (smin >> 48)) & 0xffff; + scnt += high * slist.size() - idxmin; } else { - scnt = ~(uint64_t)0; + scnt = smax - smin; seed = sstart; + if (seed < smin) + seed = smin; } + if (seed > smax) + isdone = true; } if (searchtype == SEARCH_BLOCKS) @@ -377,9 +395,14 @@ void SearchItemGenerator::getProgress(uint64_t *prog, uint64_t *end) if (searchtype == SEARCH_INC) { if (!slist.empty()) - *prog = ((seed >> 48) & 0xffff) * slist.size() + idx; + { + uint64_t h = ((seed >> 48) - (smin >> 48)) & 0xffff; + *prog = h * slist.size() + idx - idxmin; + } else - *prog = (uint64_t) seed; + { + *prog = seed - smin; + } } if (searchtype == SEARCH_BLOCKS) @@ -395,7 +418,7 @@ void SearchItemGenerator::getProgress(uint64_t *prog, uint64_t *end) // does the 48-bit seed meet the conditions c..ce? -static bool isCandidate(int64_t s48, int mc, const Condition *c, const Condition *ce, std::atomic_bool *abort) +static bool isCandidate(uint64_t s48, int mc, const Condition *c, const Condition *ce, std::atomic_bool *abort) { StructPos spos[100] = {}; for (; c != ce; c++) @@ -413,8 +436,8 @@ SearchItem *SearchItemGenerator::requestItem() item->searchtype = searchtype; item->mc = mc; - item->cond = cond; - item->ccnt = ccnt; + item->cond = condvec.data(); + item->ccnt = condvec.size(); item->itemid = itemid++; item->slist = slist.empty() ? NULL : slist.data(); item->len = slist.size(); @@ -436,28 +459,31 @@ SearchItem *SearchItemGenerator::requestItem() { if (!slist.empty()) { - int64_t high = (seed >> 48) & 0xffff; + uint64_t high = (seed >> 48) & 0xffff; idx += itemsiz; high += idx / slist.size(); idx %= slist.size(); seed = (high << 48) | slist[idx]; - if (high >= 0x10000) + if (high > (smax >> 48)) isdone = true; } else { - unsigned long long int s; - if (__builtin_uaddll_overflow(seed, itemsiz, &s)) - isdone = true; - seed = (int64_t)s; + // seed += itemsize; with overflow detection + uint64_t s = seed + itemsiz; + if (s < seed) + isdone = true; // overflow + seed = s; } + if (seed > smax) + isdone = true; } if (searchtype == SEARCH_BLOCKS) { if (!slist.empty()) { - int64_t high = (seed >> 48) & 0xffff; + uint64_t high = (seed >> 48) & 0xffff; high += itemsiz; if (high >= 0x10000) { @@ -471,8 +497,8 @@ SearchItem *SearchItemGenerator::requestItem() } else { - int64_t high = (seed >> 48) & 0xffff; - int64_t low = seed & MASK48; + uint64_t high = (seed >> 48) & 0xffff; + uint64_t low = seed & MASK48; high += itemsiz; if (high >= 0x10000) { @@ -481,11 +507,12 @@ SearchItem *SearchItemGenerator::requestItem() low++; unsigned long long ts = __rdtsc() + (1ULL << 27); - - /// === search for next candidate === + const Condition *c = item->cond; + const Condition *ce = item->cond+item->ccnt; + /// === search for next candiditem->condate === for (; low <= MASK48; low++) { - if (isCandidate(low, mc, cond, cond+ccnt, abort)) + if (isCandidate(low, mc, c, ce, abort)) break; if (__rdtsc() > ts) { diff --git a/src/searchitem.h b/src/searchitem.h index 2d8715f..1f3c5c0 100644 --- a/src/searchitem.h +++ b/src/searchitem.h @@ -25,7 +25,7 @@ public: virtual void run(); - inline bool testSeed(StructPos *spos, int64_t seed, LayerStack *g, bool s48check) + inline bool testSeed(StructPos *spos, uint64_t seed, LayerStack *g, bool s48check) { const Condition *c, *ce = cond + ccnt; if (s48check) @@ -45,8 +45,8 @@ public: } signals: - int results(QVector seeds, bool countonly); - void itemDone(uint64_t itemid, int64_t seed, bool isdone); + int results(QVector seeds, bool countonly); + void itemDone(uint64_t itemid, uint64_t seed, bool isdone); void canceled(uint64_t itemid); public: @@ -55,12 +55,12 @@ public: const Condition * cond; int ccnt; uint64_t itemid; // item identifier - const int64_t * slist; // candidate list - int64_t len; // number of candidates - int64_t idx; // current index in candidate buffer - int64_t sstart; // starting seed + const uint64_t * slist; // candidate list + uint64_t len; // number of candidates + uint64_t idx; // current index in candidate buffer + uint64_t sstart; // starting seed int scnt; // number of seeds to process in this item - int64_t seed; // (out) current seed while processing + uint64_t seed; // (out) current seed while processing bool isdone; // (out) has the final seed been reached std::atomic_bool * abort; @@ -72,9 +72,9 @@ public: struct SearchItemGenerator { void init( - QObject *mainwin, int mc, const Condition *cond, int ccnt, - Gen48Settings gen48, const std::vector& seedlist, - int itemsize, int searchtype, int64_t sstart); + QObject *mainwin, int mc, + const SearchConfig& sc, const Gen48Settings& gen48, const Config& config, + const std::vector& slist, const QVector& cv); void presearch(); @@ -84,15 +84,17 @@ struct SearchItemGenerator QObject * mainwin; int searchtype; int mc; - const Condition * cond; - int ccnt; + QVector condvec; uint64_t itemid; // item incrementor int itemsiz; // number of seeds per search item Gen48Settings gen48; // 48-bit generator settings - std::vector slist; // candidate list + std::vector slist; // candidate list uint64_t idx; // index within candidate list uint64_t scnt; // size of search space - int64_t seed; // current seed (next to be processed) + uint64_t seed; // current seed (next to be processed) + uint64_t idxmin; // idx of smin + uint64_t smin; + uint64_t smax; bool isdone; std::atomic_bool * abort; }; diff --git a/src/searchthread.cpp b/src/searchthread.cpp index 16d7a8c..05dfcaa 100644 --- a/src/searchthread.cpp +++ b/src/searchthread.cpp @@ -22,9 +22,15 @@ SearchThread::SearchThread(FormSearchControl *parent) itemgen.abort = &abort; } -bool SearchThread::set(QObject *mainwin, int type, int threads, Gen48Settings gen48, - std::vector& slist, int64_t sstart, int mc, - const QVector& cv, int itemsize, int queuesize) +bool SearchThread::set( + QObject *mainwin, int mc, + const SearchConfig& sc, const Gen48Settings& gen48, const Config& config, + std::vector& slist, const QVector& cv) + /* + QObject *mainwin, int type, int threads, Gen48Settings gen48, + std::vector& slist, uint64_t smin, uint64_t smax, + uint64_t sstart, int mc, const QVector& cv, + int itemsize, int queuesize)*/ { char refbuf[100] = {}; @@ -87,10 +93,10 @@ bool SearchThread::set(QObject *mainwin, int type, int threads, Gen48Settings ge } } - condvec = cv; - itemgen.init(mainwin, mc, condvec.data(), condvec.size(), gen48, slist, itemsize, type, sstart); - pool.setMaxThreadCount(threads); - recieved.resize(queuesize); + itemgen.init(mainwin, mc, sc, gen48, config, slist, cv); + + pool.setMaxThreadCount(sc.threads); + recieved.resize(config.queueSize); lastid = itemgen.itemid; reqstop = false; abort = false; @@ -107,7 +113,7 @@ void SearchThread::run() itemgen.getProgress(&prog, &end); emit progress(prog, end, itemgen.seed); - for (int idx = 0; idx < recieved.size(); idx++) + for (int64_t idx = 0; idx < recieved.size(); idx++) { recieved[idx].valid = false; startNextItem(); @@ -133,7 +139,7 @@ SearchItem *SearchThread::startNextItem() } -void SearchThread::onItemDone(uint64_t itemid, int64_t seed, bool isdone) +void SearchThread::onItemDone(uint64_t itemid, uint64_t seed, bool isdone) { --activecnt; @@ -142,8 +148,8 @@ void SearchThread::onItemDone(uint64_t itemid, int64_t seed, bool isdone) { if (itemid == lastid) { - int64_t len = recieved.size(); - int idx; + uint64_t len = recieved.size(); + uint64_t idx; for (idx = 1; idx < len; idx++) { if (!recieved[idx].valid) @@ -152,12 +158,12 @@ void SearchThread::onItemDone(uint64_t itemid, int64_t seed, bool isdone) lastid += idx; - for (int i = idx; i < len; i++) + for (uint64_t i = idx; i < len; i++) recieved[i-idx] = recieved[i]; - for (int i = len-idx; i < len; i++) + for (uint64_t i = len-idx; i < len; i++) recieved[i].valid = false; - for (int i = 0; i < idx; i++) + for (uint64_t i = 0; i < idx; i++) startNextItem(); uint64_t prog, end; @@ -166,7 +172,7 @@ void SearchThread::onItemDone(uint64_t itemid, int64_t seed, bool isdone) } else { - int idx = itemid - lastid; + int64_t idx = itemid - lastid; if (idx < 0 || idx >= recieved.size()) { QMessageBox::critical(parent, "Fatal Error", diff --git a/src/searchthread.h b/src/searchthread.h index 6e6a9f1..4a179e5 100644 --- a/src/searchthread.h +++ b/src/searchthread.h @@ -19,14 +19,14 @@ public: struct CheckedSeed { uint8_t valid; - int64_t seed; + uint64_t seed; }; SearchThread(FormSearchControl *parent); - bool set(QObject *mainwin, int type, int threads, Gen48Settings gen48, - std::vector& slist, int64_t sstart, int mc, - const QVector& cv, int itemsize, int queuesize); + bool set(QObject *mainwin, int mc, + const SearchConfig& sc, const Gen48Settings& gen48, const Config& config, + std::vector& slist, const QVector& cv); virtual void run() override; @@ -34,12 +34,12 @@ public: SearchItem *startNextItem(); signals: - void progress(uint64_t last, uint64_t end, int64_t seed); + void progress(uint64_t last, uint64_t end, uint64_t seed); void searchEnded(); // search thread is exiting (e.g. abort or done) void searchFinish(); // search ended and is comlete public slots: - void onItemDone(uint64_t itemid, int64_t seed, bool isdone); + void onItemDone(uint64_t itemid, uint64_t seed, bool isdone); void onItemCanceled(uint64_t itemid); public: diff --git a/src/seedtables.h b/src/seedtables.h index 7982738..32b54bc 100644 --- a/src/seedtables.h +++ b/src/seedtables.h @@ -5,7 +5,7 @@ // Quad monument bases are too expensive to generate on the fly and there are // so few of them that they can be hard coded, rather than loading from a file. -static const int64_t g_qm_90[] = { +static const uint64_t g_qm_90[] = { 35624347962, 775379617447, 3752024106001, @@ -115,7 +115,7 @@ static const int64_t g_qm_90[] = { 265956688913983, }; -static const int64_t g_qm_95[] = { +static const uint64_t g_qm_95[] = { 775379617447, 40642997855160, 75345272448242, @@ -171,7 +171,7 @@ static int qhutQual(int low20) // returns for a >90% quadmonument the number of blocks, by area, in spawn range __attribute__((const, used)) -static int qmonumentQual(int64_t s48) +static int qmonumentQual(uint64_t s48) { switch ((s48) & ((1LL<<48)-1)) { diff --git a/src/settings.h b/src/settings.h index a48196f..93036bd 100644 --- a/src/settings.h +++ b/src/settings.h @@ -63,21 +63,25 @@ enum { SEARCH_INC = 0, SEARCH_BLOCKS = 1, SEARCH_LIST = 2 }; struct SearchConfig { - int searchmode; + int searchtype; QString slist64path; int threads; - int64_t startseed; + uint64_t startseed; bool stoponres; + uint64_t smin; + uint64_t smax; SearchConfig() { reset(); } void reset() { - searchmode = SEARCH_INC; + searchtype = SEARCH_INC; slist64path = ""; threads = QThread::idealThreadCount(); startseed = 0; stoponres = true; + smin = 0; + smax = ~(uint64_t)0; } };