Large biomes and custom salts

This commit is contained in:
Cubitect 2021-07-18 15:35:22 +02:00
parent b70157df0a
commit 103351dfe1
25 changed files with 657 additions and 258 deletions

@ -1 +1 @@
Subproject commit 3b65b4bbf70b1e590edce06c34504632e7b08e5a
Subproject commit 61a341e1f695ec10d1ec836618275e871c69df4e

View File

@ -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 \

View File

@ -4,8 +4,8 @@
#include <QDialog>
#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)

View File

@ -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";

129
src/extgendialog.cpp Normal file
View File

@ -0,0 +1,129 @@
#include "extgendialog.h"
#include "ui_extgendialog.h"
#include "cutil.h"
#include <QGridLayout>
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());
}
}

42
src/extgendialog.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef EXTGENDIALOG_H
#define EXTGENDIALOG_H
#include <QDialog>
#include <QAbstractButton>
#include <QCheckBox>
#include <QLineEdit>
#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

85
src/extgendialog.ui Normal file
View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ExtGenDialog</class>
<widget class="QDialog" name="ExtGenDialog">
<property name="windowTitle">
<string>World Settings (experimental)</string>
</property>
<property name="windowIcon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/map.png</normaloff>:/icons/map.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupSalts">
<property name="title">
<string>Override structure salt</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="checkLarge">
<property name="toolTip">
<string>Simulate innertia for the map view</string>
</property>
<property name="text">
<string>Large biomes</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../icons.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ExtGenDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ExtGenDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -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();
}

View File

@ -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<Condition>& 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)

View File

@ -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 <QDebug>
#include <QFile>
// 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<Condition> condvec = formCond->getConditions();
QVector<uint64_t> 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<Pos> shp;
while (nextStronghold(&sh, &g, NULL) > 0)
{

View File

@ -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);

View File

@ -643,6 +643,7 @@ QToolButton:checked {
<addaction name="separator"/>
<addaction name="actionAddShadow"/>
<addaction name="separator"/>
<addaction name="actionExtGen"/>
<addaction name="actionPreferences"/>
</widget>
<addaction name="menuFile"/>
@ -718,6 +719,11 @@ QToolButton:checked {
<string>Add shadow for all seeds</string>
</property>
</action>
<action name="actionExtGen">
<property name="text">
<string>World settings...</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -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)
{

View File

@ -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; }

View File

@ -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<VarPos> *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<VarPos> *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<VarPos> *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<VarPos> *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<VarPos>* st = new std::vector<VarPos>();
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<Quad*>& 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<Quad*>& 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<Pos> *shp = new std::vector<Pos>;
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)

View File

@ -1,6 +1,8 @@
#ifndef QUAD_H
#define QUAD_H
#include "settings.h"
#include <QRunnable>
#include <QImage>
#include <QPainter>
@ -8,6 +10,7 @@
#include "cubiomes/finders.h"
enum {
D_NONE = -1,
// generics
@ -131,7 +134,7 @@ struct VarPos
};
void getStructs(std::vector<VarPos> *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<Quad*>& cache, int x, int z, int w, int h);
void update(std::vector<Quad*>& cache, qreal bx0, qreal bz0, qreal bx1, qreal bz1);
@ -179,8 +181,7 @@ struct Level
std::vector<Quad*> 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;

View File

@ -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<Pos>(dat);
mainwindow->setSeed(mc, seed);
mainwindow->setSeed(wi);
mapView->setView(p.x+0.5, p.z+0.5);
}
}

View File

@ -1,8 +1,11 @@
#ifndef QUADLISTDIALOG_H
#define QUADLISTDIALOG_H
#include "settings.h"
#include <QDialog>
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();

View File

@ -117,6 +117,30 @@
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="lineSeed">
<property name="toolTip">
<string>press enter to accept</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labeMC">
<property name="toolTip">
<string>Minecraft version</string>
</property>
<property name="text">
<string>MC</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="buttonGo">
<property name="text">
<string>Go</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxMC">
<property name="toolTip">
@ -190,30 +214,6 @@
</item>
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="lineSeed">
<property name="toolTip">
<string>press enter to accept</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labeMC">
<property name="toolTip">
<string>Minecraft version</string>
</property>
<property name="text">
<string>MC</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="buttonGo">
<property name="text">
<string>Go</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0" alignment="Qt::AlignRight">

View File

@ -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

View File

@ -21,7 +21,7 @@ SearchItem::~SearchItem()
void SearchItem::run()
{
LayerStack g;
setupGenerator(&g, mc);
setupGeneratorLargeBiomes(&g, mc, large);
StructPos spos[100] = {};
QVector<uint64_t> 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<uint64_t>& slist, const QVector<Condition>& 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++;

View File

@ -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<uint64_t>& slist, const QVector<Condition>& cv);
@ -84,6 +85,7 @@ struct SearchItemGenerator
QObject * mainwin;
int searchtype;
int mc;
int large;
QVector<Condition> condvec;
uint64_t itemid; // item incrementor
int itemsiz; // number of seeds per search item

View File

@ -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<uint64_t>& slist, const QVector<Condition>& 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);

View File

@ -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<uint64_t>& slist, const QVector<Condition>& cv);

View File

@ -1,8 +1,51 @@
#ifndef SETTINGS_H
#define SETTINGS_H
#include "cubiomes/finders.h"
#include <QThread>
#include <vector>
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;