From 103351dfe1703cd51a5f861366fe989f61a2f868 Mon Sep 17 00:00:00 2001 From: Cubitect Date: Sun, 18 Jul 2021 15:35:22 +0200 Subject: [PATCH] Large biomes and custom salts --- cubiomes | 2 +- cubiomes-viewer.pro | 3 + src/aboutdialog.h | 4 +- src/cutil.h | 1 + src/extgendialog.cpp | 129 +++++++++++++++++++++++++ src/extgendialog.h | 42 ++++++++ src/extgendialog.ui | 85 +++++++++++++++++ src/formconditions.cpp | 12 +-- src/formsearchcontrol.cpp | 6 +- src/mainwindow.cpp | 154 ++++++++++++++++++------------ src/mainwindow.h | 5 +- src/mainwindow.ui | 6 ++ src/mapview.cpp | 6 +- src/mapview.h | 2 +- src/quad.cpp | 195 ++++++++++++++++++++------------------ src/quad.h | 20 ++-- src/quadlistdialog.cpp | 93 +++++++++--------- src/quadlistdialog.h | 5 +- src/quadlistdialog.ui | 48 +++++----- src/search.cpp | 32 ++++++- src/searchitem.cpp | 8 +- src/searchitem.h | 4 +- src/searchthread.cpp | 6 +- src/searchthread.h | 2 +- src/settings.h | 45 ++++++++- 25 files changed, 657 insertions(+), 258 deletions(-) create mode 100644 src/extgendialog.cpp create mode 100644 src/extgendialog.h create mode 100644 src/extgendialog.ui diff --git a/cubiomes b/cubiomes index 3b65b4b..61a341e 160000 --- a/cubiomes +++ b/cubiomes @@ -1 +1 @@ -Subproject commit 3b65b4bbf70b1e590edce06c34504632e7b08e5a +Subproject commit 61a341e1f695ec10d1ec836618275e871c69df4e diff --git a/cubiomes-viewer.pro b/cubiomes-viewer.pro index b71b8e1..3bb463c 100644 --- a/cubiomes-viewer.pro +++ b/cubiomes-viewer.pro @@ -35,6 +35,7 @@ SOURCES += \ src/aboutdialog.cpp \ src/collapsible.cpp \ src/configdialog.cpp \ + src/extgendialog.cpp \ src/formconditions.cpp \ src/formgen48.cpp \ src/formsearchcontrol.cpp \ @@ -60,6 +61,7 @@ HEADERS += \ src/aboutdialog.h \ src/collapsible.h \ src/configdialog.h \ + src/extgendialog.h \ src/formconditions.h \ src/formgen48.h \ src/formsearchcontrol.h \ @@ -81,6 +83,7 @@ HEADERS += \ FORMS += \ src/aboutdialog.ui \ src/configdialog.ui \ + src/extgendialog.ui \ src/formconditions.ui \ src/formgen48.ui \ src/formsearchcontrol.ui \ diff --git a/src/aboutdialog.h b/src/aboutdialog.h index b8cd54e..71b02ad 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -4,8 +4,8 @@ #include #define VERS_MAJOR 1 -#define VERS_MINOR 8 -#define VERS_PATCH 0 // negative patch number designates a development version +#define VERS_MINOR 9 +#define VERS_PATCH -1 // 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 63ab79f..5c87776 100644 --- a/src/cutil.h +++ b/src/cutil.h @@ -30,6 +30,7 @@ inline const char* struct2str(int stype) case Ruined_Portal: return "ruined_portal"; case Ruined_Portal_N: return "ruined_portal (nether)"; case Treasure: return "treasure"; + case Mineshaft: return "mineshaft"; case Fortress: return "fortress"; case Bastion: return "bastion"; case End_City: return "end_city"; diff --git a/src/extgendialog.cpp b/src/extgendialog.cpp new file mode 100644 index 0000000..6d6484d --- /dev/null +++ b/src/extgendialog.cpp @@ -0,0 +1,129 @@ +#include "extgendialog.h" +#include "ui_extgendialog.h" + +#include "cutil.h" + +#include + +ExtGenDialog::ExtGenDialog(QWidget *parent, ExtGenSettings *extgen) + : QDialog(parent) + , ui(new Ui::ExtGenDialog) + , checkSalts{} + , lineSalts{} +{ + ui->setupUi(this); + + int stv[] = { + Desert_Pyramid, + Jungle_Pyramid, + Swamp_Hut, + Igloo, + Village, + Ocean_Ruin, + Shipwreck, + Monument, + Mansion, + Outpost, + Ruined_Portal, + Ruined_Portal_N, + Treasure, + //Mineshaft, + Fortress, + Bastion, + End_City, + End_Gateway, + }; + + QGridLayout *grid = new QGridLayout(ui->groupSalts); + for (size_t i = 0; i < sizeof(stv)/sizeof(stv[0]); i++) + { + int st = stv[i]; + grid->addWidget((checkSalts[st] = new QCheckBox(struct2str(st))), i, 0); + grid->addWidget((lineSalts[st] = new QLineEdit()), i, 1); + connect(checkSalts[st], &QCheckBox::toggled, this, &ExtGenDialog::updateToggles); + } + + Pos dummy; + if (!getStructurePos(Feature, INT_MAX, 0, 0, 0, &dummy)) + { + // cubiomes was not built with salt override support + ui->groupSalts->setEnabled(false); + } + + initSettings(extgen); +} + +ExtGenDialog::~ExtGenDialog() +{ + delete ui; +} + +void ExtGenDialog::initSettings(ExtGenSettings *extgen) +{ + ui->checkLarge->setChecked(extgen->largeBiomes); + ui->groupSalts->setChecked(extgen->saltOverride); + + for (int i = 0; i < FEATURE_NUM; i++) + { + if (!checkSalts[i]) + continue; + uint64_t salt = extgen->salts[i]; + if (salt != ~(uint64_t)0) + { + checkSalts[i]->setChecked(salt <= MASK48); + lineSalts[i]->setEnabled(salt <= MASK48); + lineSalts[i]->setText(QString::asprintf("%" PRIu64, salt & MASK48)); + } + else + { + checkSalts[i]->setChecked(false); + lineSalts[i]->setEnabled(false); + lineSalts[i]->setText(""); + } + } + updateToggles(); +} + +ExtGenSettings ExtGenDialog::getSettings() +{ + extgen.largeBiomes = ui->checkLarge->isChecked(); + extgen.saltOverride = ui->groupSalts->isChecked(); + + for (int i = 0; i < FEATURE_NUM; i++) + { + if (!checkSalts[i]) + continue; + + bool ok; + uint64_t salt; + salt = lineSalts[i]->text().toULongLong(&ok); + + if (checkSalts[i]->isChecked()) + extgen.salts[i] = salt; + else if (ok) + extgen.salts[i] = ok | (1ULL << 63); + else + extgen.salts[i] = ~(uint64_t)0; + } + + return extgen; +} + +void ExtGenDialog::on_buttonBox_clicked(QAbstractButton *button) +{ + if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole) + { + extgen.reset(); + initSettings(&extgen); + } +} + +void ExtGenDialog::updateToggles() +{ + for (int i = 0; i < FEATURE_NUM; i++) + { + if (!checkSalts[i]) + continue; + lineSalts[i]->setEnabled(checkSalts[i]->isChecked()); + } +} diff --git a/src/extgendialog.h b/src/extgendialog.h new file mode 100644 index 0000000..7a94d4f --- /dev/null +++ b/src/extgendialog.h @@ -0,0 +1,42 @@ +#ifndef EXTGENDIALOG_H +#define EXTGENDIALOG_H + +#include +#include +#include +#include + +#include "settings.h" + + +namespace Ui { +class ExtGenDialog; +} + + +class ExtGenDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ExtGenDialog(QWidget *parent, ExtGenSettings *extgen); + ~ExtGenDialog(); + + void initSettings(ExtGenSettings *extgen); + + ExtGenSettings getSettings(); + +private slots: + void on_buttonBox_clicked(QAbstractButton *button); + + void updateToggles(); + +private: + Ui::ExtGenDialog *ui; + QCheckBox *checkSalts[FEATURE_NUM]; + QLineEdit *lineSalts[FEATURE_NUM]; + + ExtGenSettings extgen; +}; + +#endif // EXTGENDIALOG_H diff --git a/src/extgendialog.ui b/src/extgendialog.ui new file mode 100644 index 0000000..0b6466d --- /dev/null +++ b/src/extgendialog.ui @@ -0,0 +1,85 @@ + + + ExtGenDialog + + + World Settings (experimental) + + + + :/icons/map.png:/icons/map.png + + + + + + Override structure salt + + + true + + + false + + + + + + + Simulate innertia for the map view + + + Large biomes + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults + + + + + + + + + + + buttonBox + accepted() + ExtGenDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ExtGenDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/formconditions.cpp b/src/formconditions.cpp index 176ad21..a197289 100644 --- a/src/formconditions.cpp +++ b/src/formconditions.cpp @@ -158,9 +158,9 @@ void FormConditions::editCondition(QListWidgetItem *item) { if (!(item->flags() & Qt::ItemIsSelectable)) return; - int mc = MC_NEWEST; - parent->getSeed(&mc, 0); - FilterDialog *dialog = new FilterDialog(this, mc, item, (Condition*)item->data(Qt::UserRole).data()); + WorldInfo wi; + parent->getSeed(&wi); + FilterDialog *dialog = new FilterDialog(this, wi.mc, item, (Condition*)item->data(Qt::UserRole).data()); QObject::connect(dialog, SIGNAL(setCond(QListWidgetItem*,Condition)), this, SLOT(addItemCondition(QListWidgetItem*,Condition)), Qt::QueuedConnection); dialog->show(); } @@ -204,9 +204,9 @@ void FormConditions::on_buttonEdit_clicked() void FormConditions::on_buttonAddFilter_clicked() { - int mc = MC_1_16; - parent->getSeed(&mc, 0); - FilterDialog *dialog = new FilterDialog(this, mc); + WorldInfo wi; + parent->getSeed(&wi); + FilterDialog *dialog = new FilterDialog(this, wi.mc); QObject::connect(dialog, SIGNAL(setCond(QListWidgetItem*,Condition)), this, SLOT(addItemCondition(QListWidgetItem*,Condition)), Qt::QueuedConnection); dialog->show(); } diff --git a/src/formsearchcontrol.cpp b/src/formsearchcontrol.cpp index 60a7487..d70aa2a 100644 --- a/src/formsearchcontrol.cpp +++ b/src/formsearchcontrol.cpp @@ -183,8 +183,8 @@ void FormSearchControl::on_buttonStart_clicked() { if (ui->buttonStart->isChecked()) { - int mc = MC_NEWEST; - parent->getSeed(&mc, NULL); + WorldInfo wi; + parent->getSeed(&wi); const Config& config = parent->config; const QVector& condvec = parent->formCond->getConditions(); SearchConfig sc = getSearchConfig(); @@ -217,7 +217,7 @@ void FormSearchControl::on_buttonStart_clicked() else slist.clear(); - ok = sthread.set(parent, mc, sc, gen48, config, slist, condvec); + ok = sthread.set(parent, wi, sc, gen48, config, slist, condvec); } if (ok) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8d58e28..622e9db 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -6,6 +6,7 @@ #include "aboutdialog.h" #include "protobasedialog.h" #include "filterdialog.h" +#include "extgendialog.h" #include "quad.h" #include "cutil.h" @@ -27,11 +28,22 @@ #include #include +// Keep the extended generator settings in global scope, but we mainly need +// them in this file. (Pass through via pointer elsewhere.) +static ExtGenSettings g_extgen; + extern "C" int getStructureConfig_override(int stype, int mc, StructureConfig *sconf) { + if U(mc == INT_MAX) // to check if override is enabled in cubiomes + mc = 0; int ok = getStructureConfig(stype, mc, sconf); - // TODO: add and apply config settings + if (ok && g_extgen.saltOverride) + { + uint64_t salt = g_extgen.salts[stype]; + if (salt <= MASK48) + sconf->salt = salt; + } return ok; } @@ -208,46 +220,46 @@ MapView* MainWindow::getMapView() return ui->mapView; } -bool MainWindow::getSeed(int *mc, uint64_t *seed, bool applyrand) +bool MainWindow::getSeed(WorldInfo *wi, bool applyrand) { bool ok = true; - if (mc) + const std::string& mcs = ui->comboBoxMC->currentText().toStdString(); + wi->mc = str2mc(mcs.c_str()); + if (wi->mc < 0) { - const std::string& mcs = ui->comboBoxMC->currentText().toStdString(); - *mc = str2mc(mcs.c_str()); - if (*mc < 0) - { - *mc = MC_NEWEST; - qDebug() << "Unknown MC version: " << *mc; - ok = false; - } + wi->mc = MC_NEWEST; + qDebug() << "Unknown MC version: " << wi->mc; + ok = false; } - if (seed) + int v = str2seed(ui->seedEdit->text(), &wi->seed); + if (applyrand && v == S_RANDOM) { - int v = str2seed(ui->seedEdit->text(), seed); - if (applyrand && v == S_RANDOM) - ui->seedEdit->setText(QString::asprintf("%" PRId64, (int64_t)*seed)); + ui->seedEdit->setText(QString::asprintf("%" PRId64, (int64_t)wi->seed)); } + wi->large = g_extgen.largeBiomes; + return ok; } -bool MainWindow::setSeed(int mc, uint64_t seed, int dim) +bool MainWindow::setSeed(WorldInfo wi, int dim) { - const char *mcstr = mc2str(mc); + const char *mcstr = mc2str(wi.mc); if (!mcstr) { - qDebug() << "Unknown MC version: " << mc; + qDebug() << "Unknown MC version: " << wi.mc; return false; } if (dim == INT_MAX) dim = getDim(); + g_extgen.largeBiomes = wi.large; + ui->comboBoxMC->setCurrentText(mcstr); - ui->seedEdit->setText(QString::asprintf("%" PRId64, (int64_t)seed)); - ui->mapView->setSeed(mc, seed, dim); + ui->seedEdit->setText(QString::asprintf("%" PRId64, (int64_t)wi.seed)); + ui->mapView->setSeed(wi, dim); return true; } @@ -275,11 +287,20 @@ void MainWindow::saveSettings() settings.setValue("config/queueSize", config.queueSize); settings.setValue("config/maxMatching", config.maxMatching); - int mc = MC_NEWEST; - uint64_t seed = 0; - getSeed(&mc, &seed, false); - settings.setValue("map/mc", mc); - settings.setValue("map/seed", (qlonglong)seed); + settings.setValue("world/largeBiomes", g_extgen.largeBiomes); + settings.setValue("world/saltOverride", g_extgen.saltOverride); + for (int st = 0; st < FEATURE_NUM; st++) + { + uint64_t salt = g_extgen.salts[st]; + if (salt <= MASK48) + settings.setValue(QString("world/salt_") + struct2str(st), (qulonglong)salt); + } + + WorldInfo wi; + getSeed(&wi, false); + settings.setValue("map/mc", wi.mc); + settings.setValue("map/large", wi.large); + settings.setValue("map/seed", (qlonglong)wi.seed); settings.setValue("map/dim", getDim()); settings.setValue("map/x", ui->mapView->getX()); settings.setValue("map/z", ui->mapView->getZ()); @@ -313,6 +334,14 @@ void MainWindow::loadSettings() ui->mapView->setSmoothMotion(config.smoothMotion); onStyleChanged(config.uistyle); + g_extgen.largeBiomes = settings.value("world/largeBiomes", g_extgen.largeBiomes).toBool(); + g_extgen.saltOverride = settings.value("world/saltOverride", g_extgen.saltOverride).toBool(); + for (int st = 0; st < FEATURE_NUM; st++) + { + QVariant v = QVariant::fromValue(~(qulonglong)0); + g_extgen.salts[st] = settings.value(QString("world/salt_") + struct2str(st), v).toULongLong(); + } + int dim = settings.value("map/dim", getDim()).toInt(); if (dim == -1) dimactions[1]->setChecked(true); @@ -321,12 +350,12 @@ void MainWindow::loadSettings() else dimactions[0]->setChecked(true); - int mc = MC_NEWEST; - uint64_t seed = 0; - getSeed(&mc, &seed, true); - mc = settings.value("map/mc", mc).toInt(); - seed = (uint64_t) settings.value("map/seed", QVariant::fromValue((qlonglong)seed)).toLongLong(); - setSeed(mc, seed); + WorldInfo wi; + getSeed(&wi, true); + wi.mc = settings.value("map/mc", wi.mc).toInt(); + wi.large = settings.value("map/large", wi.large).toBool(); + wi.seed = (uint64_t) settings.value("map/seed", QVariant::fromValue((qlonglong)wi.seed)).toLongLong(); + setSeed(wi); qreal x = ui->mapView->getX(); qreal z = ui->mapView->getZ(); @@ -380,14 +409,14 @@ bool MainWindow::saveProgress(QString fnam, bool quiet) QVector condvec = formCond->getConditions(); QVector results = formControl->getResults(); - int mc = MC_NEWEST; - getSeed(&mc, 0); + WorldInfo wi; + getSeed(&wi); QTextStream stream(&file); stream << "#Version: " << VERS_MAJOR << "." << VERS_MINOR << "." << VERS_PATCH << "\n"; stream << "#Time: " << QDateTime::currentDateTime().toString() << "\n"; // MC version of the session should take priority over the one in the settings - stream << "#MC: " << mc2str(mc) << "\n"; + stream << "#MC: " << mc2str(wi.mc) << "\n"; stream << "#Search: " << searchconf.searchtype << "\n"; if (!searchconf.slist64path.isEmpty()) @@ -445,9 +474,8 @@ bool MainWindow::loadProgress(QString fnam, bool quiet) char buf[4096]; int tmp; - int mc = MC_NEWEST; - uint64_t seed; - getSeed(&mc, &seed, true); + WorldInfo wi; + getSeed(&wi, true); QTextStream stream(&file); QString line; @@ -467,7 +495,7 @@ bool MainWindow::loadProgress(QString fnam, bool quiet) break; if (line.startsWith("#Time:")) continue; - else if (sscanf(p, "#MC: %8[^\n]", buf) == 1) { mc = str2mc(buf); if (mc < 0) return false; } + else if (sscanf(p, "#MC: %8[^\n]", buf) == 1) { wi.mc = str2mc(buf); if (wi.mc < 0) return false; } // SearchConfig else if (sscanf(p, "#Search: %d", &searchconf.searchtype) == 1) {} else if (sscanf(p, "#Progress: %" PRId64, &searchconf.startseed) == 1) {} @@ -508,7 +536,7 @@ bool MainWindow::loadProgress(QString fnam, bool quiet) } } - setSeed(mc, seed); + setSeed(wi); formControl->on_buttonClear_clicked(); formControl->searchResultsAdd(seeds, false); @@ -529,10 +557,9 @@ bool MainWindow::loadProgress(QString fnam, bool quiet) void MainWindow::updateMapSeed() { - int mc; - uint64_t seed; - if (getSeed(&mc, &seed)) - setSeed(mc, seed); + WorldInfo wi; + if (getSeed(&wi)) + setSeed(wi); } @@ -653,11 +680,11 @@ void MainWindow::on_actionScan_seed_for_Quad_Huts_triggered() void MainWindow::on_actionOpen_shadow_seed_triggered() { - int mc; - uint64_t seed; - if (getSeed(&mc, &seed)) + WorldInfo wi; + if (getSeed(&wi)) { - setSeed(mc, getShadow(seed)); + wi.seed = getShadow(wi.seed); + setSeed(wi); } } @@ -687,6 +714,18 @@ void MainWindow::on_actionAddShadow_triggered() formControl->searchResultsAdd(shadows, false); } +void MainWindow::on_actionExtGen_triggered() +{ + ExtGenDialog *dialog = new ExtGenDialog(this, &g_extgen); + int status = dialog->exec(); + if (status == QDialog::Accepted) + { + g_extgen = dialog->getSettings(); + updateMapSeed(); + update(); + } +} + void MainWindow::on_mapView_customContextMenuRequested(const QPoint &pos) { QMenu menu(this); @@ -767,9 +806,8 @@ void MainWindow::on_buttonAnalysis_clicked() bool everything = ui->radioEverything->isChecked(); - int mc; - uint64_t seed; - if (!getSeed(&mc, &seed)) + WorldInfo wi; + if (!getSeed(&wi)) return; ui->buttonAnalysis->setEnabled(false); @@ -781,8 +819,8 @@ void MainWindow::on_buttonAnalysis_clicked() int dim = getDim(); LayerStack g; - setupGenerator(&g, mc); - applySeed(&g, seed); + setupGeneratorLargeBiomes(&g, wi.mc, wi.large); + applySeed(&g, wi.seed); int *ids = allocCache(g.entry_1, step, step); for (int x = x1; x <= x2; x += step) @@ -800,13 +838,13 @@ void MainWindow::on_buttonAnalysis_clicked() } if (everything || dim == -1) { - genNetherScaled(mc, seed, 1, ids, x, z, w, h, 0, 0); + genNetherScaled(wi.mc, wi.seed, 1, ids, x, z, w, h, 0, 0); for (int i = 0; i < w*h; i++) idcnt[ ids[i] & 0xff ]++; } if (everything || dim == +1) { - genEndScaled(mc, seed, 1, ids, x, z, w, h); + genEndScaled(wi.mc, wi.seed, 1, ids, x, z, w, h); for (int i = 0; i < w*h; i++) idcnt[ ids[i] & 0xff ]++; } @@ -862,9 +900,9 @@ void MainWindow::on_buttonAnalysis_clicked() int stype = mapopt2stype(sopt); st.clear(); StructureConfig sconf; - if (!getStructureConfig_override(stype, mc, &sconf)) + if (!getStructureConfig_override(stype, wi.mc, &sconf)) continue; - getStructs(&st, sconf, mc, sdim, seed, x1, z1, x2, z2); + getStructs(&st, sconf, wi, sdim, x1, z1, x2, z2); if (st.empty()) continue; @@ -890,7 +928,7 @@ void MainWindow::on_buttonAnalysis_clicked() if (everything || (dim == 0 && getMapView()->getShow(D_SPAWN))) { - Pos pos = getSpawn(mc, &g, NULL, seed); + Pos pos = getSpawn(wi.mc, &g, NULL, wi.seed); if (pos.x >= x1 && pos.x <= x2 && pos.z >= z1 && pos.z <= z2) { item_cat = new QTreeWidgetItem(tree); @@ -905,7 +943,7 @@ void MainWindow::on_buttonAnalysis_clicked() if (everything || (dim == 0 && getMapView()->getShow(D_STRONGHOLD))) { StrongholdIter sh; - initFirstStronghold(&sh, mc, seed); + initFirstStronghold(&sh, wi.mc, wi.seed); std::vector shp; while (nextStronghold(&sh, &g, NULL) > 0) { diff --git a/src/mainwindow.h b/src/mainwindow.h index 373aa02..7ab9ee5 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -45,8 +45,8 @@ public: QAction *addMapAction(int sopt, const char *iconpath, const char *tip); - bool getSeed(int *mc, uint64_t *seed, bool applyrand = true); - bool setSeed(int mc, uint64_t seed, int dim = INT_MAX); + bool getSeed(WorldInfo *wi, bool applyrand = true); + bool setSeed(WorldInfo wi, int dim = INT_MAX); int getDim(); MapView *getMapView(); @@ -80,6 +80,7 @@ private slots: void on_actionCopy_triggered(); void on_actionPaste_triggered(); void on_actionAddShadow_triggered(); + void on_actionExtGen_triggered(); void on_mapView_customContextMenuRequested(const QPoint &pos); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 181812e..ca55797 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -643,6 +643,7 @@ QToolButton:checked { + @@ -718,6 +719,11 @@ QToolButton:checked { Add shadow for all seeds + + + World settings... + + diff --git a/src/mapview.cpp b/src/mapview.cpp index cacd1c9..36ed7f8 100644 --- a/src/mapview.cpp +++ b/src/mapview.cpp @@ -72,15 +72,15 @@ MapView::~MapView() delete overlay; } -void MapView::setSeed(int mc, uint64_t s, int dim) +void MapView::setSeed(WorldInfo wi, int dim) { prevx = focusx = getX(); prevz = focusz = getZ(); velx = velz = 0; - if (world == NULL || world->mc != mc || world->seed != s) + if (world == NULL || !wi.equals(world->wi)) { delete world; - world = new QWorld(mc, s, dim); + world = new QWorld(wi, dim); } else if (world->dim != dim) { diff --git a/src/mapview.h b/src/mapview.h index d629992..4025f80 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, uint64_t s, int dim); + void setSeed(WorldInfo wi, 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 0bd8738..0d8ae1f 100644 --- a/src/quad.cpp +++ b/src/quad.cpp @@ -11,7 +11,7 @@ Quad::Quad(const Level* l, int i, int j) - : mc(l->mc),seed(l->seed),dim(l->dim),entry(l->entry) + : wi(l->wi),dim(l->dim),entry(l->entry) , ti(i),tj(j),blocks(l->blocks),pixs(l->pixs),sopt(l->sopt) , rgb(),img(),spos() , done() @@ -28,7 +28,7 @@ Quad::~Quad() } void getStructs(std::vector *out, const StructureConfig sconf, - int mc, int dim, uint64_t seed, int x0, int z0, int x1, int z1) + WorldInfo wi, int dim, int x0, int z0, int x1, int z1) { union { LayerStack g; @@ -36,22 +36,22 @@ void getStructs(std::vector *out, const StructureConfig sconf, EndNoise en; } u; - if (dim == 0) - { - setupGenerator(&u.g, mc); - } - int si0 = (int)floor(x0 / (qreal)(sconf.regionSize * 16)); int sj0 = (int)floor(z0 / (qreal)(sconf.regionSize * 16)); int si1 = (int)floor((x1-1) / (qreal)(sconf.regionSize * 16)); int sj1 = (int)floor((z1-1) / (qreal)(sconf.regionSize * 16)); + if (dim == 0) + { + setupGeneratorLargeBiomes(&u.g, wi.mc, wi.large); + } + for (int i = si0; i <= si1; i++) { for (int j = sj0; j <= sj1; j++) { Pos p; - if (!getStructurePos(sconf.structType, mc, seed, i, j, &p)) + if (!getStructurePos(sconf.structType, wi.mc, wi.seed, i, j, &p)) continue; if (p.x >= x0 && p.x < x1 && p.z >= z0 && p.z < z1) @@ -59,19 +59,19 @@ void getStructs(std::vector *out, const StructureConfig sconf, int id = 0; if (dim == 0) { - id = isViableStructurePos(sconf.structType, mc, &u.g, seed, p.x, p.z); + id = isViableStructurePos(sconf.structType, wi.mc, &u.g, wi.seed, p.x, p.z); } else if (dim == -1) { - id = isViableNetherStructurePos(sconf.structType, mc, &u.nn, seed, p.x, p.z); + id = isViableNetherStructurePos(sconf.structType, wi.mc, &u.nn, wi.seed, p.x, p.z); } else if (dim == +1) { - id = isViableEndStructurePos(sconf.structType, mc, &u.en, seed, p.x, p.z); + id = isViableEndStructurePos(sconf.structType, wi.mc, &u.en, wi.seed, p.x, p.z); if (id && sconf.structType == End_City) { SurfaceNoise sn; - initSurfaceNoiseEnd(&sn, seed); + initSurfaceNoiseEnd(&sn, wi.seed); id = isViableEndCityTerrain(&u.en, &sn, p.x, p.z); } } @@ -81,7 +81,7 @@ void getStructs(std::vector *out, const StructureConfig sconf, VarPos vp = { p, 0 }; if (sconf.structType == Village) { - VillageType vt = getVillageType(mc, seed, p.x, p.z, id); + VillageType vt = getVillageType(wi.mc, wi.seed, p.x, p.z, id); vp.variant = vt.abandoned; } out->push_back(vp); @@ -105,12 +105,12 @@ void Quad::run() if (dim == -1) { b = (int*) malloc((w+7) * (h+7) * sizeof(int)); - genNetherScaled(mc, seed, blocks / pixs, b, x, z, w, h, 0, 0); + genNetherScaled(wi.mc, wi.seed, blocks / pixs, b, x, z, w, h, 0, 0); } else if (dim == +1) // end { b = (int*) malloc((w+7) * (h+7) * sizeof(int)); - genEndScaled(mc, seed, blocks / pixs, b, x, z, w, h); + genEndScaled(wi.mc, wi.seed, blocks / pixs, b, x, z, w, h); } else { @@ -132,8 +132,8 @@ void Quad::run() int z0 = tj*blocks, z1 = (tj+1)*blocks; std::vector* st = new std::vector(); StructureConfig sconf; - if (getStructureConfig_override(structureType, mc, &sconf)) - getStructs(st, sconf, mc, dim, seed, x0, z0, x1, z1); + if (getStructureConfig_override(structureType, wi.mc, &sconf)) + getStructs(st, sconf, wi, dim, x0, z0, x1, z1); spos = st; } } @@ -142,7 +142,7 @@ void Quad::run() Level::Level() - : cells(),g(),entry(),seed(),mc(),dim() + : cells(),g(),entry(),wi(),dim() , tx(),tz(),tw(),th() , scale(),blocks(),pixs() , sopt() @@ -209,10 +209,9 @@ int mapOceanMixMod(const Layer * l, int * out, int x, int z, int w, int h) return 0; } -void Level::init4map(int mc, uint64_t ws, int dim, int pix, int layerscale) +void Level::init4map(WorldInfo wi, int dim, int pix, int layerscale) { - this->mc = mc; - this->seed = ws; + this->wi = wi; this->dim = dim; tx = tz = tw = th = 0; @@ -223,7 +222,9 @@ void Level::init4map(int mc, uint64_t ws, int dim, int pix, int layerscale) if (dim == 0) // overworld { - setupGenerator(&g, mc); + setupGeneratorLargeBiomes(&g, wi.mc, wi.large); + int l1 = 0, l2 = 0; + entry = NULL; switch (scale) { @@ -234,41 +235,55 @@ void Level::init4map(int mc, uint64_t ws, int dim, int pix, int layerscale) entry = g.entry_4; break; case 16: - if (mc >= MC_1_13) { - entry = setupLayer(&g, L_VORONOI_1, &mapOceanMixMod, mc, 1, 0, 0, &g.layers[L_SHORE_16], &g.layers[L_ZOOM_16_OCEAN]); + if (wi.mc >= MC_1_13) { + l1 = wi.large ? L_ZOOM_4 : L_SHORE_16; + l2 = L_ZOOM_16_OCEAN; } else { entry = g.entry_16; } break; case 64: - if (mc >= MC_1_13) { - entry = setupLayer(&g, L_VORONOI_1, &mapOceanMixMod, mc, 1, 0, 0, &g.layers[L_SUNFLOWER_64], &g.layers[L_ZOOM_64_OCEAN]); + if (wi.mc >= MC_1_13) { + l1 = wi.large ? L_SHORE_16 : L_SUNFLOWER_64; + l2 = L_ZOOM_64_OCEAN; } else { entry = g.entry_64; } break; case 256: - if (mc >= MC_1_13) { - int layerid = mc >= MC_1_14 ? L_BAMBOO_256 : L_BIOME_256; - entry = setupLayer(&g, L_VORONOI_1, &mapOceanMixMod, mc, 1, 0, 0, &g.layers[layerid], &g.layers[L_OCEAN_TEMP_256]); + if (wi.mc >= MC_1_13) { + if (wi.large) { + l1 = L_SUNFLOWER_64; + } else { + l1 = (wi.mc >= MC_1_14 ? L_BAMBOO_256 : L_BIOME_256); + } + l2 = L_OCEAN_TEMP_256; } else { entry = g.entry_256; } break; - default: + } + if (!entry && l1 && l2) + { + // setup a custom layer in place of voronoi + entry = setupLayer( + &g, L_VORONOI_1, &mapOceanMixMod, wi.mc, 1, 0, 0, + &g.layers[l1], &g.layers[l2]); + } + if (!entry) + { printf("Bad scale (%d) for level\n", scale); exit(1); } - setLayerSeed(entry, seed); + setLayerSeed(entry, wi.seed); } } -void Level::init4struct(int mc, uint64_t ws, int dim, int blocks, int sopt, int lv) +void Level::init4struct(WorldInfo wi, int dim, int blocks, int sopt, int lv) { - this->mc = mc; + this->wi = wi; this->dim = dim; - this->seed = ws; this->blocks = blocks; this->pixs = -1; this->scale = -1; @@ -384,9 +399,8 @@ void Level::update(std::vector& cache, qreal bx0, qreal bz0, qreal bx1, q } -QWorld::QWorld(int mc, uint64_t seed, int dim) - : mc(mc) - , seed(seed) +QWorld::QWorld(WorldInfo wi, int dim) + : wi(wi) , dim(dim) , sha() , lvb() @@ -409,49 +423,49 @@ QWorld::QWorld(int mc, uint64_t seed, int dim) , selvar() , qual() { - setupGenerator(&g, mc); - applySeed(&g, seed); - sha = getVoronoiSHA(seed); + setupGeneratorLargeBiomes(&g, wi.mc, wi.large); + applySeed(&g, wi.seed); + sha = getVoronoiSHA(wi.seed); activelv = 0; int pixs = 512; lvs.resize(D_SPAWN); - lvs[D_DESERT] .init4struct(mc, seed, 0, 2048, D_DESERT, 2); - lvs[D_JUNGLE] .init4struct(mc, seed, 0, 2048, D_JUNGLE, 2); - lvs[D_IGLOO] .init4struct(mc, seed, 0, 2048, D_IGLOO, 2); - lvs[D_HUT] .init4struct(mc, seed, 0, 2048, D_HUT, 2); - lvs[D_VILLAGE] .init4struct(mc, seed, 0, 2048, D_VILLAGE, 2); - lvs[D_MANSION] .init4struct(mc, seed, 0, 2048, D_MANSION, 3); - lvs[D_MONUMENT] .init4struct(mc, seed, 0, 2048, D_MONUMENT, 2); - lvs[D_RUINS] .init4struct(mc, seed, 0, 2048, D_RUINS, 1); - lvs[D_SHIPWRECK] .init4struct(mc, seed, 0, 2048, D_SHIPWRECK, 1); - 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, 2); - lvs[D_GATEWAY] .init4struct(mc, seed, 1, 2048, D_GATEWAY, 2); - lvs[D_MINESHAFT] .init4struct(mc, seed, 0, 2048, D_MINESHAFT, 1); + lvs[D_DESERT] .init4struct(wi, 0, 2048, D_DESERT, 2); + lvs[D_JUNGLE] .init4struct(wi, 0, 2048, D_JUNGLE, 2); + lvs[D_IGLOO] .init4struct(wi, 0, 2048, D_IGLOO, 2); + lvs[D_HUT] .init4struct(wi, 0, 2048, D_HUT, 2); + lvs[D_VILLAGE] .init4struct(wi, 0, 2048, D_VILLAGE, 2); + lvs[D_MANSION] .init4struct(wi, 0, 2048, D_MANSION, 3); + lvs[D_MONUMENT] .init4struct(wi, 0, 2048, D_MONUMENT, 2); + lvs[D_RUINS] .init4struct(wi, 0, 2048, D_RUINS, 1); + lvs[D_SHIPWRECK] .init4struct(wi, 0, 2048, D_SHIPWRECK, 1); + lvs[D_TREASURE] .init4struct(wi, 0, 2048, D_TREASURE, 1); + lvs[D_OUTPOST] .init4struct(wi, 0, 2048, D_OUTPOST, 2); + lvs[D_PORTAL] .init4struct(wi, 0, 2048, D_PORTAL, 1); + lvs[D_PORTALN] .init4struct(wi,-1, 2048, D_PORTALN, 1); + lvs[D_FORTESS] .init4struct(wi,-1, 2048, D_FORTESS, 1); + lvs[D_BASTION] .init4struct(wi,-1, 2048, D_BASTION, 1); + lvs[D_ENDCITY] .init4struct(wi, 1, 2048, D_ENDCITY, 2); + lvs[D_GATEWAY] .init4struct(wi, 1, 2048, D_GATEWAY, 2); + lvs[D_MINESHAFT] .init4struct(wi, 0, 2048, D_MINESHAFT, 1); if (dim == 0) { lvb.resize(5); - lvb[0].init4map(mc, seed, dim, pixs, 1); - lvb[1].init4map(mc, seed, dim, pixs, 4); - lvb[2].init4map(mc, seed, dim, pixs, 16); - lvb[3].init4map(mc, seed, dim, pixs, 64); - lvb[4].init4map(mc, seed, dim, pixs, 256); + lvb[0].init4map(wi, dim, pixs, 1); + lvb[1].init4map(wi, dim, pixs, 4); + lvb[2].init4map(wi, dim, pixs, 16); + lvb[3].init4map(wi, dim, pixs, 64); + lvb[4].init4map(wi, dim, pixs, 256); } else { lvb.resize(4); - lvb[0].init4map(mc, seed, dim, pixs, 1); - lvb[1].init4map(mc, seed, dim, pixs, 4); - lvb[2].init4map(mc, seed, dim, pixs, 16); - lvb[3].init4map(mc, seed, dim, pixs, 64); + lvb[0].init4map(wi, dim, pixs, 1); + lvb[1].init4map(wi, dim, pixs, 4); + lvb[2].init4map(wi, dim, pixs, 16); + lvb[3].init4map(wi, dim, pixs, 64); } cachesize = 100; qual = 1.0; @@ -525,19 +539,19 @@ void QWorld::setDim(int dim) if (dim == 0) { lvb.resize(5); - lvb[0].init4map(mc, seed, dim, pixs, 1); - lvb[1].init4map(mc, seed, dim, pixs, 4); - lvb[2].init4map(mc, seed, dim, pixs, 16); - lvb[3].init4map(mc, seed, dim, pixs, 64); - lvb[4].init4map(mc, seed, dim, pixs, 256); + lvb[0].init4map(wi, dim, pixs, 1); + lvb[1].init4map(wi, dim, pixs, 4); + lvb[2].init4map(wi, dim, pixs, 16); + lvb[3].init4map(wi, dim, pixs, 64); + lvb[4].init4map(wi, dim, pixs, 256); } else { lvb.resize(4); - lvb[0].init4map(mc, seed, dim, pixs, 1); - lvb[1].init4map(mc, seed, dim, pixs, 4); - lvb[2].init4map(mc, seed, dim, pixs, 16); - lvb[3].init4map(mc, seed, dim, pixs, 64); + lvb[0].init4map(wi, dim, pixs, 1); + lvb[1].init4map(wi, dim, pixs, 4); + lvb[2].init4map(wi, dim, pixs, 16); + lvb[3].init4map(wi, dim, pixs, 64); } } @@ -545,19 +559,19 @@ int QWorld::getBiome(Pos p) { if (dim == -1) { - if (mc < MC_1_16) + if (wi.mc < MC_1_16) return nether_wastes; NetherNoise nn; - setNetherSeed(&nn, seed); + setNetherSeed(&nn, wi.seed); voronoiAccess3D(sha, p.x, 0, p.z, &p.x, 0, &p.z); return getNetherBiome(&nn, p.x, 0, p.z, NULL); } else if (dim == 1) { - if (mc < MC_1_9) + if (wi.mc < MC_1_9) return the_end; int buf[49]; - genEndScaled(mc, seed, 1, buf, p.x, p.z, 1, 1); + genEndScaled(wi.mc, wi.seed, 1, buf, p.x, p.z, 1, 1); return buf[0]; } return getBiomeAtPos(&g, p); @@ -595,28 +609,27 @@ void QWorld::cleancache(std::vector& cache, unsigned int maxsize) struct SpawnStronghold : public QRunnable { QWorld *world; - int mc; - uint64_t seed; + WorldInfo wi; - SpawnStronghold(QWorld *world, int mc, uint64_t seed) : - world(world),mc(mc),seed(seed) {} + SpawnStronghold(QWorld *world, WorldInfo wi) : + world(world),wi(wi) {} void run() { LayerStack g; - setupGenerator(&g, mc); - applySeed(&g, seed); + setupGeneratorLargeBiomes(&g, wi.mc, wi.large); + applySeed(&g, wi.seed); Pos *p = new Pos; - *p = getSpawn(mc, &g, NULL, seed); + *p = getSpawn(wi.mc, &g, NULL, wi.seed); world->spawn = p; if (world->isdel) return; StrongholdIter sh; - initFirstStronghold(&sh, mc, seed); + initFirstStronghold(&sh, wi.mc, wi.seed); std::vector *shp = new std::vector; - shp->reserve(mc >= MC_1_9 ? 128 : 3); + shp->reserve(wi.mc >= MC_1_9 ? 128 : 3); while (nextStronghold(&sh, &g, NULL) > 0) { @@ -710,7 +723,7 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz, { for (int i = 0; i < w; i++) { - int isslime = isSlimeChunk(seed, i+x, j+z); + int isslime = isSlimeChunk(wi.seed, i+x, j+z); slimeimg.setPixel(i, j, isslime); } } @@ -847,7 +860,7 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz, if (spawn == NULL && (sshow[D_SPAWN] || sshow[D_STRONGHOLD])) { spawn = (Pos*) -1; - QThreadPool::globalInstance()->start(new SpawnStronghold(this, mc, seed)); + QThreadPool::globalInstance()->start(new SpawnStronghold(this, wi)); } if (seldo) diff --git a/src/quad.h b/src/quad.h index 7552c8c..3010d0d 100644 --- a/src/quad.h +++ b/src/quad.h @@ -1,6 +1,8 @@ #ifndef QUAD_H #define QUAD_H +#include "settings.h" + #include #include #include @@ -8,6 +10,7 @@ #include "cubiomes/finders.h" + enum { D_NONE = -1, // generics @@ -131,7 +134,7 @@ struct VarPos }; void getStructs(std::vector *out, const StructureConfig sconf, - int mc, int dim, uint64_t seed, int x0, int z0, int x1, int z1); + WorldInfo wi, int dim, int x0, int z0, int x1, int z1); class Quad : public QRunnable { @@ -141,8 +144,7 @@ public: void run(); - int mc; - uint64_t seed; + WorldInfo wi; int dim; const Layer *entry; int ti, tj; @@ -170,8 +172,8 @@ struct Level Level(); ~Level(); - 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 init4map(WorldInfo wi, int dim, int pix, int layerscale); + void init4struct(WorldInfo wi, 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); @@ -179,8 +181,7 @@ struct Level std::vector cells; LayerStack g; Layer *entry; - uint64_t seed; - int mc; + WorldInfo wi; int dim; int tx, tz, tw, th; int scale; @@ -193,7 +194,7 @@ struct Level struct QWorld { - QWorld(int mc, uint64_t seed, int dim = 0); + QWorld(WorldInfo wi, int dim = 0); ~QWorld(); void setDim(int dim); @@ -204,8 +205,7 @@ struct QWorld int getBiome(Pos p); - int mc; - uint64_t seed; + WorldInfo wi; int dim; LayerStack g; uint64_t sha; diff --git a/src/quadlistdialog.cpp b/src/quadlistdialog.cpp index 7fce0fe..52d299e 100644 --- a/src/quadlistdialog.cpp +++ b/src/quadlistdialog.cpp @@ -40,36 +40,40 @@ void QuadListDialog::loadSeed() ui->comboBoxMC->setCurrentText("1.17"); ui->lineSeed->clear(); - int mc; - uint64_t seed; - mainwindow->getSeed(&mc, &seed, false); + WorldInfo wi; + mainwindow->getSeed(&wi, false); - const char *mcstr = mc2str(mc); + const char *mcstr = mc2str(wi.mc); if (!mcstr) { - qDebug() << "Unknown MC version: " << mc; + qDebug() << "Unknown MC version: " << wi.mc; return; } ui->comboBoxMC->setCurrentText(mcstr); - ui->lineSeed->setText(QString::asprintf("%" PRId64, (int64_t)seed)); + ui->lineSeed->setText(QString::asprintf("%" PRId64, (int64_t)wi.seed)); } -bool QuadListDialog::getSeed(int *mc, uint64_t *seed) +bool QuadListDialog::getSeed(WorldInfo *wi) { + // init using mainwindow + bool ok = mainwindow->getSeed(wi, false); const std::string& mcs = ui->comboBoxMC->currentText().toStdString(); - *mc = str2mc(mcs.c_str()); - if (*mc < 0) + wi->mc = str2mc(mcs.c_str()); + if (wi->mc < 0) { - qDebug() << "Unknown MC version: " << *mc; - return false; + wi->mc = MC_NEWEST; + qDebug() << "Unknown MC version: " << wi->mc; + ok = false; } - int v = str2seed(ui->lineSeed->text(), seed); + int v = str2seed(ui->lineSeed->text(), &wi->seed); if (v == S_RANDOM) - ui->lineSeed->setText(QString::asprintf("%" PRId64, (int64_t)*seed)); + { + ui->lineSeed->setText(QString::asprintf("%" PRId64, (int64_t)wi->seed)); + } - return true; + return ok; } @@ -78,16 +82,15 @@ void QuadListDialog::refresh() ui->listQuadStruct->setRowCount(0); ui->labelMsg->clear(); - int mc; - uint64_t seed; - if (!getSeed(&mc, &seed)) + WorldInfo wi; + if (!getSeed(&wi)) return; LayerStack g; - setupGenerator(&g, mc); + setupGeneratorLargeBiomes(&g, wi.mc, wi.large); StructureConfig sconf; - getStructureConfig_override(Swamp_Hut, mc, &sconf); + getStructureConfig_override(Swamp_Hut, wi.mc, &sconf); const int maxq = 1000; Pos *qlist = new Pos[maxq]; @@ -95,7 +98,7 @@ void QuadListDialog::refresh() int qcnt; qcnt = scanForQuads( - sconf, 128, (seed) & MASK48, + sconf, 128, (wi.seed) & MASK48, low20QuadHutBarely, sizeof(low20QuadHutBarely) / sizeof(uint64_t), 20, sconf.salt, -r, -r, 2*r, 2*r, qlist, maxq); @@ -107,20 +110,19 @@ void QuadListDialog::refresh() for (int i = 0; i < qcnt; i++) { Pos qh[4]; - getStructurePos(sconf.structType, mc, seed, qlist[i].x+0, qlist[i].z+0, qh+0); - getStructurePos(sconf.structType, mc, seed, qlist[i].x+0, qlist[i].z+1, qh+1); - getStructurePos(sconf.structType, mc, seed, qlist[i].x+1, qlist[i].z+0, qh+2); - getStructurePos(sconf.structType, mc, seed, qlist[i].x+1, qlist[i].z+1, qh+3); - - if (isViableStructurePos(sconf.structType, mc, &g, seed, qh[0].x, qh[0].z) && - isViableStructurePos(sconf.structType, mc, &g, seed, qh[1].x, qh[1].z) && - isViableStructurePos(sconf.structType, mc, &g, seed, qh[2].x, qh[2].z) && - isViableStructurePos(sconf.structType, mc, &g, seed, qh[3].x, qh[3].z)) + getStructurePos(sconf.structType, wi.mc, wi.seed, qlist[i].x+0, qlist[i].z+0, qh+0); + getStructurePos(sconf.structType, wi.mc, wi.seed, qlist[i].x+0, qlist[i].z+1, qh+1); + getStructurePos(sconf.structType, wi.mc, wi.seed, qlist[i].x+1, qlist[i].z+0, qh+2); + getStructurePos(sconf.structType, wi.mc, wi.seed, qlist[i].x+1, qlist[i].z+1, qh+3); + if (isViableStructurePos(sconf.structType, wi.mc, &g, wi.seed, qh[0].x, qh[0].z) && + isViableStructurePos(sconf.structType, wi.mc, &g, wi.seed, qh[1].x, qh[1].z) && + isViableStructurePos(sconf.structType, wi.mc, &g, wi.seed, qh[2].x, qh[2].z) && + isViableStructurePos(sconf.structType, wi.mc, &g, wi.seed, qh[3].x, qh[3].z)) { ui->listQuadStruct->insertRow(row); Pos afk; afk = getOptimalAfk(qh, 7,7,9, 0); - float rad = isQuadBase(sconf, moveStructure(seed, -qlist[i].x, -qlist[i].z), 128); + float rad = isQuadBase(sconf, moveStructure(wi.seed, -qlist[i].x, -qlist[i].z), 128); int dist = (int) round(sqrt(afk.x * (qreal)afk.x + afk.z * (qreal)afk.z)); QVariant var = QVariant::fromValue(afk); @@ -147,13 +149,13 @@ void QuadListDialog::refresh() } qhn = row; - if (mc >= MC_1_8) + if (wi.mc >= MC_1_8) { - getStructureConfig_override(Monument, mc, &sconf); + getStructureConfig_override(Monument, wi.mc, &sconf); // TODO: check salt delta uint64_t salt_delta = sconf.salt - MONUMENT_CONFIG.salt; qcnt = scanForQuads( - sconf, 160, seed & MASK48, + sconf, 160, wi.seed & MASK48, g_qm_90, sizeof(g_qm_90) / sizeof(uint64_t), 48, salt_delta, -r, -r, 2*r, 2*r, qlist, maxq); @@ -163,20 +165,20 @@ void QuadListDialog::refresh() for (int i = 0; i < qcnt; i++) { Pos qm[4]; - getStructurePos(sconf.structType, mc, seed, qlist[i].x+0, qlist[i].z+0, qm+0); - getStructurePos(sconf.structType, mc, seed, qlist[i].x+0, qlist[i].z+1, qm+1); - getStructurePos(sconf.structType, mc, seed, qlist[i].x+1, qlist[i].z+0, qm+2); - getStructurePos(sconf.structType, mc, seed, qlist[i].x+1, qlist[i].z+1, qm+3); - if (isViableStructurePos(sconf.structType, mc, &g, seed, qm[0].x, qm[0].z) && - isViableStructurePos(sconf.structType, mc, &g, seed, qm[1].x, qm[1].z) && - isViableStructurePos(sconf.structType, mc, &g, seed, qm[2].x, qm[2].z) && - isViableStructurePos(sconf.structType, mc, &g, seed, qm[3].x, qm[3].z)) + getStructurePos(sconf.structType, wi.mc, wi.seed, qlist[i].x+0, qlist[i].z+0, qm+0); + getStructurePos(sconf.structType, wi.mc, wi.seed, qlist[i].x+0, qlist[i].z+1, qm+1); + getStructurePos(sconf.structType, wi.mc, wi.seed, qlist[i].x+1, qlist[i].z+0, qm+2); + getStructurePos(sconf.structType, wi.mc, wi.seed, qlist[i].x+1, qlist[i].z+1, qm+3); + if (isViableStructurePos(sconf.structType, wi.mc, &g, wi.seed, qm[0].x, qm[0].z) && + isViableStructurePos(sconf.structType, wi.mc, &g, wi.seed, qm[1].x, qm[1].z) && + isViableStructurePos(sconf.structType, wi.mc, &g, wi.seed, qm[2].x, qm[2].z) && + isViableStructurePos(sconf.structType, wi.mc, &g, wi.seed, qm[3].x, qm[3].z)) { ui->listQuadStruct->insertRow(row); Pos afk; afk = getOptimalAfk(qm, 58,23,58, 0); afk.x -= 29; afk.z -= 29; // monuments position is centered - float rad = isQuadBase(sconf, moveStructure(seed, -qlist[i].x, -qlist[i].z), 160); + float rad = isQuadBase(sconf, moveStructure(wi.seed, -qlist[i].x, -qlist[i].z), 160); int dist = (int) round(sqrt(afk.x * (qreal)afk.x + afk.z * (qreal)afk.z)); QVariant var = QVariant::fromValue(afk); @@ -238,16 +240,15 @@ void QuadListDialog::gotoSwampHut() if (!item) return; - int mc; - uint64_t seed; - if (!getSeed(&mc, &seed)) + WorldInfo wi; + if (!getSeed(&wi)) return; QVariant dat = item->data(Qt::UserRole); if (dat.isValid()) { Pos p = qvariant_cast(dat); - mainwindow->setSeed(mc, seed); + mainwindow->setSeed(wi); mapView->setView(p.x+0.5, p.z+0.5); } } diff --git a/src/quadlistdialog.h b/src/quadlistdialog.h index 864fdb1..2c137e4 100644 --- a/src/quadlistdialog.h +++ b/src/quadlistdialog.h @@ -1,8 +1,11 @@ #ifndef QUADLISTDIALOG_H #define QUADLISTDIALOG_H +#include "settings.h" + #include + class MainWindow; namespace Ui { @@ -20,7 +23,7 @@ public: void loadSeed(); void refresh(); - bool getSeed(int *mc, uint64_t *seed); + bool getSeed(WorldInfo *wi); private slots: void on_buttonGo_clicked(); diff --git a/src/quadlistdialog.ui b/src/quadlistdialog.ui index 8f489ec..8721d02 100644 --- a/src/quadlistdialog.ui +++ b/src/quadlistdialog.ui @@ -117,6 +117,30 @@ + + + + press enter to accept + + + + + + + Minecraft version + + + MC + + + + + + + Go + + + @@ -190,30 +214,6 @@ - - - - press enter to accept - - - - - - - Minecraft version - - - MC - - - - - - - Go - - - diff --git a/src/search.cpp b/src/search.cpp index c04fb39..62593ad 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -179,7 +179,6 @@ L_qm_any: case F_RUINS: case F_SHIPWRECK: case F_TREASURE: - case F_MINESHAFT: case F_PORTAL: case F_PORTALN: @@ -281,6 +280,37 @@ L_qm_any: } return 0; + case F_MINESHAFT: + x1 = cond->x1; + z1 = cond->z1; + x2 = cond->x2; + z2 = cond->z2; + if (cond->relative) + { + x1 += spos[cond->relative].cx; + z1 += spos[cond->relative].cz; + x2 += spos[cond->relative].cx; + z2 += spos[cond->relative].cz; + } + rx1 = x1 >> 4; + rz1 = z1 >> 4; + rx2 = x2 >> 4; + rz2 = z2 >> 4; + qual = getMineshafts(mc, seed, rx1, rz1, rx2, rz2, p, 128); + if (qual >= cond->count) + { + xt = zt = 0; + for (int i = 0; i < qual; i++) + { + xt += p[i].x; + zt += p[i].z; + } + sout->sconf = sconf; + sout->cx = xt / qual; + sout->cz = zt / qual; + return 1; + } + return 0; case F_SPAWN: // TODO: warn if spawn is used for relative positioning diff --git a/src/searchitem.cpp b/src/searchitem.cpp index 3a8f0fe..dc4b008 100644 --- a/src/searchitem.cpp +++ b/src/searchitem.cpp @@ -21,7 +21,7 @@ SearchItem::~SearchItem() void SearchItem::run() { LayerStack g; - setupGenerator(&g, mc); + setupGeneratorLargeBiomes(&g, mc, large); StructPos spos[100] = {}; QVector matches; @@ -127,13 +127,14 @@ void SearchItem::run() void SearchItemGenerator::init( - QObject *mainwin, int mc, + QObject *mainwin, WorldInfo wi, const SearchConfig& sc, const Gen48Settings& gen48, const Config& config, const std::vector& slist, const QVector& cv) { this->mainwin = mainwin; this->searchtype = sc.searchtype; - this->mc = mc; + this->mc = wi.mc; + this->large = wi.large; this->condvec = cv; this->itemid = 0; this->itemsiz = config.seedsPerItem; @@ -436,6 +437,7 @@ SearchItem *SearchItemGenerator::requestItem() item->searchtype = searchtype; item->mc = mc; + item->large = large; item->cond = condvec.data(); item->ccnt = condvec.size(); item->itemid = itemid++; diff --git a/src/searchitem.h b/src/searchitem.h index 1f3c5c0..1ba5514 100644 --- a/src/searchitem.h +++ b/src/searchitem.h @@ -52,6 +52,7 @@ signals: public: int searchtype; int mc; + int large; const Condition * cond; int ccnt; uint64_t itemid; // item identifier @@ -72,7 +73,7 @@ public: struct SearchItemGenerator { void init( - QObject *mainwin, int mc, + QObject *mainwin, WorldInfo wi, const SearchConfig& sc, const Gen48Settings& gen48, const Config& config, const std::vector& slist, const QVector& cv); @@ -84,6 +85,7 @@ struct SearchItemGenerator QObject * mainwin; int searchtype; int mc; + int large; QVector condvec; uint64_t itemid; // item incrementor int itemsiz; // number of seeds per search item diff --git a/src/searchthread.cpp b/src/searchthread.cpp index 976d6b4..98e792e 100644 --- a/src/searchthread.cpp +++ b/src/searchthread.cpp @@ -23,7 +23,7 @@ SearchThread::SearchThread(FormSearchControl *parent) } bool SearchThread::set( - QObject *mainwin, int mc, + QObject *mainwin, WorldInfo wi, const SearchConfig& sc, const Gen48Settings& gen48, const Config& config, std::vector& slist, const QVector& cv) /* @@ -58,7 +58,7 @@ bool SearchThread::set( QMessageBox::warning(NULL, "Error", QString::asprintf("Encountered invalid filter type %d in condition ID [%02d].", c.type, c.save)); return false; } - if (mc < g_filterinfo.list[c.type].mcmin) + if (wi.mc < g_filterinfo.list[c.type].mcmin) { const char *mcs = mc2str(g_filterinfo.list[c.type].mcmin); QString s = QString::asprintf("Condition [%02d] requires a minimum Minecraft version of %s.", c.save, mcs); @@ -93,7 +93,7 @@ bool SearchThread::set( } } - itemgen.init(mainwin, mc, sc, gen48, config, slist, cv); + itemgen.init(mainwin, wi, sc, gen48, config, slist, cv); pool.setMaxThreadCount(sc.threads); recieved.resize(config.queueSize); diff --git a/src/searchthread.h b/src/searchthread.h index 555d3ae..d5c3ae4 100644 --- a/src/searchthread.h +++ b/src/searchthread.h @@ -24,7 +24,7 @@ public: SearchThread(FormSearchControl *parent); - bool set(QObject *mainwin, int mc, + bool set(QObject *mainwin, WorldInfo wi, const SearchConfig& sc, const Gen48Settings& gen48, const Config& config, std::vector& slist, const QVector& cv); diff --git a/src/settings.h b/src/settings.h index 93036bd..8b1220b 100644 --- a/src/settings.h +++ b/src/settings.h @@ -1,8 +1,51 @@ #ifndef SETTINGS_H #define SETTINGS_H +#include "cubiomes/finders.h" + #include +#include + + +struct ExtGenSettings +{ + bool largeBiomes; + bool saltOverride; + uint64_t salts[FEATURE_NUM]; + + ExtGenSettings() { reset(); } + + void reset() + { + largeBiomes = false; + saltOverride = false; + for (int i = 0; i < FEATURE_NUM; i++) + salts[i] = ~(uint64_t)0; + } +}; + +struct WorldInfo +{ + int mc; + bool large; + uint64_t seed; + + WorldInfo() { reset(); } + + bool equals(const WorldInfo& wi) const + { + return mc == wi.mc && large == wi.large && seed == wi.seed; + } + + void reset() + { + mc = MC_NEWEST; + large = false; + seed = 0; + } +}; + enum { STYLE_SYSTEM, STYLE_DARK }; struct Config @@ -22,7 +65,7 @@ struct Config smoothMotion = true; restoreSession = true; autosaveCycle = 10; - uistyle = STYLE_DARK; + uistyle = STYLE_SYSTEM; seedsPerItem = 256; queueSize = QThread::idealThreadCount(); maxMatching = 65536;