mirror of
https://github.com/Cubitect/cubiomes-viewer.git
synced 2025-01-08 11:57:50 +08:00
Some changes for v4.0.0 (locations finder + biome sampling + area input change)
* added biome samples filter to check biome proportions (#173, #266) * added outline display for the area of selected conditions (WIP) * added "from-visible" to conditions editor (#271) * added Locations to Search tab, to look for positions in the current seed * moved Tiggers to Search tab * changed area/position input fields to use block coordinates (#265) * changed spiral iterator to use an arbitrary, user defined step size * fixed octave options and added generated display texts (#253)
This commit is contained in:
parent
08f04345e8
commit
01fa7069b3
@ -1,7 +1,7 @@
|
||||
# Cubiomes Viewer Build Instructions
|
||||
|
||||
Cubiomes Viewer is a Qt5 application and requires:
|
||||
* Qt5.9 or newer (Qt6 is not supported) and a
|
||||
* Qt5.9 or newer (Qt6 might work, but isn't currently supported) and a
|
||||
* GNU C++ compiler (GCC or Clang).
|
||||
|
||||
The cubiomes library is included as a submodule to this repository.
|
||||
|
2
cubiomes
2
cubiomes
@ -1 +1 @@
|
||||
Subproject commit 6b36603d2dc31f6ef8a3d4746c9b64ad3ace0a00
|
||||
Subproject commit c3ff21a1a8b6bf362221db3f4dee71a0dc7dba9b
|
@ -32,6 +32,10 @@ win32: {
|
||||
static_gnu: {
|
||||
LIBS += -static -static-libgcc -static-libstdc++
|
||||
}
|
||||
sanitizer: {
|
||||
QMAKE_CFLAGS += -fsanitize=undefined
|
||||
LIBS += -lubsan -ldl
|
||||
}
|
||||
|
||||
gcc {
|
||||
greaterThan(QMAKE_GCC_MAJOR_VERSION, 9): QMAKE_CXXFLAGS += -Wno-deprecated-copy
|
||||
@ -39,10 +43,6 @@ gcc {
|
||||
|
||||
CONFIG(debug, debug|release): {
|
||||
CUTARGET = debug
|
||||
!win32 {
|
||||
QMAKE_CFLAGS += -fsanitize=undefined
|
||||
LIBS += -lubsan -ldl
|
||||
}
|
||||
} else {
|
||||
CUTARGET = release
|
||||
}
|
||||
@ -115,6 +115,7 @@ SOURCES += \
|
||||
src/search.cpp \
|
||||
src/searchthread.cpp \
|
||||
src/tabbiomes.cpp \
|
||||
src/tablocations.cpp \
|
||||
src/tabstructures.cpp \
|
||||
src/tabtriggers.cpp \
|
||||
src/mainwindow.cpp \
|
||||
@ -182,6 +183,7 @@ HEADERS += \
|
||||
src/searchthread.h \
|
||||
src/seedtables.h \
|
||||
src/tabbiomes.h \
|
||||
src/tablocations.h \
|
||||
src/tabstructures.h \
|
||||
src/tabtriggers.h \
|
||||
src/mainwindow.h \
|
||||
@ -206,6 +208,7 @@ FORMS += \
|
||||
src/mainwindow.ui \
|
||||
src/rangedialog.ui \
|
||||
src/tabbiomes.ui \
|
||||
src/tablocations.ui \
|
||||
src/tabstructures.ui \
|
||||
src/tabtriggers.ui
|
||||
|
||||
|
@ -9,11 +9,11 @@
|
||||
<name>Cubiomes Viewer</name>
|
||||
<summary>An efficient Minecraft seed finder and map viewer.</summary>
|
||||
<description>
|
||||
<p>Cubiomes Viewer offers highly customizable seed-finding utilities and a map viewer for the biome and structure generation of Minecraft Java Edition for the main releases up to 1.19.</p>
|
||||
<p>Cubiomes Viewer offers highly customizable seed-finding utilities and a map viewer for the biome and structure generation of Minecraft Java Edition for the main releases up to 1.21.</p>
|
||||
</description>
|
||||
|
||||
<releases>
|
||||
<release version="3.4.2" date="2024-01-02">
|
||||
<release version="4.0.dev0" date="2024-01.??">
|
||||
</release>
|
||||
</releases>
|
||||
|
||||
|
@ -2116,7 +2116,7 @@ https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsplitter
|
||||
|
||||
--------------------------------------------------------------------------- */
|
||||
QSplitter {
|
||||
background-color: #455364;
|
||||
background-color: #19232D; /*#455364;*/
|
||||
spacing: 0px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
|
@ -4,9 +4,9 @@
|
||||
#include <QDialog>
|
||||
#include <QString>
|
||||
|
||||
#define VERS_MAJOR 3
|
||||
#define VERS_MINOR 4
|
||||
#define VERS_PATCH 2 // negative patch number designates a development version
|
||||
#define VERS_MAJOR 4
|
||||
#define VERS_MINOR 0
|
||||
#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)
|
||||
|
@ -21,29 +21,16 @@
|
||||
#include <QFontMetricsF>
|
||||
|
||||
|
||||
static QString getTip(int mc, int layer, uint32_t flags, int id)
|
||||
{
|
||||
uint64_t mL = 0, mM = 0;
|
||||
genPotential(&mL, &mM, layer, mc, flags, id);
|
||||
QString tip = ConditionDialog::tr("Generates any of:");
|
||||
for (int j = 0; j < 64; j++)
|
||||
if (mL & (1ULL << j))
|
||||
tip += QString("\n") + getBiomeDisplay(mc, j);
|
||||
for (int j = 0; j < 64; j++)
|
||||
if (mM & (1ULL << j))
|
||||
tip += QString("\n") + getBiomeDisplay(mc, 128+j);
|
||||
return tip;
|
||||
}
|
||||
|
||||
#define WARNING_CHAR QChar(0x26A0)
|
||||
|
||||
ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcversion, QListWidgetItem *item, Condition *initcond)
|
||||
ConditionDialog::ConditionDialog(FormConditions *parent, MapView *mapview, Config *config, WorldInfo wi, QListWidgetItem *item, Condition *initcond)
|
||||
: QDialog(parent, Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint)
|
||||
, ui(new Ui::ConditionDialog)
|
||||
, luahash()
|
||||
, mapview(mapview)
|
||||
, config(config)
|
||||
, item(item)
|
||||
, mc(mcversion)
|
||||
, wi(wi)
|
||||
{
|
||||
memset(&cond, 0, sizeof(cond));
|
||||
ui->setupUi(this);
|
||||
@ -55,7 +42,7 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
|
||||
textDescription->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
|
||||
ui->collapseDescription->init(tr("Description/Notes"), textDescription, true);
|
||||
|
||||
const char *p_mcs = mc2str(mc);
|
||||
const char *p_mcs = mc2str(wi.mc);
|
||||
QString mcs = tr("MC %1", "Minecraft version").arg(p_mcs ? p_mcs : "?");
|
||||
ui->labelMC->setText(mcs);
|
||||
|
||||
@ -86,20 +73,20 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
|
||||
if (c.save == initcond->save)
|
||||
continue;
|
||||
if (c.save == initcond->relative)
|
||||
initindex = ui->comboBoxRelative->count();
|
||||
initindex = ui->comboRelative->count();
|
||||
}
|
||||
QString condstr = c.summary(false).simplified();
|
||||
ui->comboBoxRelative->addItem(condstr, c.save);
|
||||
ui->comboRelative->addItem(condstr, c.save);
|
||||
}
|
||||
if (initindex < 0)
|
||||
{
|
||||
if (initcond && initcond->relative > 0)
|
||||
{
|
||||
initindex = ui->comboBoxRelative->count();
|
||||
initindex = ui->comboRelative->count();
|
||||
QString condstr = QString("[%1] %2 broken reference")
|
||||
.arg(initcond->relative, 2, 10, QChar('0'))
|
||||
.arg(WARNING_CHAR);
|
||||
ui->comboBoxRelative->addItem(condstr, initcond->relative);
|
||||
ui->comboRelative->addItem(condstr, initcond->relative);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -117,6 +104,8 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
|
||||
ui->lineSquare->setValidator(uintval);
|
||||
ui->lineRadius->setValidator(uintval);
|
||||
|
||||
ui->lineSpiralStep->setValidator(new QIntValidator(1, 0xffff, this));
|
||||
|
||||
ui->lineBiomeSize->setValidator(new QIntValidator(1, INT_MAX, this));
|
||||
ui->lineTolerance->setValidator(new QIntValidator(0, 255, this));
|
||||
|
||||
@ -125,28 +114,31 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
|
||||
ui->lineMin->setValidator(new QDoubleValidator(-1e6, 1e6, 4, this));
|
||||
ui->lineMax->setValidator(new QDoubleValidator(-1e6, 1e6, 4, this));
|
||||
|
||||
ui->comboBoxCat->setItemDelegate(new ComboBoxDelegate(this, ui->comboBoxCat));
|
||||
ui->comboBoxType->setItemDelegate(new ComboBoxDelegate(this, ui->comboBoxType));
|
||||
ui->lineCoverage->setValidator(new QDoubleValidator(0.0001, 100.0000, 4, this));
|
||||
ui->lineConfidence->setValidator(new QDoubleValidator(0.0001, 99.9999, 4, this));
|
||||
|
||||
//qobject_cast<QListView*>(ui->comboBoxCat->view())->setSpacing(1);
|
||||
//qobject_cast<QListView*>(ui->comboBoxType->view())->setSpacing(1);
|
||||
ui->comboCat->setItemDelegate(new ComboBoxDelegate(this, ui->comboCat));
|
||||
ui->comboType->setItemDelegate(new ComboBoxDelegate(this, ui->comboType));
|
||||
|
||||
ui->comboBoxCat->addItem(tr("Select category"));
|
||||
ui->comboBoxCat->insertSeparator(1);
|
||||
ui->comboBoxCat->addItem(getPix("helper"), tr("Algorithm helpers"), CAT_HELPER);
|
||||
ui->comboBoxCat->addItem(getPix("quad"), tr("Quad-structure"), CAT_QUAD);
|
||||
ui->comboBoxCat->addItem(getPix("stronghold"), tr("Structures"), CAT_STRUCT);
|
||||
ui->comboBoxCat->addItem(getPix("overworld"), tr("Biomes"), CAT_BIOMES);
|
||||
ui->comboBoxCat->addItem(getPix("nether"), tr("Nether biomes"), CAT_NETHER);
|
||||
ui->comboBoxCat->addItem(getPix("the_end"), tr("End biomes"), CAT_END);
|
||||
ui->comboBoxCat->addItem(getPix("slime"), tr("Other"), CAT_OTHER);
|
||||
int fmh = ui->comboBoxCat->fontMetrics().height() + 8;
|
||||
ui->comboBoxCat->setIconSize(QSize(fmh, fmh));
|
||||
ui->comboBoxType->setIconSize(QSize(fmh, fmh));
|
||||
//qobject_cast<QListView*>(ui->comboCat->view())->setSpacing(1);
|
||||
//qobject_cast<QListView*>(ui->comboType->view())->setSpacing(1);
|
||||
|
||||
ui->comboCat->addItem(tr("Select category"));
|
||||
ui->comboCat->insertSeparator(1);
|
||||
ui->comboCat->addItem(getPix("helper"), tr("Algorithm helpers"), CAT_HELPER);
|
||||
ui->comboCat->addItem(getPix("quad"), tr("Quad-structure"), CAT_QUAD);
|
||||
ui->comboCat->addItem(getPix("stronghold"), tr("Structures"), CAT_STRUCT);
|
||||
ui->comboCat->addItem(getPix("overworld"), tr("Biomes"), CAT_BIOMES);
|
||||
ui->comboCat->addItem(getPix("nether"), tr("Nether biomes"), CAT_NETHER);
|
||||
ui->comboCat->addItem(getPix("the_end"), tr("End biomes"), CAT_END);
|
||||
ui->comboCat->addItem(getPix("slime"), tr("Other"), CAT_OTHER);
|
||||
int fmh = ui->comboCat->fontMetrics().height() + 8;
|
||||
ui->comboCat->setIconSize(QSize(fmh, fmh));
|
||||
ui->comboType->setIconSize(QSize(fmh, fmh));
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
QString bname = getBiomeDisplay(mc, i);
|
||||
QString bname = getBiomeDisplay(wi.mc, i);
|
||||
if (bname.isEmpty())
|
||||
continue;
|
||||
QCheckBox *cb = new QCheckBox(bname);
|
||||
@ -214,7 +206,7 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
|
||||
if (i == NP_DEPTH)
|
||||
{
|
||||
LabeledRange *lr;
|
||||
if (mc <= MC_1_17)
|
||||
if (wi.mc <= MC_1_17)
|
||||
lr = new LabeledRange(this, 0, 256);
|
||||
else
|
||||
lr = new LabeledRange(this, -64, 320);
|
||||
@ -253,15 +245,15 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
|
||||
std::vector<int> ids;
|
||||
for (int id = 0; id < 256; id++)
|
||||
ids.push_back(id);
|
||||
IdCmp cmp(IdCmp::SORT_LEX, mc, DIM_UNDEF);
|
||||
IdCmp cmp(IdCmp::SORT_LEX, wi.mc, DIM_UNDEF);
|
||||
std::sort(ids.begin(), ids.end(), cmp);
|
||||
|
||||
for (int id : ids)
|
||||
{
|
||||
const int *lim = getBiomeParaLimits(mc, id);
|
||||
const int *lim = getBiomeParaLimits(wi.mc, id);
|
||||
if (!lim)
|
||||
continue;
|
||||
NoiseBiomeIndicator *cb = new NoiseBiomeIndicator(getBiomeDisplay(mc, id), this);
|
||||
NoiseBiomeIndicator *cb = new NoiseBiomeIndicator(getBiomeDisplay(wi.mc, id), this);
|
||||
QString tip = "<pre>";
|
||||
for (int j = 0; j < NP_MAX; j++)
|
||||
{
|
||||
@ -310,6 +302,8 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
|
||||
ui->checkSkipRef->setChecked(false);
|
||||
ui->radioSquare->setChecked(true);
|
||||
ui->checkRadius->setChecked(false);
|
||||
ui->lineCoverage->setText("100");
|
||||
ui->lineConfidence->setText("95");
|
||||
onCheckStartChanged(false);
|
||||
on_comboClimatePara_currentIndexChanged(0);
|
||||
|
||||
@ -328,22 +322,25 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
|
||||
ui->comboLua->setCurrentIndex(-1); // force index change
|
||||
ui->comboLua->setCurrentIndex(ui->comboLua->findData(QVariant::fromValue(cond.hash)));
|
||||
|
||||
ui->comboBoxCat->setCurrentIndex(ui->comboBoxCat->findData(ft.cat));
|
||||
for (int i = 0; i < ui->comboBoxType->count(); i++)
|
||||
ui->comboCat->setCurrentIndex(ui->comboCat->findData(ft.cat));
|
||||
for (int i = 0; i < ui->comboType->count(); i++)
|
||||
{
|
||||
int type = ui->comboBoxType->itemData(i, Qt::UserRole).toInt();
|
||||
int type = ui->comboType->itemData(i, Qt::UserRole).toInt();
|
||||
if (type == cond.type)
|
||||
{
|
||||
ui->comboBoxType->setCurrentIndex(i);
|
||||
ui->comboType->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ui->comboBoxRelative->setCurrentIndex(initindex);
|
||||
on_comboBoxRelative_activated(initindex);
|
||||
ui->comboRelative->setCurrentIndex(initindex);
|
||||
on_comboRelative_activated(initindex);
|
||||
ui->textEditLua->document()->setModified(false);
|
||||
|
||||
ui->comboMatchBiome->insertItem(0, getBiomeDisplay(mc, cond.biomeId), QVariant::fromValue(cond.biomeId));
|
||||
if (cond.step)
|
||||
ui->lineSpiralStep->setText(QString::number(cond.step));
|
||||
|
||||
ui->comboMatchBiome->insertItem(0, getBiomeDisplay(wi.mc, cond.biomeId), QVariant::fromValue(cond.biomeId));
|
||||
ui->comboMatchBiome->setCurrentIndex(0);
|
||||
|
||||
ui->comboClimatePara->setCurrentIndex(ui->comboClimatePara->findData(QVariant::fromValue(cond.para)));
|
||||
@ -364,6 +361,10 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
|
||||
|
||||
ui->checkApprox->setChecked(cond.flags & Condition::FLG_APPROX);
|
||||
ui->checkMatchAny->setChecked(cond.flags & Condition::FLG_MATCH_ANY);
|
||||
ui->lineCoverage->setText(QString::number(cond.converage ? cond.converage * 100 : 100));
|
||||
ui->lineConfidence->setText(QString::number(cond.confidence ? cond.confidence * 100 : 95));
|
||||
ui->checkSamplePos->setChecked(cond.count == 1);
|
||||
|
||||
int i, n = ui->comboY->count();
|
||||
for (i = 0; i < n; i++)
|
||||
if (ui->comboY->itemText(i).section(' ', 0, 0).toInt() == cond.y)
|
||||
@ -475,26 +476,40 @@ void ConditionDialog::addTempCat(int temp, QString name)
|
||||
int r = temp % Special;
|
||||
ui->gridLayoutTemps->addWidget(tempsboxes[temp], r, c * 2 + 0);
|
||||
ui->gridLayoutTemps->addWidget(l, r, c * 2 + 1);
|
||||
if (mc > MC_1_6 && mc <= MC_1_17)
|
||||
l->setToolTip(getTip(mc, L_SPECIAL_1024, 0, r + (temp >= Special ? 256 : 0)));
|
||||
if (wi.mc > MC_1_6 && wi.mc <= MC_1_17)
|
||||
{
|
||||
uint64_t mL = 0, mM = 0;
|
||||
genPotential(&mL, &mM, L_SPECIAL_1024, wi.mc, 0, r + (temp >= Special ? 256 : 0));
|
||||
QString tip = ConditionDialog::tr("Generates any of:");
|
||||
for (int j = 0; j < 64; j++)
|
||||
if (mL & (1ULL << j))
|
||||
tip += QString("\n") + getBiomeDisplay(wi.mc, j);
|
||||
for (int j = 0; j < 64; j++)
|
||||
if (mM & (1ULL << j))
|
||||
tip += QString("\n") + getBiomeDisplay(wi.mc, 128+j);
|
||||
l->setToolTip(tip);
|
||||
}
|
||||
}
|
||||
|
||||
void ConditionDialog::updateMode()
|
||||
{
|
||||
int filterindex = ui->comboBoxType->currentData().toInt();
|
||||
int filterindex = ui->comboType->currentData().toInt();
|
||||
const FilterInfo &ft = g_filterinfo.list[filterindex];
|
||||
|
||||
ui->lineSummary->setPlaceholderText(QApplication::translate("Filter", ft.name));
|
||||
|
||||
QPalette pal;
|
||||
if (mc < ft.mcmin || mc > ft.mcmax)
|
||||
if (wi.mc < ft.mcmin || wi.mc > ft.mcmax)
|
||||
pal.setColor(QPalette::Normal, QPalette::Button, QColor(255,0,0,127));
|
||||
ui->comboBoxType->setPalette(pal);
|
||||
ui->comboType->setPalette(pal);
|
||||
|
||||
ui->groupBoxGeneral->setEnabled(filterindex != F_SELECT);
|
||||
ui->groupBoxPosition->setEnabled(filterindex != F_SELECT);
|
||||
|
||||
ui->checkRadius->setEnabled(ft.rmax);
|
||||
ui->checkRadius->setEnabled(ft.loc & FilterInfo::LOC_R);
|
||||
|
||||
bool p1 = ft.loc & FilterInfo::LOC_1;
|
||||
bool p2 = ft.loc & FilterInfo::LOC_2;
|
||||
|
||||
if (ui->checkRadius->isEnabled() && ui->checkRadius->isChecked())
|
||||
{
|
||||
@ -516,28 +531,44 @@ void ConditionDialog::updateMode()
|
||||
}
|
||||
else
|
||||
{
|
||||
bool custom = ui->radioCustom->isChecked();
|
||||
|
||||
ui->lineRadius->setEnabled(false);
|
||||
|
||||
ui->radioSquare->setEnabled(ft.area);
|
||||
ui->radioCustom->setEnabled(ft.area);
|
||||
ui->radioSquare->setEnabled(p2);
|
||||
ui->radioCustom->setEnabled(p2);
|
||||
|
||||
ui->lineSquare->setEnabled(!custom && ft.area);
|
||||
|
||||
ui->labelX1->setEnabled(ft.coord && (custom || !ft.area));
|
||||
ui->labelZ1->setEnabled(ft.coord && (custom || !ft.area));
|
||||
ui->labelX2->setEnabled(custom && ft.area);
|
||||
ui->labelZ2->setEnabled(custom && ft.area);
|
||||
ui->lineEditX1->setEnabled(ft.coord && (custom || !ft.area));
|
||||
ui->lineEditZ1->setEnabled(ft.coord && (custom || !ft.area));
|
||||
ui->lineEditX2->setEnabled(custom && ft.area);
|
||||
ui->lineEditZ2->setEnabled(custom && ft.area);
|
||||
if (ui->radioCustom->isChecked())
|
||||
{
|
||||
ui->lineSquare->setEnabled(false);
|
||||
ui->labelX1->setEnabled(p1);
|
||||
ui->labelZ1->setEnabled(p1);
|
||||
ui->labelX2->setEnabled(p2);
|
||||
ui->labelZ2->setEnabled(p2);
|
||||
ui->lineEditX1->setEnabled(p1);
|
||||
ui->lineEditZ1->setEnabled(p1);
|
||||
ui->lineEditX2->setEnabled(p2);
|
||||
ui->lineEditZ2->setEnabled(p2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->lineSquare->setEnabled(p2);
|
||||
ui->labelX1->setEnabled(p1 && !p2);
|
||||
ui->labelZ1->setEnabled(p1 && !p2);
|
||||
ui->labelX2->setEnabled(false);
|
||||
ui->labelZ2->setEnabled(false);
|
||||
ui->lineEditX1->setEnabled(p1 && !p2);
|
||||
ui->lineEditZ1->setEnabled(p1 && !p2);
|
||||
ui->lineEditX2->setEnabled(false);
|
||||
ui->lineEditZ2->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
ui->labelSpinBox->setEnabled(ft.count);
|
||||
ui->spinBox->setEnabled(ft.count);
|
||||
ui->checkSkipRef->setEnabled(ft.count);
|
||||
ui->buttonFromVisible->setEnabled(mapview && p2 && ui->comboRelative->currentIndex() == 0);
|
||||
|
||||
bool cnt = ft.branch == FilterInfo::BR_CLUST;
|
||||
|
||||
ui->labelSpinBox->setEnabled(cnt);
|
||||
ui->spinBox->setEnabled(cnt);
|
||||
ui->checkSkipRef->setEnabled(cnt);
|
||||
|
||||
ui->labelY->setEnabled(ft.hasy);
|
||||
ui->comboY->setEnabled(ft.hasy);
|
||||
@ -561,14 +592,18 @@ void ConditionDialog::updateMode()
|
||||
else if (ft.cat == CAT_BIOMES || ft.cat == CAT_NETHER || ft.cat == CAT_END)
|
||||
{
|
||||
ui->stackedWidget->setCurrentWidget(ui->pageBiomes);
|
||||
ui->checkApprox->setEnabled(mc <= MC_1_17 || ft.step == 4);
|
||||
ui->checkApprox->setEnabled(wi.mc <= MC_1_17 || ft.grid == 4);
|
||||
ui->checkMatchAny->setEnabled(true);
|
||||
if (filterindex == F_BIOME_SAMPLE)
|
||||
ui->stackedBiome->setCurrentWidget(ui->pageBiomeOptSample);
|
||||
else
|
||||
ui->stackedBiome->setCurrentWidget(ui->pageBiomeOpt);
|
||||
}
|
||||
else if (filterindex == F_VILLAGE)
|
||||
{
|
||||
ui->stackedWidget->setCurrentWidget(ui->pageVillage);
|
||||
ui->checkStartPieces->setEnabled(mc >= MC_1_14);
|
||||
ui->checkAbandoned->setEnabled(filterindex == F_VILLAGE && mc >= MC_1_10);
|
||||
ui->checkStartPieces->setEnabled(wi.mc >= MC_1_14);
|
||||
ui->checkAbandoned->setEnabled(filterindex == F_VILLAGE && wi.mc >= MC_1_10);
|
||||
}
|
||||
else if (filterindex == F_FORTRESS)
|
||||
{
|
||||
@ -578,22 +613,22 @@ void ConditionDialog::updateMode()
|
||||
else if (filterindex == F_BASTION)
|
||||
{
|
||||
ui->stackedWidget->setCurrentWidget(ui->pageBastion);
|
||||
ui->checkStartBastion->setEnabled(mc >= MC_1_16_1);
|
||||
ui->checkStartBastion->setEnabled(wi.mc >= MC_1_16_1);
|
||||
}
|
||||
else if (filterindex == F_PORTAL || filterindex == F_PORTALN)
|
||||
{
|
||||
ui->stackedWidget->setCurrentWidget(ui->pagePortal);
|
||||
ui->checkStartPortal->setEnabled(mc >= MC_1_16_1);
|
||||
ui->checkStartPortal->setEnabled(wi.mc >= MC_1_16_1);
|
||||
}
|
||||
else if (filterindex == F_ENDCITY)
|
||||
{
|
||||
ui->stackedWidget->setCurrentWidget(ui->pageEndCity);
|
||||
ui->checkBasement->setEnabled(mc >= MC_1_9);
|
||||
ui->checkBasement->setEnabled(wi.mc >= MC_1_9);
|
||||
}
|
||||
else if (filterindex == F_IGLOO)
|
||||
{
|
||||
ui->stackedWidget->setCurrentWidget(ui->pageIgloo);
|
||||
ui->checkEndShip->setEnabled(mc >= MC_1_9);
|
||||
ui->checkEndShip->setEnabled(wi.mc >= MC_1_9);
|
||||
}
|
||||
else if (filterindex == F_HEIGHT)
|
||||
{
|
||||
@ -603,6 +638,10 @@ void ConditionDialog::updateMode()
|
||||
{
|
||||
ui->stackedWidget->setCurrentWidget(ui->pageLua);
|
||||
}
|
||||
else if (filterindex == F_SPIRAL)
|
||||
{
|
||||
ui->stackedWidget->setCurrentWidget(ui->pageSpiral);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->stackedWidget->setCurrentWidget(ui->pageNone);
|
||||
@ -610,26 +649,14 @@ void ConditionDialog::updateMode()
|
||||
|
||||
updateBiomeSelection();
|
||||
|
||||
QString loc = "";
|
||||
QString areatip = "";
|
||||
QString lowtip = "";
|
||||
QString uptip = "";
|
||||
QString loc = tr("Location");
|
||||
QString areatip = tr("From floor(-x/2) to floor(x/2) on both axes (inclusive)");
|
||||
QString lowtip = tr("Lower bound (inclusive)");
|
||||
QString uptip = tr("Upper bound (inclusive)");
|
||||
|
||||
if (ft.grid > 1)
|
||||
loc += " " + tr("(sampled on a grid of scale 1:%1)").arg(ft.grid);
|
||||
|
||||
if (ft.step > 1)
|
||||
{
|
||||
QString multxt = QString("%1%2").arg(QChar(0xD7)).arg(ft.step);
|
||||
loc = tr("Location (coordinates are multiplied by %1)").arg(multxt);
|
||||
areatip = tr("From floor(-x/2)%1 to floor(x/2)%1 on both axes (inclusive)").arg(multxt);
|
||||
lowtip = tr("Lower bound %1 (inclusive)").arg(multxt);
|
||||
uptip = tr("Upper bound %1 (inclusive)").arg(multxt);
|
||||
}
|
||||
else
|
||||
{
|
||||
loc = tr("Location");
|
||||
areatip = tr("From floor(-x/2) to floor(x/2) on both axes (inclusive)");
|
||||
lowtip = tr("Lower bound (inclusive)");
|
||||
uptip = tr("Upper bound (inclusive)");
|
||||
}
|
||||
ui->groupBoxPosition->setTitle(loc);
|
||||
ui->radioSquare->setToolTip(areatip);
|
||||
ui->labelX1->setToolTip(lowtip);
|
||||
@ -646,7 +673,7 @@ void ConditionDialog::updateMode()
|
||||
|
||||
void ConditionDialog::updateBiomeSelection()
|
||||
{
|
||||
int filterindex = ui->comboBoxType->currentData().toInt();
|
||||
int filterindex = ui->comboType->currentData().toInt();
|
||||
const FilterInfo &ft = g_filterinfo.list[filterindex];
|
||||
|
||||
// clear tool tips
|
||||
@ -669,14 +696,14 @@ void ConditionDialog::updateBiomeSelection()
|
||||
available.push_back(cold_ocean);
|
||||
available.push_back(frozen_ocean);
|
||||
}
|
||||
else if (ft.cat == CAT_BIOMES && mc > MC_B1_7 && mc <= MC_1_17)
|
||||
else if (ft.cat == CAT_BIOMES && wi.mc > MC_B1_7 && wi.mc <= MC_1_17)
|
||||
{
|
||||
int layerId = ft.layer;
|
||||
if (layerId == 0)
|
||||
{
|
||||
Generator tmp;
|
||||
setupGenerator(&tmp, mc, 0);
|
||||
const Layer *l = getLayerForScale(&tmp, ft.step);
|
||||
setupGenerator(&tmp, wi.mc, 0);
|
||||
const Layer *l = getLayerForScale(&tmp, ft.grid);
|
||||
if (l)
|
||||
layerId = l - tmp.ls.layers;
|
||||
}
|
||||
@ -688,7 +715,7 @@ void ConditionDialog::updateBiomeSelection()
|
||||
QCheckBox *cb = it.second;
|
||||
uint64_t mL = 0, mM = 0;
|
||||
uint32_t flags = 0;
|
||||
genPotential(&mL, &mM, layerId, mc, flags, it.first);
|
||||
genPotential(&mL, &mM, layerId, wi.mc, flags, it.first);
|
||||
|
||||
if (mL || mM)
|
||||
{
|
||||
@ -699,12 +726,12 @@ void ConditionDialog::updateBiomeSelection()
|
||||
for (int j = 0; j < 64; j++)
|
||||
{
|
||||
if (mL & (1ULL << j))
|
||||
tip += QString("\n") + getBiomeDisplay(mc, j);
|
||||
tip += QString("\n") + getBiomeDisplay(wi.mc, j);
|
||||
}
|
||||
for (int j = 0; j < 64; j++)
|
||||
{
|
||||
if (mM & (1ULL << j))
|
||||
tip += QString("\n") + getBiomeDisplay(mc, j+128);
|
||||
tip += QString("\n") + getBiomeDisplay(wi.mc, j+128);
|
||||
}
|
||||
cb->setToolTip(tip);
|
||||
}
|
||||
@ -719,12 +746,12 @@ void ConditionDialog::updateBiomeSelection()
|
||||
{
|
||||
for (const auto& it : biomecboxes)
|
||||
{
|
||||
if (isOverworld(mc, it.first))
|
||||
if (isOverworld(wi.mc, it.first))
|
||||
available.push_back(it.first);
|
||||
}
|
||||
}
|
||||
|
||||
IdCmp cmp = {IdCmp::SORT_LEX, mc, DIM_UNDEF};
|
||||
IdCmp cmp = {IdCmp::SORT_LEX, wi.mc, DIM_UNDEF};
|
||||
std::sort(available.begin(), available.end(), cmp);
|
||||
|
||||
if (ui->stackedWidget->currentWidget() == ui->pageBiomes)
|
||||
@ -772,7 +799,7 @@ void ConditionDialog::updateBiomeSelection()
|
||||
|
||||
for (int id: available)
|
||||
{
|
||||
QString s = getBiomeDisplay(mc, id);
|
||||
QString s = getBiomeDisplay(wi.mc, id);
|
||||
ui->comboMatchBiome->addItem(getBiomeIcon(id), s, QVariant::fromValue(id));
|
||||
allowed_matches.append(s);
|
||||
}
|
||||
@ -785,7 +812,7 @@ void ConditionDialog::updateBiomeSelection()
|
||||
}
|
||||
else
|
||||
{
|
||||
QString s = QString("%1 %2").arg(WARNING_CHAR).arg(getBiomeDisplay(mc, curid.toInt()));
|
||||
QString s = QString("%1 %2").arg(WARNING_CHAR).arg(getBiomeDisplay(wi.mc, curid.toInt()));
|
||||
ui->comboMatchBiome->insertItem(0, getBiomeIcon(curid.toInt(), true), s, curid);
|
||||
ui->comboMatchBiome->setCurrentIndex(0);
|
||||
allowed_matches.append(s);
|
||||
@ -830,21 +857,25 @@ int ConditionDialog::warnIfBad(Condition cond)
|
||||
}
|
||||
else if (cond.type == F_BIOME_CENTER || cond.type == F_BIOME_CENTER_256)
|
||||
{
|
||||
int w = cond.x2 - cond.x1 + 1;
|
||||
int h = cond.z2 - cond.z1 + 1;
|
||||
int s = ft.pow2;
|
||||
int w = (cond.x2 >> s) - (cond.x1 >> s) + 1;
|
||||
int h = (cond.z2 >> s) - (cond.z1 >> s) + 1;
|
||||
if ((unsigned int)(w * h) < cond.count * cond.biomeSize)
|
||||
{
|
||||
QString text = tr(
|
||||
"The biome locator checks for %1 instances of size %2 each, "
|
||||
"which cannot be satisfied by an area of size %3%4%5 = %6.")
|
||||
.arg(cond.count).arg(cond.biomeSize).arg(w).arg(QChar(0xD7)).arg(h).arg(w * h);
|
||||
"The biome locator checks for %n instance(s), each of size %1, "
|
||||
"which cannot be satisfied by an area of size\n"
|
||||
"%2%3%4 = %5 < %6 @ scale 1:%7.", "", cond.count)
|
||||
.arg(cond.biomeSize)
|
||||
.arg(w).arg(QChar(0xD7)).arg(h).arg(w*h)
|
||||
.arg(cond.count * cond.biomeSize).arg(1<<s);
|
||||
warn(this, tr("Area Insufficient"), text);
|
||||
return QMessageBox::Cancel;
|
||||
}
|
||||
}
|
||||
else if (ft.cat == CAT_BIOMES)
|
||||
{
|
||||
if (mc >= MC_1_18)
|
||||
if (wi.mc >= MC_1_18)
|
||||
{
|
||||
uint64_t m = cond.biomeToFindM;
|
||||
uint64_t underground =
|
||||
@ -890,8 +921,8 @@ void ConditionDialog::onAccept()
|
||||
|
||||
Condition c = cond;
|
||||
c.version = Condition::VER_CURRENT;
|
||||
c.type = ui->comboBoxType->currentData().toInt();
|
||||
c.relative = ui->comboBoxRelative->currentData().toInt();
|
||||
c.type = ui->comboType->currentData().toInt();
|
||||
c.relative = ui->comboRelative->currentData().toInt();
|
||||
c.count = ui->spinBox->value();
|
||||
c.skipref = ui->checkSkipRef->isChecked();
|
||||
|
||||
@ -923,19 +954,21 @@ void ConditionDialog::onAccept()
|
||||
c.z2 = ui->lineEditZ2->text().toInt();
|
||||
}
|
||||
|
||||
if (ft.area)
|
||||
if (ft.loc & FilterInfo::LOC_2)
|
||||
{
|
||||
if (c.x1 > c.x2) std::swap(c.x1, c.x2);
|
||||
if (c.z1 > c.z2) std::swap(c.z1, c.z2);
|
||||
}
|
||||
|
||||
if (ui->checkRadius->isChecked())
|
||||
if (ui->checkRadius->isEnabled() && ui->checkRadius->isChecked())
|
||||
c.rmax = ui->lineRadius->text().toInt() + 1;
|
||||
else
|
||||
c.rmax = 0;
|
||||
|
||||
c.y = ui->comboY->currentText().section(' ', 0, 0).toInt();
|
||||
|
||||
c.step = ui->lineSpiralStep->text().toUShort();
|
||||
|
||||
if (ui->stackedWidget->currentWidget() == ui->pageBiomes)
|
||||
{
|
||||
c.biomeToFind = c.biomeToFindM = 0;
|
||||
@ -959,7 +992,9 @@ void ConditionDialog::onAccept()
|
||||
}
|
||||
}
|
||||
}
|
||||
c.count = 0;
|
||||
c.count = ui->checkSamplePos->isChecked() ? 1 : 0;
|
||||
c.converage = ui->lineCoverage->text().toFloat() / 100.0;
|
||||
c.confidence = ui->lineConfidence->text().toFloat() / 100.0;
|
||||
}
|
||||
if (ui->stackedWidget->currentWidget() == ui->pageBiomeCenter)
|
||||
{
|
||||
@ -1029,17 +1064,18 @@ void ConditionDialog::onAccept()
|
||||
close();
|
||||
}
|
||||
|
||||
void ConditionDialog::on_comboBoxType_activated(int)
|
||||
void ConditionDialog::on_comboType_activated(int)
|
||||
{
|
||||
updateMode();
|
||||
}
|
||||
|
||||
void ConditionDialog::on_comboBoxRelative_activated(int)
|
||||
void ConditionDialog::on_comboRelative_activated(int)
|
||||
{
|
||||
QPalette pal;
|
||||
if (ui->comboBoxRelative->currentText().contains(WARNING_CHAR))
|
||||
if (ui->comboRelative->currentText().contains(WARNING_CHAR))
|
||||
pal.setColor(QPalette::Normal, QPalette::Button, QColor(255,0,0,127));
|
||||
ui->comboBoxRelative->setPalette(pal);
|
||||
ui->comboRelative->setPalette(pal);
|
||||
updateMode();
|
||||
}
|
||||
|
||||
void ConditionDialog::on_buttonUncheck_clicked()
|
||||
@ -1073,21 +1109,34 @@ void ConditionDialog::on_buttonAreaInfo_clicked()
|
||||
"</p><p>"
|
||||
"Alternatively, the area can be defined as a <b>centered square</b> "
|
||||
"with a certain side length. In this case the area has the bounds: "
|
||||
"[-X/2, -X/2] on both axes, rounding down and bounds included. For "
|
||||
"[-X/2, +X/2] on both axes, rounding down and bounds included. For "
|
||||
"example a centered square with side 3 will go from -2 to 1 for both "
|
||||
"the X and Z axes."
|
||||
"</p><p>"
|
||||
"Important to note is that some filters have a scaling associated with "
|
||||
"them. This means that the area is not defined in blocks, but on a grid "
|
||||
"with the given spacing (such as chunks instead of blocks). A scaling "
|
||||
"of 1:16, for example, means that the aforementioned centered square of "
|
||||
"side 3 will range from -32 to 31 in block coordinates. (Chunk 1 has "
|
||||
"blocks 16 to 31.)"
|
||||
"them. This means the condition only checks on a grid with that spacing. "
|
||||
"An area with a range from -21 to 21 at scale 1:16 may effectively be "
|
||||
"expanded to -32 to 31, and get sampled at -32, -16, 0 and 16."
|
||||
"</p></body></html>"
|
||||
));
|
||||
mb.exec();
|
||||
}
|
||||
|
||||
void ConditionDialog::on_buttonFromVisible_clicked()
|
||||
{
|
||||
if (!mapview)
|
||||
return;
|
||||
int x1, z1, x2, z2;
|
||||
mapview->getVisible(&x1, &z1, &x2, &z2);
|
||||
ui->lineEditX1->setText(QString::number(x1));
|
||||
ui->lineEditZ1->setText(QString::number(z1));
|
||||
ui->lineEditX2->setText(QString::number(x2));
|
||||
ui->lineEditZ2->setText(QString::number(z2));
|
||||
ui->checkRadius->setChecked(false);
|
||||
ui->radioCustom->setChecked(true);
|
||||
updateMode();
|
||||
}
|
||||
|
||||
void ConditionDialog::on_checkRadius_toggled(bool)
|
||||
{
|
||||
updateMode();
|
||||
@ -1121,15 +1170,15 @@ void ConditionDialog::on_ConditionDialog_finished(int result)
|
||||
item = 0;
|
||||
}
|
||||
|
||||
void ConditionDialog::on_comboBoxCat_currentIndexChanged(int)
|
||||
void ConditionDialog::on_comboCat_currentIndexChanged(int)
|
||||
{
|
||||
int cat = ui->comboBoxCat->currentData().toInt();
|
||||
ui->comboBoxType->setEnabled(cat != CAT_NONE);
|
||||
ui->comboBoxType->clear();
|
||||
int cat = ui->comboCat->currentData().toInt();
|
||||
ui->comboType->setEnabled(cat != CAT_NONE);
|
||||
ui->comboType->clear();
|
||||
|
||||
int slot = 0;
|
||||
ui->comboBoxType->insertItem(slot, tr("Select type"), QVariant::fromValue((int)F_SELECT));
|
||||
ui->comboBoxType->insertSeparator(++slot);
|
||||
ui->comboType->insertItem(slot, tr("Select type"), QVariant::fromValue((int)F_SELECT));
|
||||
ui->comboType->insertSeparator(++slot);
|
||||
|
||||
const FilterInfo *ft_list[FILTER_MAX] = {};
|
||||
const FilterInfo *ft;
|
||||
@ -1150,16 +1199,16 @@ void ConditionDialog::on_comboBoxCat_currentIndexChanged(int)
|
||||
QVariant vidx = QVariant::fromValue((int)(ft - g_filterinfo.list));
|
||||
QString txt = QApplication::translate("Filter", ft->name);
|
||||
if (ft->icon)
|
||||
ui->comboBoxType->insertItem(slot, getPix(ft->icon), txt, vidx);
|
||||
ui->comboType->insertItem(slot, getPix(ft->icon), txt, vidx);
|
||||
else
|
||||
ui->comboBoxType->insertItem(slot, txt, vidx);
|
||||
ui->comboType->insertItem(slot, txt, vidx);
|
||||
|
||||
if (mc < ft->mcmin || mc > ft->mcmax)
|
||||
ui->comboBoxType->setItemData(slot, false, Qt::UserRole-1); // deactivate
|
||||
if (wi.mc < ft->mcmin || wi.mc > ft->mcmax)
|
||||
ui->comboType->setItemData(slot, false, Qt::UserRole-1); // deactivate
|
||||
if (ft == g_filterinfo.list + F_FORTRESS)
|
||||
ui->comboBoxType->insertSeparator(slot++);
|
||||
ui->comboType->insertSeparator(slot++);
|
||||
if (ft == g_filterinfo.list + F_ENDCITY)
|
||||
ui->comboBoxType->insertSeparator(slot++);
|
||||
ui->comboType->insertSeparator(slot++);
|
||||
}
|
||||
|
||||
updateMode();
|
||||
@ -1253,8 +1302,8 @@ void ConditionDialog::onClimateLimitChanged()
|
||||
|
||||
getClimateLimits(limok, limex);
|
||||
|
||||
getPossibleBiomesForLimits(ok, mc, limok);
|
||||
getPossibleBiomesForLimits(ex, mc, limex);
|
||||
getPossibleBiomesForLimits(ok, wi.mc, limok);
|
||||
getPossibleBiomesForLimits(ex, wi.mc, limex);
|
||||
|
||||
for (auto& it : noisebiomes)
|
||||
{
|
||||
@ -1270,7 +1319,7 @@ void ConditionDialog::onClimateLimitChanged()
|
||||
|
||||
void ConditionDialog::on_lineBiomeSize_textChanged(const QString &)
|
||||
{
|
||||
int filterindex = ui->comboBoxType->currentData().toInt();
|
||||
int filterindex = ui->comboType->currentData().toInt();
|
||||
double area = ui->lineBiomeSize->text().toInt();
|
||||
QString s;
|
||||
if (filterindex == F_BIOME_CENTER_256)
|
||||
@ -1368,7 +1417,7 @@ void ConditionDialog::on_pushLuaSaveAs_clicked()
|
||||
stream.flush();
|
||||
file.close();
|
||||
ui->textEditLua->document()->setModified(false);
|
||||
uint64_t hash = getScriptHash(fnam);
|
||||
uint64_t hash = getScriptHash(QFileInfo(fnam));
|
||||
ui->comboLua->addItem(QFileInfo(fnam).baseName(), QVariant::fromValue(hash));
|
||||
ui->comboLua->setCurrentIndex(ui->comboLua->count() - 1);
|
||||
}
|
||||
@ -1495,17 +1544,21 @@ void ConditionDialog::on_comboClimatePara_currentIndexChanged(int)
|
||||
{
|
||||
ui->comboOctaves->clear();
|
||||
int loptidx = LOPT_NOISE_PARA + ui->comboClimatePara->currentData().toInt();
|
||||
QStringList items;
|
||||
for (int i = 0; ; i++)
|
||||
{
|
||||
if (const char *s = getLayerOptionText(loptidx, i))
|
||||
items.append(s);
|
||||
else
|
||||
LayerOptInfo info;
|
||||
if (!getLayerOptionInfo(&info, loptidx, i, wi))
|
||||
break;
|
||||
ui->comboOctaves->addItem(info.summary);
|
||||
ui->comboOctaves->setItemData(ui->comboOctaves->count()-1, info.tooltip, Qt::ToolTipRole);
|
||||
}
|
||||
ui->comboOctaves->addItems(items);
|
||||
on_comboOctaves_currentIndexChanged(0);
|
||||
}
|
||||
|
||||
void ConditionDialog::on_comboOctaves_currentIndexChanged(int)
|
||||
{
|
||||
ui->comboOctaves->setToolTip(ui->comboOctaves->currentData(Qt::ToolTipRole).toString());
|
||||
}
|
||||
|
||||
void ConditionDialog::on_comboY_currentTextChanged(const QString &text)
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <QStandardItemModel>
|
||||
|
||||
class MainWindow;
|
||||
class MapView;
|
||||
|
||||
namespace Ui {
|
||||
class ConditionDialog;
|
||||
@ -180,7 +181,7 @@ class ConditionDialog : public QDialog
|
||||
|
||||
public:
|
||||
|
||||
explicit ConditionDialog(FormConditions *parent, Config *config, int mc, QListWidgetItem *item = 0, Condition *initcond = 0);
|
||||
explicit ConditionDialog(FormConditions *parent, MapView *mapview, Config *config, WorldInfo wi, QListWidgetItem *item = 0, Condition *initcond = 0);
|
||||
virtual ~ConditionDialog();
|
||||
|
||||
void addTempCat(int temp, QString name);
|
||||
@ -199,15 +200,16 @@ signals:
|
||||
void setCond(QListWidgetItem *item, Condition cond, int modified);
|
||||
|
||||
private slots:
|
||||
void on_comboBoxType_activated(int);
|
||||
void on_comboType_activated(int);
|
||||
|
||||
void on_comboBoxRelative_activated(int);
|
||||
void on_comboRelative_activated(int);
|
||||
|
||||
void on_buttonUncheck_clicked();
|
||||
void on_buttonInclude_clicked();
|
||||
void on_buttonExclude_clicked();
|
||||
|
||||
void on_buttonAreaInfo_clicked();
|
||||
void on_buttonFromVisible_clicked();
|
||||
|
||||
void on_checkRadius_toggled(bool checked);
|
||||
void on_radioSquare_toggled(bool checked);
|
||||
@ -218,7 +220,7 @@ private slots:
|
||||
|
||||
void on_ConditionDialog_finished(int result);
|
||||
|
||||
void on_comboBoxCat_currentIndexChanged(int);
|
||||
void on_comboCat_currentIndexChanged(int);
|
||||
|
||||
void onCheckStartChanged(int state);
|
||||
void onClimateLimitChanged();
|
||||
@ -236,6 +238,7 @@ private slots:
|
||||
void on_pushInfoLua_clicked();
|
||||
|
||||
void on_comboClimatePara_currentIndexChanged(int index);
|
||||
void on_comboOctaves_currentIndexChanged(int index);
|
||||
|
||||
void on_comboY_currentTextChanged(const QString &text);
|
||||
void on_comboY2_currentTextChanged(const QString &text);
|
||||
@ -255,10 +258,11 @@ private:
|
||||
uint64_t luahash;
|
||||
|
||||
public:
|
||||
MapView *mapview;
|
||||
Config *config;
|
||||
QListWidgetItem *item;
|
||||
Condition cond;
|
||||
int mc;
|
||||
WorldInfo wi;
|
||||
};
|
||||
|
||||
#endif // CONDITIONDIALOG_H
|
||||
|
@ -13,7 +13,7 @@
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="4">
|
||||
<widget class="QComboBox" name="comboBoxCat">
|
||||
<widget class="QComboBox" name="comboCat">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>2</horstretch>
|
||||
@ -26,7 +26,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QComboBox" name="comboBoxType">
|
||||
<widget class="QComboBox" name="comboType">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
@ -256,6 +256,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonFromVisible">
|
||||
<property name="text">
|
||||
<string>From visible</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
@ -344,7 +351,7 @@ QPushButton:hover {
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3" colspan="4">
|
||||
<widget class="QComboBox" name="comboBoxRelative">
|
||||
<widget class="QComboBox" name="comboRelative">
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContentsOnFirstShow</enum>
|
||||
</property>
|
||||
@ -388,7 +395,7 @@ QPushButton:hover {
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>5</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="pageNone">
|
||||
<property name="enabled">
|
||||
@ -460,47 +467,7 @@ QPushButton:hover {
|
||||
<string>Biomes</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_13">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkApprox">
|
||||
<property name="toolTip">
|
||||
<string>Enables optimizations that trade some accuracy for speed</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Approximate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkMatchAny">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style="white-space:pre">Satisfied if <span style=" font-weight:600;">any</span> of the checked biomes are present</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Match any</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="labelY">
|
||||
<property name="text">
|
||||
<string>Sample at height (Y):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<item row="0" column="5">
|
||||
<widget class="QComboBox" name="comboY">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
@ -565,7 +532,24 @@ QPushButton:hover {
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="5">
|
||||
<item row="3" column="0" colspan="6">
|
||||
<widget class="QScrollArea" name="scrollBiomes">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollBiomesContent">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinAndMaxSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayoutBiomes"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="6">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonUncheck">
|
||||
@ -590,21 +574,128 @@ QPushButton:hover {
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="5">
|
||||
<widget class="QScrollArea" name="scrollBiomes">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
<item row="0" column="3">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollBiomesContent">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinAndMaxSize</enum>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="2" colspan="2">
|
||||
<widget class="QStackedWidget" name="stackedBiome">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="pageBiomeOpt">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_30">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayoutBiomes"/>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkMatchAny">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style="white-space:pre">Satisfied if <span style=" font-weight:600;">any</span> of the checked biomes are present</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Match any</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="checkApprox">
|
||||
<property name="toolTip">
|
||||
<string>Enables optimizations that trade some accuracy for speed</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Approximate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pageBiomeOptSample">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_31">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>Coverage (%):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>Confidence (%):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QCheckBox" name="checkSamplePos">
|
||||
<property name="text">
|
||||
<string>Yield positions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineCoverage"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineConfidence"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="labelY">
|
||||
<property name="text">
|
||||
<string>Sample at height (Y):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -1325,6 +1416,58 @@ QPushButton:hover {
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pageSpiral">
|
||||
<layout class="QGridLayout" name="gridLayout_28">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBoxSpiral">
|
||||
<property name="title">
|
||||
<string>Spiral iterator</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_29">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Step size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineSpiralStep">
|
||||
<property name="text">
|
||||
<string>512</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pageVillage">
|
||||
<layout class="QGridLayout" name="gridLayoutVillage">
|
||||
<property name="leftMargin">
|
||||
@ -1669,14 +1812,14 @@ QPushButton:hover {
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>comboBoxCat</tabstop>
|
||||
<tabstop>comboBoxType</tabstop>
|
||||
<tabstop>comboCat</tabstop>
|
||||
<tabstop>comboType</tabstop>
|
||||
<tabstop>spinBox</tabstop>
|
||||
<tabstop>lineEditX1</tabstop>
|
||||
<tabstop>lineEditZ1</tabstop>
|
||||
<tabstop>lineEditX2</tabstop>
|
||||
<tabstop>lineEditZ2</tabstop>
|
||||
<tabstop>comboBoxRelative</tabstop>
|
||||
<tabstop>comboRelative</tabstop>
|
||||
<tabstop>stackedWidget</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
|
@ -52,7 +52,9 @@ ConfigDialog::ConfigDialog(QWidget *parent, Config *config)
|
||||
int hsc = ui->scrollAreaWidgetContents->sizeHint().height();
|
||||
int hpa = parent->size().height();
|
||||
int h = size.height();
|
||||
h += hsc - hsa + layout()->margin();
|
||||
int m1, m2;
|
||||
layout()->getContentsMargins(0, &m1, 0, &m2);
|
||||
h += hsc - hsa + m1 + m2;
|
||||
if (h > hpa) h = hpa;
|
||||
size.setHeight(h);
|
||||
resize(size);
|
||||
|
@ -75,7 +75,7 @@ FormConditions::FormConditions(QWidget *parent)
|
||||
}
|
||||
|
||||
qRegisterMetaType< Condition >("Condition");
|
||||
qRegisterMetaTypeStreamOperators< Condition >("Condition");
|
||||
// qRegisterMetaTypeStreamOperators< Condition >("Condition");
|
||||
}
|
||||
|
||||
FormConditions::~FormConditions()
|
||||
@ -117,10 +117,12 @@ void FormConditions::updateSensitivity()
|
||||
ui->buttonEdit->setEnabled(false);
|
||||
}
|
||||
|
||||
QVector<Condition> selcond;
|
||||
int disabled = 0;
|
||||
for (int i = 0; i < selected.size(); i++)
|
||||
{
|
||||
Condition c = qvariant_cast<Condition>(selected[i]->data(Qt::UserRole));
|
||||
selcond.append(c);
|
||||
if (c.meta & Condition::DISABLED)
|
||||
disabled++;
|
||||
}
|
||||
@ -131,6 +133,8 @@ void FormConditions::updateSensitivity()
|
||||
else
|
||||
ui->buttonDisable->setText(tr("Toggle"));
|
||||
ui->buttonDisable->setEnabled(!selected.empty());
|
||||
|
||||
emit selectionUpdate(selcond);
|
||||
}
|
||||
|
||||
|
||||
@ -207,7 +211,7 @@ void FormConditions::editCondition(QListWidgetItem *item)
|
||||
return;
|
||||
WorldInfo wi;
|
||||
parent->getSeed(&wi);
|
||||
ConditionDialog *dialog = new ConditionDialog(this, &parent->config, wi.mc, item, (Condition*)item->data(Qt::UserRole).data());
|
||||
ConditionDialog *dialog = new ConditionDialog(this, parent->getMapView(), &parent->config, wi, item, (Condition*)item->data(Qt::UserRole).data());
|
||||
QObject::connect(dialog, SIGNAL(setCond(QListWidgetItem*,Condition,int)), this, SLOT(addItemCondition(QListWidgetItem*,Condition,int)), Qt::QueuedConnection);
|
||||
dialog->show();
|
||||
}
|
||||
@ -266,7 +270,7 @@ void FormConditions::on_buttonAddFilter_clicked()
|
||||
return;
|
||||
WorldInfo wi;
|
||||
parent->getSeed(&wi);
|
||||
ConditionDialog *dialog = new ConditionDialog(this, &parent->config, wi.mc);
|
||||
ConditionDialog *dialog = new ConditionDialog(this, parent->getMapView(), &parent->config, wi);
|
||||
QObject::connect(dialog, SIGNAL(setCond(QListWidgetItem*,Condition,int)), this, SLOT(addItemCondition(QListWidgetItem*,Condition)), Qt::QueuedConnection);
|
||||
dialog->show();
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
void selectionUpdate(const QVector<Condition>& selected);
|
||||
|
||||
public slots:
|
||||
void on_buttonRemoveAll_clicked();
|
||||
|
@ -487,21 +487,21 @@ void FormSearchControl::on_buttonSearchHelp_clicked()
|
||||
mb.setText(tr(
|
||||
"<html><head/><body><p>"
|
||||
"The <b>incremental</b> search checks seeds in numerical order, "
|
||||
"save for grouping into work items for parallelization. This type "
|
||||
"of search is best suited for a non-exhaustive search space and "
|
||||
"with strong biome dependencies. You can restrict this type of "
|
||||
"search to a value range using the "..." button."
|
||||
"except for grouping seeds into work items for parallelization. "
|
||||
"This is the recommended option for general searches. You can "
|
||||
"restrict this type of search to a value range using the "
|
||||
""..." button."
|
||||
"</p><p>"
|
||||
"When searching <b>48-bit only</b>, the search is limited to the seed "
|
||||
"bases and does not yield matching seeds, but rather checks only the "
|
||||
"parts of the conditions can be determined from the lower 48-bits. "
|
||||
"Sessions saved from this search are suitable to be used later with "
|
||||
"the 48-bit generator to look for matching seeds."
|
||||
"When using <b>48-bit only</b>, the search checks partial seeds and "
|
||||
"will not test the full conditions. Instead it yields seed bases "
|
||||
"that may satify the conditions without knowing the upper 16-bit of "
|
||||
"the seed. A session file saved from this search is suitable to be used "
|
||||
"later with the 48-bit generator to look for matching seeds."
|
||||
"</p><p>"
|
||||
"With <b>48-bit family blocks</b> the search looks for suitable "
|
||||
"48-bit seeds first and parallelizes the search through the upper "
|
||||
"16-bits. This search type is best suited for exhaustive searches and "
|
||||
"those with very restrictive structure requirements."
|
||||
"16-bits. This search type can be a better match for exhaustive searches "
|
||||
"and those with very restrictive structure requirements."
|
||||
"</p><p>"
|
||||
"Load a <b>seed list from a file</b> to search through an "
|
||||
"existing set of seeds. The seeds should be in decimal ASCII text, "
|
||||
@ -585,7 +585,7 @@ void FormSearchControl::searchResult(uint64_t seed)
|
||||
qbuf.push_back(seed);
|
||||
if (ui->checkStop->isChecked())
|
||||
{
|
||||
onBufferTimeout();
|
||||
stopSearch();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <QElapsedTimer>
|
||||
#include <QAbstractTableModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QFile>
|
||||
|
||||
#include <deque>
|
||||
|
||||
|
@ -167,7 +167,7 @@ QPushButton:hover {
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Queued progress within search set</string>
|
||||
<string>Queued progress within the search set</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
|
@ -74,7 +74,7 @@ void GotoDialog::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||
QString s = clipboard->text().trimmed();
|
||||
QStringList xz = s.split(QRegExp("[, ]+"));
|
||||
QStringList xz = s.split(QRegularExpression("[, ]+"));
|
||||
if (xz.count() == 2)
|
||||
{
|
||||
ui->lineX->setText(xz[0]);
|
||||
|
@ -5,125 +5,96 @@
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
const char *getLayerOptionText(int mode, int disp)
|
||||
bool getLayerOptionInfo(LayerOptInfo *info, int mode, int disp, WorldInfo wi)
|
||||
{
|
||||
/*
|
||||
Para 0:
|
||||
4096 0.952381
|
||||
1024 0.158730
|
||||
Para 1:
|
||||
1024 0.564374
|
||||
512 0.282187
|
||||
Para 2:
|
||||
2048 0.751468
|
||||
1024 0.375734
|
||||
512 0.375734
|
||||
256 0.187867
|
||||
128 0.093933
|
||||
64 0.023483
|
||||
32 0.011742
|
||||
16 0.005871
|
||||
8 0.002935
|
||||
Para 3:
|
||||
2048 0.716846
|
||||
1024 0.358423
|
||||
256 0.089606
|
||||
128 0.044803
|
||||
Para 4:
|
||||
32 0.666667
|
||||
16 0.333333
|
||||
8 0.166667
|
||||
Para 5:
|
||||
512 0.634921
|
||||
256 0.634921
|
||||
128 0.158730
|
||||
*/
|
||||
QString txt;
|
||||
QString tip;
|
||||
int nptype = -1;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case LOPT_BIOMES:
|
||||
switch (disp) {
|
||||
case 0: return "1:1";
|
||||
case 1: return "1:4";
|
||||
case 2: return "1:16";
|
||||
case 3: return "1:64";
|
||||
case 4: return "1:256";
|
||||
default: return nullptr;
|
||||
}
|
||||
case LOPT_NOISE_T_4:
|
||||
switch (disp) {
|
||||
case 0: return "All";
|
||||
case 1: return "+A[0] 1:4096 x0.952381";
|
||||
case 2: return "+B[0] 1:4023 x0.952381";
|
||||
case 3: return "+A[1] 1:1024 x0.158730";
|
||||
case 4: return "+B[1] 1:1005 x0.158730";
|
||||
default: return nullptr;
|
||||
}
|
||||
case LOPT_NOISE_H_4:
|
||||
switch (disp) {
|
||||
case 0: return "All";
|
||||
case 1: return "+A[0] 1:1024 x0.564374";
|
||||
case 2: return "+B[0] 1:1005 x0.564374";
|
||||
case 3: return "+A[1] 1:512 x0.282187";
|
||||
case 4: return "+B[1] 1:502 x0.282187";
|
||||
default: return nullptr;
|
||||
}
|
||||
case LOPT_NOISE_C_4:
|
||||
switch (disp) {
|
||||
case 0: return "All";
|
||||
case 1: return "+A[0] 1:2048 x0.751468";
|
||||
case 2: return "+B[0] 1:2011 x0.751468";
|
||||
case 3: return "+A[1] 1:1024 x0.375734";
|
||||
case 4: return "+B[1] 1:1005 x0.375734";
|
||||
case 5: return "+A[2] 1:512 x0.375734";
|
||||
case 6: return "+B[2] 1:502 x0.375734";
|
||||
case 7: return "+A[3] 1:256 x0.187867";
|
||||
case 8: return "+B[3] 1:251 x0.187867";
|
||||
case 9: return "+A[4] 1:128 x0.093933";
|
||||
case 10: return "+B[4] 1:125 x0.093933";
|
||||
case 11: return "+A[5] 1:64 x0.023483";
|
||||
case 12: return "+B[5] 1:62 x0.023483";
|
||||
case 13: return "+A[6] 1:32 x0.011742";
|
||||
case 14: return "+B[6] 1:31 x0.011742";
|
||||
default: return nullptr;
|
||||
}
|
||||
case LOPT_NOISE_E_4:
|
||||
switch (disp) {
|
||||
case 0: return "All";
|
||||
case 1: return "+A[0] 1:2048 x0.716846";
|
||||
case 2: return "+B[0] 1:2011 x0.716846";
|
||||
case 3: return "+A[1] 1:1024 x0.358423";
|
||||
case 4: return "+B[1] 1:1005 x0.358423";
|
||||
case 5: return "+A[2] 1:256 x0.089606";
|
||||
case 6: return "+B[2] 1:251 x0.089606";
|
||||
case 7: return "+A[3] 1:128 x0.044803";
|
||||
case 8: return "+B[3] 1:125 x0.044803";
|
||||
default: return nullptr;
|
||||
}
|
||||
case LOPT_NOISE_W_4:
|
||||
switch (disp) {
|
||||
case 0: return "All";
|
||||
case 1: return "+A[0] 1:512 x0.634921";
|
||||
case 2: return "+B[0] 1:502 x0.634921";
|
||||
case 3: return "+A[1] 1:256 x0.634921";
|
||||
case 4: return "+B[1] 1:251 x0.634921";
|
||||
case 5: return "+A[2] 1:128 x0.158730";
|
||||
case 6: return "+B[2] 1:125 x0.158730";
|
||||
default: return nullptr;
|
||||
}
|
||||
if (disp == 0) txt = "1:1";
|
||||
if (disp == 1) txt = "1:4";
|
||||
if (disp == 2) txt = "1:16";
|
||||
if (disp == 3) txt = "1:64";
|
||||
if (disp == 4) txt = "1:256";
|
||||
break;
|
||||
case LOPT_HEIGHT_4:
|
||||
switch (disp) {
|
||||
case 0: return QT_TRANSLATE_NOOP("LayerDialog", "Grayscale");
|
||||
case 1: return QT_TRANSLATE_NOOP("LayerDialog", "Shaded biome map");
|
||||
case 2: return QT_TRANSLATE_NOOP("LayerDialog", "Contours on biomes");
|
||||
case 3: return QT_TRANSLATE_NOOP("LayerDialog", "Shaded with contours");
|
||||
default: return nullptr;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
if (disp == 0) txt = QApplication::translate("LayerDialog", "Grayscale");
|
||||
if (disp == 1) txt = QApplication::translate("LayerDialog", "Shaded biome map");
|
||||
if (disp == 2) txt = QApplication::translate("LayerDialog", "Contours on biomes");
|
||||
if (disp == 3) txt = QApplication::translate("LayerDialog", "Shaded with contours");
|
||||
break;
|
||||
case LOPT_NOISE_T_4: nptype = NP_TEMPERATURE; break;
|
||||
case LOPT_NOISE_H_4: nptype = NP_HUMIDITY; break;
|
||||
case LOPT_NOISE_C_4: nptype = NP_CONTINENTALNESS; break;
|
||||
case LOPT_NOISE_E_4: nptype = NP_EROSION; break;
|
||||
case LOPT_NOISE_W_4: nptype = NP_WEIRDNESS; break;
|
||||
}
|
||||
|
||||
if (nptype != -1 && disp >= 0)
|
||||
{
|
||||
BiomeNoise bn;
|
||||
initBiomeNoise(&bn, wi.mc);
|
||||
setBiomeSeed(&bn, wi.seed, wi.large);
|
||||
|
||||
DoublePerlinNoise *dpn = bn.climate + nptype;
|
||||
PerlinNoise *oct[2] = { dpn->octA.octaves, dpn->octB.octaves };
|
||||
int noct = dpn->octA.octcnt;
|
||||
int idx = noct-1;
|
||||
int ab = 1;
|
||||
if (disp > 0)
|
||||
{
|
||||
idx = (disp - 1) / 2;
|
||||
ab = (disp - 1) % 2;
|
||||
if (idx >= noct)
|
||||
return false;
|
||||
}
|
||||
|
||||
double ampsum = 0, amptot = 0;
|
||||
for (int i = 0; i < noct; i++)
|
||||
{
|
||||
for (int j = 0; j <= 1; j++)
|
||||
{
|
||||
double a = oct[j][i].amplitude;
|
||||
amptot += a;
|
||||
if (i < idx || (idx == i && j <= ab))
|
||||
ampsum += a;
|
||||
}
|
||||
}
|
||||
amptot *= dpn->amplitude;
|
||||
ampsum *= dpn->amplitude;
|
||||
|
||||
double f = 337.0 / 331.0;
|
||||
PerlinNoise *pn = &oct[ab][idx];
|
||||
double a = pn->amplitude * dpn->amplitude;
|
||||
double l = pn->lacunarity * (ab == 0 ? 1.0 : f);
|
||||
|
||||
if (disp == 0)
|
||||
{
|
||||
txt += QString("%1.. x%2").arg(QChar(0x03A3)).arg(amptot, 0, 'f', 6);
|
||||
tip += QApplication::translate("LayerDialog", "All octaves");
|
||||
}
|
||||
else
|
||||
{
|
||||
txt += QString("%1..").arg(QChar(0x03A3));
|
||||
txt += QString::asprintf("%d%c 1:%-5.0f x%.6f", idx, ab?'B':'A', 1.0/l, a);
|
||||
tip += QApplication::translate("LayerDialog", "Contribution of the %n most significant octaves out of %1 total.", "", disp).arg(2*noct);
|
||||
}
|
||||
tip += "\n" + QApplication::translate("LayerDialog", "Total contribution: %1 = %2%").arg(ampsum).arg(100 * ampsum / amptot, 0, 'f', 1);
|
||||
tip += "\n" + QApplication::translate("LayerDialog", "Octave amplitude: %1").arg(a);
|
||||
tip += "\n" + QApplication::translate("LayerDialog", "Octave lacunarity: %1 = 1/%2").arg(l).arg(1.0/l);
|
||||
}
|
||||
|
||||
if (info) {
|
||||
info->summary = txt;
|
||||
info->tooltip = tip;
|
||||
}
|
||||
return !txt.isEmpty();
|
||||
}
|
||||
|
||||
LayerDialog::LayerDialog(QWidget *parent, int mc)
|
||||
LayerDialog::LayerDialog(QWidget *parent, WorldInfo wi)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::LayerDialog)
|
||||
, radio{}
|
||||
@ -157,18 +128,21 @@ LayerDialog::LayerDialog(QWidget *parent, int mc)
|
||||
{
|
||||
if (!combo[i])
|
||||
continue;
|
||||
QStringList items;
|
||||
for (int j = 0; ; j++)
|
||||
{
|
||||
const char *item = getLayerOptionText(i, j);
|
||||
if (!item)
|
||||
LayerOptInfo info;
|
||||
if (!getLayerOptionInfo(&info, i, j, wi))
|
||||
break;
|
||||
QString s = QApplication::translate("LayerDialog", item).leftJustified(24);
|
||||
QString s = info.summary.leftJustified(24);
|
||||
if (j < 9)
|
||||
s += "\tALT+"+QString::number(j+1);
|
||||
items.append(s);
|
||||
combo[i]->addItem(s);
|
||||
combo[i]->setItemData(combo[i]->count()-1, info.tooltip, Qt::ToolTipRole);
|
||||
}
|
||||
combo[i]->addItems(items);
|
||||
connect(combo[i], QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int){
|
||||
this->onComboChange(combo[i]);
|
||||
});
|
||||
onComboChange(combo[i]);
|
||||
}
|
||||
|
||||
QFont fmono;
|
||||
@ -182,17 +156,17 @@ LayerDialog::LayerDialog(QWidget *parent, int mc)
|
||||
combo[i]->setFont(fmono);
|
||||
if (i >= LOPT_NOISE_T_4 && i <= LOPT_NOISE_W_4)
|
||||
{
|
||||
radio[i]->setEnabled(mc > MC_1_17);
|
||||
radio[i]->setEnabled(wi.mc > MC_1_17);
|
||||
if (combo[i])
|
||||
combo[i]->setEnabled(mc > MC_1_17);
|
||||
combo[i]->setEnabled(wi.mc > MC_1_17);
|
||||
}
|
||||
if (i == LOPT_RIVER_4 || i == LOPT_OCEAN_256)
|
||||
{
|
||||
radio[i]->setEnabled(mc > MC_1_12 && mc <= MC_1_17);
|
||||
radio[i]->setEnabled(wi.mc > MC_1_12 && wi.mc <= MC_1_17);
|
||||
}
|
||||
if (i == LOPT_NOOCEAN_1 || i == LOPT_BETA_T_1 || i == LOPT_BETA_H_1)
|
||||
{
|
||||
radio[i]->setEnabled(mc <= MC_B1_7);
|
||||
radio[i]->setEnabled(wi.mc <= MC_B1_7);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -235,6 +209,11 @@ void LayerDialog::onRadioChange()
|
||||
}
|
||||
}
|
||||
|
||||
void LayerDialog::onComboChange(QComboBox *combo)
|
||||
{
|
||||
combo->setToolTip(combo->currentData(Qt::ToolTipRole).toString());
|
||||
}
|
||||
|
||||
void LayerDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
{
|
||||
QDialogButtonBox::StandardButton b = ui->buttonBox->standardButton(button);
|
||||
|
@ -11,14 +11,20 @@ namespace Ui {
|
||||
class LayerDialog;
|
||||
}
|
||||
|
||||
const char *getLayerOptionText(int mode, int disp);
|
||||
struct LayerOptInfo
|
||||
{
|
||||
QString summary;
|
||||
QString tooltip;
|
||||
};
|
||||
|
||||
bool getLayerOptionInfo(LayerOptInfo *info, int mode, int disp, WorldInfo wi);
|
||||
|
||||
class LayerDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LayerDialog(QWidget *parent, int mc);
|
||||
explicit LayerDialog(QWidget *parent, WorldInfo mc);
|
||||
~LayerDialog();
|
||||
|
||||
void setLayerOptions(LayerOpt lopts);
|
||||
@ -29,6 +35,7 @@ signals:
|
||||
|
||||
public slots:
|
||||
void onRadioChange();
|
||||
void onComboChange(QComboBox *combo);
|
||||
|
||||
private slots:
|
||||
void on_buttonBox_clicked(QAbstractButton *button);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "exportdialog.h"
|
||||
#include "layerdialog.h"
|
||||
#include "tabtriggers.h"
|
||||
#include "tablocations.h"
|
||||
#include "tabbiomes.h"
|
||||
#include "tabstructures.h"
|
||||
#include "message.h"
|
||||
@ -52,7 +53,8 @@ MainWindow::MainWindow(QString sessionpath, QString resultspath, QWidget *parent
|
||||
, sessionpath(sessionpath)
|
||||
, prevdir(".")
|
||||
, autosaveTimer()
|
||||
, prevtab(-1)
|
||||
, tabidx(-1)
|
||||
, tabsearch(-1)
|
||||
, dimactions{}
|
||||
, dimgroup()
|
||||
{
|
||||
@ -86,7 +88,8 @@ MainWindow::MainWindow(QString sessionpath, QString resultspath, QWidget *parent
|
||||
|
||||
ui->menuHistory->clear();
|
||||
|
||||
ui->tabContainer->addTab(new TabTriggers(this), tr("Triggers"));
|
||||
ui->tabContainerSearch->addTab(new TabTriggers(this), tr("Triggers"));
|
||||
ui->tabContainerSearch->addTab(new TabLocations(this), tr("Locations"));
|
||||
ui->tabContainer->addTab(new TabBiomes(this), tr("Biomes"));
|
||||
ui->tabContainer->addTab(new TabStructures(this), tr("Structures"));
|
||||
|
||||
@ -185,7 +188,8 @@ MainWindow::MainWindow(QString sessionpath, QString resultspath, QWidget *parent
|
||||
saction[D_GRID]->setChecked(true);
|
||||
|
||||
ui->splitterMap->setSizes(QList<int>({6500, 10000}));
|
||||
ui->splitterSearch->setSizes(QList<int>({1000, 1000, 2000}));
|
||||
ui->splitterSearch->setSizes(QList<int>({1000, 3000}));
|
||||
ui->splitterSeeds->setSizes(QList<int>({500, 2500}));
|
||||
|
||||
qRegisterMetaType< int64_t >("int64_t");
|
||||
qRegisterMetaType< uint64_t >("uint64_t");
|
||||
@ -202,6 +206,7 @@ MainWindow::MainWindow(QString sessionpath, QString resultspath, QWidget *parent
|
||||
|
||||
ui->collapseConstraints->init(tr("Conditions"), formCond, false);
|
||||
connect(formCond, &FormConditions::changed, this, &MainWindow::onConditionsChanged);
|
||||
connect(formCond, &FormConditions::selectionUpdate, this, &MainWindow::onConditionsSelect);
|
||||
ui->collapseConstraints->setInfo(
|
||||
tr("Help: Conditions"),
|
||||
tr(
|
||||
@ -304,7 +309,7 @@ bool MainWindow::loadTranslation(QString lang)
|
||||
static QTranslator qt_translator;
|
||||
if (!rc_translator.load(lang, ":/lang"))
|
||||
return false;
|
||||
QLocale::setDefault(lang);
|
||||
QLocale::setDefault(QLocale(lang));
|
||||
QString qt_locale = "qtbase_" + lang;
|
||||
QString qt_trpath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
|
||||
if (qt_translator.load(qt_locale, qt_trpath))
|
||||
@ -432,8 +437,9 @@ bool MainWindow::setSeed(WorldInfo wi, int dim)
|
||||
ui->seedEdit->setEnabled(true);
|
||||
ui->comboY->setEnabled(true);
|
||||
|
||||
ISaveTab *tab = dynamic_cast<ISaveTab*>(ui->tabContainer->currentWidget());
|
||||
if (tab)
|
||||
if (ISaveTab *tab = dynamic_cast<ISaveTab*>(ui->tabContainer->currentWidget()))
|
||||
tab->refresh();
|
||||
if (ISaveTab *tab = dynamic_cast<ISaveTab*>(ui->tabContainerSearch->currentWidget()))
|
||||
tab->refresh();
|
||||
return true;
|
||||
}
|
||||
@ -466,6 +472,7 @@ void MainWindow::saveSettings()
|
||||
g_extgen.save(settings);
|
||||
|
||||
on_tabContainer_currentChanged(-1);
|
||||
on_tabContainerSearch_currentChanged(-1);
|
||||
|
||||
WorldInfo wi;
|
||||
getSeed(&wi, false);
|
||||
@ -497,7 +504,7 @@ void MainWindow::loadSettings()
|
||||
showMaximized();
|
||||
} else {
|
||||
resize(settings.value("mainwindow/size", size()).toSize());
|
||||
move(settings.value("mainwindow/pos", pos()).toPoint());
|
||||
//move(settings.value("mainwindow/pos", pos()).toPoint());
|
||||
}
|
||||
prevdir = settings.value("mainwindow/prevdir", prevdir).toString();
|
||||
|
||||
@ -635,7 +642,7 @@ void MainWindow::setDockable(bool dockable)
|
||||
// and avoid a warning about negative size widget
|
||||
QWidget *title = new QWidget(this);
|
||||
QHBoxLayout *l = new QHBoxLayout(title);
|
||||
l->setMargin(0);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
title->setLayout(l);
|
||||
dock->setTitleBarWidget(title);
|
||||
dock->setFloating(false);
|
||||
@ -885,7 +892,7 @@ void MainWindow::on_actionLayerDisplay_triggered()
|
||||
{
|
||||
WorldInfo wi;
|
||||
getSeed(&wi, false);
|
||||
LayerDialog *dialog = new LayerDialog(this, wi.mc);
|
||||
LayerDialog *dialog = new LayerDialog(this, wi);
|
||||
dialog->setLayerOptions(lopt);
|
||||
connect(dialog, &LayerDialog::apply, [=](){
|
||||
lopt = dialog->getLayerOptions();
|
||||
@ -895,14 +902,24 @@ void MainWindow::on_actionLayerDisplay_triggered()
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
void MainWindow::on_tabContainer_currentChanged(int index)
|
||||
static int tab_switch(QTabWidget *tabs, int idxprev, int idxnext)
|
||||
{
|
||||
QSettings settings(APP_STRING, APP_STRING);
|
||||
ISaveTab *tabold = dynamic_cast<ISaveTab*>(ui->tabContainer->widget(prevtab));
|
||||
ISaveTab *tabnew = dynamic_cast<ISaveTab*>(ui->tabContainer->widget(index));
|
||||
ISaveTab *tabold = dynamic_cast<ISaveTab*>(tabs->widget(idxprev));
|
||||
ISaveTab *tabnew = dynamic_cast<ISaveTab*>(tabs->widget(idxnext));
|
||||
if (tabold) tabold->save(settings);
|
||||
if (tabnew) tabnew->load(settings);
|
||||
prevtab = index;
|
||||
return idxnext;
|
||||
}
|
||||
|
||||
void MainWindow::on_tabContainer_currentChanged(int index)
|
||||
{
|
||||
tabidx = tab_switch(ui->tabContainer, tabidx, index);
|
||||
}
|
||||
|
||||
void MainWindow::on_tabContainerSearch_currentChanged(int index)
|
||||
{
|
||||
tabsearch = tab_switch(ui->tabContainerSearch, tabsearch, index);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSearch_seed_list_triggered()
|
||||
@ -946,16 +963,16 @@ void MainWindow::onActionMapToggled(int sopt, bool show)
|
||||
|
||||
void MainWindow::onActionBiomeLayerSelect(int mode, int disp)
|
||||
{
|
||||
WorldInfo wi;
|
||||
getSeed(&wi, false);
|
||||
lopt.mode = mode;
|
||||
if (disp >= 0)
|
||||
{
|
||||
if (!getLayerOptionText(mode, disp))
|
||||
if (!getLayerOptionInfo(nullptr, mode, disp, wi))
|
||||
return; // unsupported display mode
|
||||
lopt.disp[mode] = disp;
|
||||
}
|
||||
lopt.mode = mode;
|
||||
WorldInfo wi;
|
||||
if (getSeed(&wi, false))
|
||||
setSeed(wi, DIM_UNDEF);
|
||||
setSeed(wi, DIM_UNDEF);
|
||||
}
|
||||
|
||||
void MainWindow::onConditionsChanged()
|
||||
@ -964,6 +981,37 @@ void MainWindow::onConditionsChanged()
|
||||
formGen48->updateAutoConditions(conds);
|
||||
}
|
||||
|
||||
void MainWindow::onConditionsSelect(const QVector<Condition>& selection)
|
||||
{
|
||||
std::vector<Shape> shapes;
|
||||
for (const Condition& c : selection)
|
||||
{
|
||||
if (c.meta & Condition::DISABLED)
|
||||
continue;
|
||||
if (c.relative)
|
||||
continue;
|
||||
const FilterInfo& ft = g_filterinfo.list[c.type];
|
||||
|
||||
Shape s;
|
||||
s.dim = ft.dim;
|
||||
if (c.rmax)
|
||||
{
|
||||
s.type = Shape::CIRCLE;
|
||||
s.p1 = s.p2 = Pos{0,0};
|
||||
s.r = c.rmax - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.type = Shape::RECT;
|
||||
s.p1 = Pos{c.x1, c.z1};
|
||||
s.p2 = Pos{c.x2+1, c.z2+1};
|
||||
s.r = 0;
|
||||
}
|
||||
shapes.push_back(s);
|
||||
}
|
||||
getMapView()->setShapes(shapes);
|
||||
}
|
||||
|
||||
void MainWindow::onGen48Changed()
|
||||
{
|
||||
formGen48->updateCount();
|
||||
|
@ -103,6 +103,7 @@ private slots:
|
||||
void on_actionLayerDisplay_triggered();
|
||||
|
||||
void on_tabContainer_currentChanged(int index);
|
||||
void on_tabContainerSearch_currentChanged(int index);
|
||||
|
||||
void on_actionSearch_seed_list_triggered();
|
||||
void on_actionSearch_full_seed_space_triggered();
|
||||
@ -113,6 +114,7 @@ private slots:
|
||||
void onActionHistory(QAction *act);
|
||||
void onActionBiomeLayerSelect(int lopt, int disp = -1);
|
||||
void onConditionsChanged();
|
||||
void onConditionsSelect(const QVector<Condition>& selection);
|
||||
void onGen48Changed();
|
||||
void onSelectedSeedChanged(uint64_t seed);
|
||||
void onSearchStatusChanged(bool running);
|
||||
@ -136,7 +138,8 @@ public:
|
||||
QString sessionpath;
|
||||
QString prevdir;
|
||||
QTimer autosaveTimer;
|
||||
int prevtab;
|
||||
int tabidx;
|
||||
int tabsearch;
|
||||
|
||||
QVector<QAction*> laction;
|
||||
QVector<QAction*> saction;
|
||||
|
@ -211,6 +211,11 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabContainer">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QToolButton {
|
||||
background-color: transparent;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -224,120 +229,68 @@
|
||||
<attribute name="title">
|
||||
<string>Search</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>540</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
<widget class="QSplitter" name="splitterSearch">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QAbstractScrollArea#scrollArea {
|
||||
border: 0px none;
|
||||
}
|
||||
|
||||
QToolButton {
|
||||
background-color: transparent;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<widget class="Collapsible" name="collapseConstraints" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>440</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
</widget>
|
||||
<widget class="QWidget" name="gridLayoutWidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
<number>18</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitterSearch">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<widget class="QTabWidget" name="tabContainerSearch">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">
|
||||
QSplitter {
|
||||
background-color: transparent;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="Collapsible" name="collapseConstraints" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Collapsible" name="collapseGen48" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Collapsible" name="collapseControl" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabSeeds">
|
||||
<attribute name="title">
|
||||
<string>Seeds</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitterSeeds">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="Collapsible" name="collapseGen48" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Collapsible" name="collapseControl" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -59,7 +59,7 @@ MapView::MapView(QWidget *parent)
|
||||
setFont(fmono);
|
||||
|
||||
QPalette pal = palette();
|
||||
pal.setColor(QPalette::Background, Qt::black);
|
||||
pal.setColor(QPalette::Dark, Qt::black);
|
||||
setAutoFillBackground(true);
|
||||
setPalette(pal);
|
||||
|
||||
@ -189,6 +189,13 @@ void MapView::setConfig(const Config& c)
|
||||
update(2);
|
||||
}
|
||||
|
||||
void MapView::setShapes(const std::vector<Shape>& s)
|
||||
{
|
||||
shapes = s;
|
||||
settingsToWorld();
|
||||
update(1);
|
||||
}
|
||||
|
||||
void MapView::refreshBiomeColors()
|
||||
{
|
||||
if (world)
|
||||
@ -207,6 +214,7 @@ void MapView::settingsToWorld()
|
||||
world->memlimit = (uint64_t) config.mapCacheSize * 1024 * 1024;
|
||||
world->threadlimit = config.mapThreads;
|
||||
world->lopt = lopt;
|
||||
world->shapes = shapes;
|
||||
}
|
||||
|
||||
static qreal smoothstep(qreal x)
|
||||
@ -304,6 +312,27 @@ qreal MapView::getZ()
|
||||
return fz;
|
||||
}
|
||||
|
||||
static qreal clampimax(qreal x, bool *ok = nullptr)
|
||||
{
|
||||
const double imax = INT_MAX - 1024.0;
|
||||
if (x < -imax) x = -imax;
|
||||
if (x > +imax) x = +imax;
|
||||
if (ok) *ok = (x > -imax && x < +imax);
|
||||
return x;
|
||||
}
|
||||
|
||||
void MapView::getVisible(int *x0, int *z0, int *x1, int *z1)
|
||||
{
|
||||
qreal x = getX();
|
||||
qreal z = getZ();
|
||||
qreal uiw = width() / blocks2pix;
|
||||
qreal uih = height() / blocks2pix;
|
||||
if (x0) *x0 = (int) clampimax( floor(x - uiw/2) );
|
||||
if (z0) *z0 = (int) clampimax( floor(z - uih/2) );
|
||||
if (x1) *x1 = (int) clampimax( ceil(x + uiw/2) );
|
||||
if (z1) *z1 = (int) clampimax( ceil(z + uih/2) );
|
||||
}
|
||||
|
||||
void MapView::update(int cnt)
|
||||
{
|
||||
updatecounter = cnt;
|
||||
@ -435,19 +464,12 @@ void MapView::onGoto()
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
static bool clampabs(qreal *x, qreal m)
|
||||
{
|
||||
if (*x < -m) { *x = -m; return true; }
|
||||
if (*x > +m) { *x = +m; return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
void MapView::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
//painter.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
|
||||
qreal fx = getX();
|
||||
qreal fz = getZ();
|
||||
@ -458,8 +480,11 @@ void MapView::paintEvent(QPaintEvent *)
|
||||
focusz = z_dst;
|
||||
blocks2pix = 1.0 / s_dst;
|
||||
}
|
||||
if (clampabs(&fx, INT_MAX-1024)) focusx = fx;
|
||||
if (clampabs(&fz, INT_MAX-1024)) focusz = fz;
|
||||
bool ok;
|
||||
fx = clampimax(fx, &ok);
|
||||
if (!ok) focusx = fx;
|
||||
fz = clampimax(fz, &ok);
|
||||
if (!ok) focusz = fz;
|
||||
|
||||
if (world)
|
||||
{
|
||||
@ -468,9 +493,7 @@ void MapView::paintEvent(QPaintEvent *)
|
||||
QPoint cur = mapFromGlobal(QCursor::pos());
|
||||
qreal bx = (cur.x() - width()/2.0) / blocks2pix + fx;
|
||||
qreal bz = (cur.y() - height()/2.0) / blocks2pix + fz;
|
||||
clampabs(&bx, INT_MAX-1024);
|
||||
clampabs(&bz, INT_MAX-1024);
|
||||
Pos p = {(int)bx, (int)bz};
|
||||
Pos p = {(int)clampimax(bx), (int)clampimax(bz)};
|
||||
overlay->pos = p;
|
||||
overlay->bname = world->getBiomeName(p);
|
||||
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
qreal getX();
|
||||
qreal getZ();
|
||||
qreal getScale() const { return 1.0 / blocks2pix; }
|
||||
void getVisible(int *x0, int *z0, int *x1, int *z1);
|
||||
|
||||
void deleteWorld();
|
||||
void refresh();
|
||||
@ -53,6 +54,7 @@ public:
|
||||
bool getShow(int stype);
|
||||
void setShow(int stype, bool v);
|
||||
void setConfig(const Config& config);
|
||||
void setShapes(const std::vector<Shape>& shapes);
|
||||
void refreshBiomeColors();
|
||||
|
||||
void timeout();
|
||||
@ -110,6 +112,8 @@ private:
|
||||
bool measure;
|
||||
int updatecounter;
|
||||
|
||||
std::vector<Shape> shapes;
|
||||
|
||||
bool sshow[D_STRUCT_NUM];
|
||||
LayerOpt lopt;
|
||||
Config config;
|
||||
|
@ -207,7 +207,7 @@ LabeledRange::LabeledRange(QWidget *parent, int vmin, int vmax)
|
||||
l->addWidget(minlabel);
|
||||
l->addWidget(slider);
|
||||
l->addWidget(maxlabel);
|
||||
l->setMargin(0);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
setLayout(l);
|
||||
|
||||
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(rangeChanged(void)));
|
||||
|
@ -72,7 +72,7 @@ void getScripts(QMap<uint64_t, QString>& scripts)
|
||||
QDirIterator it(dir, QDirIterator::NoIteratorFlags);
|
||||
while (it.hasNext())
|
||||
{
|
||||
QFileInfo f = it.next();
|
||||
QFileInfo f = QFileInfo(it.next());
|
||||
if (f.suffix() != "lua")
|
||||
continue;
|
||||
uint64_t hash = getScriptHash(f);
|
||||
@ -436,19 +436,32 @@ BlockRule *LuaHighlighter::nextBlockRule(const QString& text, int *pos, int *nex
|
||||
{
|
||||
BlockRule *rule = nullptr;
|
||||
int min = INT_MAX;
|
||||
int end = 0;
|
||||
for (int i = 0, n = blockrules.size(); i < n; i++)
|
||||
{
|
||||
#if 1
|
||||
QRegularExpressionMatch m = blockrules[i].start.match(text, *pos);
|
||||
if (m.hasMatch() && m.capturedStart() < min)
|
||||
{
|
||||
rule = &blockrules[i];
|
||||
min = m.capturedStart();
|
||||
end = m.capturedEnd();
|
||||
}
|
||||
}
|
||||
#else
|
||||
int s = blockrules[i].start.indexIn(text, *pos);
|
||||
if (s >= 0 && s < min)
|
||||
{
|
||||
rule = &blockrules[i];
|
||||
min = s;
|
||||
end = s + rule->start.matchedLength();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (rule)
|
||||
{
|
||||
*pos = min;
|
||||
*next = min + rule->start.matchedLength();
|
||||
*next = end;
|
||||
}
|
||||
return rule;
|
||||
}
|
||||
@ -467,6 +480,21 @@ void LuaHighlighter::highlightBlock(const QString& text)
|
||||
|
||||
while (rule)
|
||||
{
|
||||
#if 1
|
||||
QRegularExpressionMatch m = rule->end.match(text, match);
|
||||
if (m.hasMatch())
|
||||
{
|
||||
markFormated(&line, start, line.length() - start, rule->format);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
int end = m.capturedEnd();
|
||||
markFormated(&line, start, end - start, rule->format);
|
||||
start = end;
|
||||
rule = nextBlockRule(line, &start, &match);
|
||||
}
|
||||
#else
|
||||
int end = rule->end.indexIn(text, match);
|
||||
if (end == -1)
|
||||
{
|
||||
@ -480,6 +508,7 @@ void LuaHighlighter::highlightBlock(const QString& text)
|
||||
start = end;
|
||||
rule = nextBlockRule(line, &start, &match);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (rule)
|
||||
setCurrentBlockState(rule - &blockrules[0]);
|
||||
@ -489,6 +518,14 @@ void LuaHighlighter::highlightBlock(const QString& text)
|
||||
for (const Rule &rule : qAsConst(rules))
|
||||
{
|
||||
const QString *l = rule.overlay ? &text : &line;
|
||||
#if 1
|
||||
QRegularExpressionMatch m = rule.pattern.match(*l);
|
||||
while (m.hasMatch())
|
||||
{
|
||||
setFormat(m.capturedStart(), m.capturedLength(), rule.format);
|
||||
m = rule.pattern.match(*l, m.capturedEnd());
|
||||
}
|
||||
#else
|
||||
QRegExp expression(rule.pattern);
|
||||
int index = expression.indexIn(*l);
|
||||
while (index >= 0)
|
||||
@ -497,6 +534,7 @@ void LuaHighlighter::highlightBlock(const QString& text)
|
||||
setFormat(index, length, rule.format);
|
||||
index = expression.indexIn(*l, index + length);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -633,7 +671,7 @@ void ScriptEditor::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
const QString text = document()->toPlainText();
|
||||
const QChar linebreak = QChar(0x2029);
|
||||
QString ws = linebreak + QStringRef(&text, start, end-start).toString();
|
||||
QString ws = linebreak + text.mid(start, end-start);
|
||||
cursor.beginEditBlock();
|
||||
cursor.insertText(ws);
|
||||
cursor.endEditBlock();
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <QPlainTextEdit>
|
||||
#include <QMutex>
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "cubiomes/finders.h"
|
||||
|
||||
@ -60,7 +61,7 @@ int runCheckScript(
|
||||
|
||||
struct Rule
|
||||
{
|
||||
QRegExp pattern;
|
||||
QRegularExpression pattern;
|
||||
QTextCharFormat format;
|
||||
bool overlay;
|
||||
Rule() : pattern(),format(),overlay() {}
|
||||
@ -69,7 +70,7 @@ struct Rule
|
||||
};
|
||||
struct BlockRule
|
||||
{
|
||||
QRegExp start, end;
|
||||
QRegularExpression start, end;
|
||||
QTextCharFormat format;
|
||||
BlockRule() : start(), end(), format() {}
|
||||
BlockRule(const QString& s, const QString& e, const QTextCharFormat& f)
|
||||
|
546
src/search.cpp
546
src/search.cpp
@ -34,7 +34,7 @@ QString Condition::summary(bool aligntab) const
|
||||
}
|
||||
|
||||
QString cnts;
|
||||
if (ft.count)
|
||||
if (ft.branch == FilterInfo::BR_CLUST)
|
||||
cnts += MULTIPLY_CHAR + QString::number(count);
|
||||
if (skipref)
|
||||
cnts += "*";
|
||||
@ -73,10 +73,10 @@ QString Condition::summary(bool aligntab) const
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ft.coord)
|
||||
s += QString::asprintf("(%d,%d)", x1*ft.step, z1*ft.step);
|
||||
if (ft.area)
|
||||
s += QString::asprintf(",(%d,%d)", (x2+1)*ft.step-1, (z2+1)*ft.step-1);
|
||||
if (ft.loc & FilterInfo::LOC_1)
|
||||
s += QString::asprintf("(%d,%d)", x1, z1);
|
||||
if (ft.loc & FilterInfo::LOC_2)
|
||||
s += QString::asprintf(",(%d,%d)", x2, z2);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@ -95,15 +95,13 @@ bool Condition::versionUpgrade()
|
||||
memset(pad1, 0, sizeof(pad1));
|
||||
hash = 0;
|
||||
memset(deps, 0, sizeof(deps));
|
||||
memset(pad2, 0, sizeof(pad2));
|
||||
biomeId = biomeSize = tol = minmax = para = octave = 0;
|
||||
varflags = varbiome = varstart = 0;
|
||||
biomeId = biomeSize = tol = minmax = para = octave = step = 0;
|
||||
}
|
||||
else if (version == VER_2_3_0)
|
||||
if (version < VER_2_4_0)
|
||||
{
|
||||
varflags = varbiome = varstart = 0;
|
||||
}
|
||||
else if (version == VER_2_4_0)
|
||||
if (version < VER_3_4_0)
|
||||
{
|
||||
if (type == F_CLIMATE_MINMAX)
|
||||
{
|
||||
@ -126,6 +124,28 @@ bool Condition::versionUpgrade()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (version < VER_4_0_0)
|
||||
{
|
||||
const FilterInfo& ft = g_filterinfo.list[type];
|
||||
if (ft.grid > 1)
|
||||
{
|
||||
x1 = x1 * ft.grid;
|
||||
z1 = z1 * ft.grid;
|
||||
x2 = (x2+1) * ft.grid - 1;
|
||||
z2 = (z2+1) * ft.grid - 1;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case F_SPIRAL: step = 1; break;
|
||||
case F_SPIRAL_4: step = 4; type = F_SPIRAL; break;
|
||||
case F_SPIRAL_16: step = 16; type = F_SPIRAL; break;
|
||||
case F_SPIRAL_64: step = 64; type = F_SPIRAL; break;
|
||||
case F_SPIRAL_256: step = 256; type = F_SPIRAL; break;
|
||||
case F_SPIRAL_512: step = 512; type = F_SPIRAL; break;
|
||||
case F_SPIRAL_1024: step = 1024; type = F_SPIRAL; break;
|
||||
}
|
||||
}
|
||||
|
||||
version = VER_CURRENT;
|
||||
return true;
|
||||
}
|
||||
@ -312,66 +332,96 @@ int testTreeAt(
|
||||
ConditionTree *tree = env->condtree;
|
||||
Condition& c = tree->condvec[node];
|
||||
const std::vector<char>& branches = tree->references[c.save];
|
||||
int st;
|
||||
int st, br;
|
||||
int rx1, rz1, rx2, rz2;
|
||||
int sref;
|
||||
Pos pos;
|
||||
Pos inst[MAX_INSTANCES];
|
||||
const FilterInfo *finfo;
|
||||
|
||||
switch (c.type)
|
||||
{
|
||||
case F_SPIRAL_1: sref = 0; goto L_ref_pow2;
|
||||
case F_SPIRAL_4: sref = 2; goto L_ref_pow2;
|
||||
case F_SPIRAL_16: sref = 4; goto L_ref_pow2;
|
||||
case F_SPIRAL_64: sref = 6; goto L_ref_pow2;
|
||||
case F_SPIRAL_256: sref = 8; goto L_ref_pow2;
|
||||
case F_SPIRAL_512: sref = 9; goto L_ref_pow2;
|
||||
case F_SPIRAL_1024: sref = 10; goto L_ref_pow2;
|
||||
L_ref_pow2:
|
||||
rx1 = ((c.x1 << sref) + at.x) >> sref;
|
||||
rz1 = ((c.z1 << sref) + at.z) >> sref;
|
||||
rx2 = ((c.x2 << sref) + at.x) >> sref;
|
||||
rz2 = ((c.z2 << sref) + at.z) >> sref;
|
||||
case F_SPIRAL:
|
||||
|
||||
st = COND_FAILED;
|
||||
{ // run a spiral iterator over the rectangle
|
||||
int x = (rx1 + rx2) >> 1;
|
||||
int z = (rz1 + rz2) >> 1;
|
||||
int step = c.step ? c.step : 512;
|
||||
int rmax, x1, z1, x2, z2;
|
||||
if (c.rmax > 0)
|
||||
{
|
||||
rmax = c.rmax - 1;
|
||||
x1 = at.x - rmax;
|
||||
z1 = at.z - rmax;
|
||||
x2 = at.x + rmax;
|
||||
z2 = at.z + rmax;
|
||||
rmax = rmax * rmax + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rmax = 0;
|
||||
x1 = c.x1 + at.x;
|
||||
z1 = c.z1 + at.z;
|
||||
x2 = c.x2 + at.x;
|
||||
z2 = c.z2 + at.z;
|
||||
}
|
||||
|
||||
rx1 = floordiv(x1, step);
|
||||
rz1 = floordiv(z1, step);
|
||||
rx2 = floordiv(x2, step);
|
||||
rz2 = floordiv(z2, step);
|
||||
|
||||
int rx = (rx1 + rx2) >> 1;
|
||||
int rz = (rz1 + rz2) >> 1;
|
||||
int i = 0, dl = 1;
|
||||
int dx = 1, dz = 0;
|
||||
while (true)
|
||||
{
|
||||
bool inx = (x >= rx1 && x <= rx2);
|
||||
bool inz = (z >= rz1 && z <= rz2);
|
||||
bool inx = (rx >= rx1 && rx <= rx2);
|
||||
bool inz = (rz >= rz1 && rz <= rz2);
|
||||
if (!inx && !inz)
|
||||
break;
|
||||
if (inx && inz)
|
||||
{
|
||||
pos.x = (x << sref);
|
||||
pos.z = (z << sref);
|
||||
// children are combined via AND
|
||||
int sta = COND_OK;
|
||||
for (int b : branches)
|
||||
pos.x = rx * step;
|
||||
pos.z = rz * step;
|
||||
|
||||
bool inr = true;
|
||||
if (rmax)
|
||||
{
|
||||
int stb = testTreeAt(pos, env, pass, abort, path, b);
|
||||
if (*abort)
|
||||
return COND_FAILED;
|
||||
if (stb < sta)
|
||||
sta = stb;
|
||||
if (sta == COND_FAILED)
|
||||
break;
|
||||
int dx = pos.x - at.x;
|
||||
int dz = pos.z - at.z;
|
||||
int64_t rsq = dx*(int64_t)dx + dz*(int64_t)dz;
|
||||
inr = (rsq < rmax);
|
||||
}
|
||||
else if (pos.x < x1 || pos.x > x2 || pos.z < z1 || pos.z > z2)
|
||||
{
|
||||
inr = false;
|
||||
}
|
||||
|
||||
if (inr)
|
||||
{
|
||||
// children are combined via AND
|
||||
int sta = COND_OK;
|
||||
for (int b : branches)
|
||||
{
|
||||
int stb = testTreeAt(pos, env, pass, abort, path, b);
|
||||
if (*abort)
|
||||
return COND_FAILED;
|
||||
if (stb < sta)
|
||||
sta = stb;
|
||||
if (sta == COND_FAILED)
|
||||
break;
|
||||
}
|
||||
if (sta == COND_MAYBE_POS_VALID )
|
||||
sta = COND_MAYBE_POS_INVAL; // position moves => invalidate
|
||||
if (sta > st)
|
||||
st = sta;
|
||||
if (path && st >= COND_MAYBE_POS_VALID)
|
||||
path[c.save] = pos;
|
||||
if (st == COND_OK)
|
||||
return COND_OK;
|
||||
}
|
||||
if (sta == COND_MAYBE_POS_VALID )
|
||||
sta = COND_MAYBE_POS_INVAL; // position moves => invalidate
|
||||
if (sta > st)
|
||||
st = sta;
|
||||
if (path && st >= COND_MAYBE_POS_VALID)
|
||||
path[c.save] = pos;
|
||||
if (st == COND_OK)
|
||||
return COND_OK;
|
||||
}
|
||||
x += dx;
|
||||
z += dz;
|
||||
rx += dx;
|
||||
rz += dz;
|
||||
if (++i == dl)
|
||||
{
|
||||
i = 0;
|
||||
@ -412,7 +462,7 @@ int testTreeAt(
|
||||
return st;
|
||||
|
||||
|
||||
case F_LOGIC_OR:
|
||||
case F_LOGIC_OR: //qDebug() << at.x << at.z; return COND_FAILED;
|
||||
if (branches.empty())
|
||||
{
|
||||
if (path)
|
||||
@ -499,18 +549,48 @@ int testTreeAt(
|
||||
{
|
||||
if (icnt == 1)
|
||||
path[c.save] = *inst;
|
||||
else if (icnt > 1 && st == COND_OK)
|
||||
path[c.save] = *inst;
|
||||
else
|
||||
path[c.save].x = path[c.save].z = -1;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
finfo = g_filterinfo.list + c.type;
|
||||
if (c.count == 1 && (finfo->count || finfo->cat == CAT_QUAD))
|
||||
{ // condition has exactly one required instance so we can check each
|
||||
// of the found instances individually, i.e. this branch splits the
|
||||
// instances into independent subbranches (combined via OR)
|
||||
// quad conditions are also processed here since we want to
|
||||
// examine all instances without support for averaging
|
||||
|
||||
br = g_filterinfo.list[c.type].branch;
|
||||
|
||||
if (br == FilterInfo::BR_NONE || (br == FilterInfo::BR_CLUST && c.count != 1))
|
||||
{ // this condition cannot branch, position of multiple instances
|
||||
// will be averaged to a center point
|
||||
if (c.type == 0)
|
||||
{ // this is the root condition
|
||||
st = COND_OK;
|
||||
pos = at;
|
||||
}
|
||||
else
|
||||
{
|
||||
st = testCondAt(at, env, pass, abort, inst, NULL, &c);
|
||||
if (st == COND_FAILED || st == COND_MAYBE_POS_INVAL)
|
||||
return st;
|
||||
pos = inst[0]; // center point of instances
|
||||
}
|
||||
for (char b : branches)
|
||||
{
|
||||
if (st == COND_FAILED)
|
||||
break;
|
||||
int sta = testTreeAt(pos, env, pass, abort, path, b);
|
||||
if (*abort)
|
||||
return COND_FAILED;
|
||||
if (sta < st)
|
||||
st = sta;
|
||||
}
|
||||
if (path && st >= COND_MAYBE_POS_VALID)
|
||||
path[c.save] = pos;
|
||||
return st;
|
||||
}
|
||||
else
|
||||
{ // check each instance individually, splitting the instances into
|
||||
// independent subbranches that are combined via OR
|
||||
int icnt = MAX_INSTANCES;
|
||||
st = testCondAt(at, env, pass, abort, inst, &icnt, &c);
|
||||
if (st == COND_FAILED || st == COND_MAYBE_POS_INVAL)
|
||||
@ -548,35 +628,6 @@ int testTreeAt(
|
||||
path[c.save] = inst[iok];
|
||||
return st;
|
||||
}
|
||||
else
|
||||
{ // this condition cannot branch, position of multiple instances
|
||||
// will be averaged to a center point
|
||||
if (c.type == 0)
|
||||
{ // this is the root condition
|
||||
st = COND_OK;
|
||||
pos = at;
|
||||
}
|
||||
else
|
||||
{
|
||||
st = testCondAt(at, env, pass, abort, inst, NULL, &c);
|
||||
if (st == COND_FAILED || st == COND_MAYBE_POS_INVAL)
|
||||
return st;
|
||||
pos = inst[0]; // center point of instances
|
||||
}
|
||||
for (char b : branches)
|
||||
{
|
||||
if (st == COND_FAILED)
|
||||
break;
|
||||
int sta = testTreeAt(pos, env, pass, abort, path, b);
|
||||
if (*abort)
|
||||
return COND_FAILED;
|
||||
if (sta < st)
|
||||
st = sta;
|
||||
}
|
||||
if (path && st >= COND_MAYBE_POS_VALID)
|
||||
path[c.save] = pos;
|
||||
return st;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -895,6 +946,59 @@ static int f_track_minmax(void *data, int x, int z, double p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct sample_boime_t
|
||||
{
|
||||
Condition *cond;
|
||||
Pos at;
|
||||
int rmaxsq;
|
||||
int n;
|
||||
int64_t xsum;
|
||||
int64_t zsum;
|
||||
Pos *cent;
|
||||
int *imax;
|
||||
std::atomic_bool *stop;
|
||||
};
|
||||
|
||||
static int f_biome_sampler(Generator *g, int scale, int x, int y, int z, void *data)
|
||||
{
|
||||
sample_boime_t *info = (sample_boime_t*) data;
|
||||
if (info->stop && *info->stop)
|
||||
return -2;
|
||||
if (info->rmaxsq)
|
||||
{
|
||||
int dx = x - info->at.x;
|
||||
int dz = z - info->at.z;
|
||||
int64_t rsq = dx*(int64_t)dx + dz*(int64_t)dz;
|
||||
if (rsq >= info->rmaxsq)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int id = getBiomeAt(g, scale, x, y, z);
|
||||
uint64_t incl = 0, excl = 0;
|
||||
if (id < 128) {
|
||||
incl = info->cond->biomeToFind & (1ULL << id);
|
||||
excl = info->cond->biomeToExcl & (1ULL << id);
|
||||
} else {
|
||||
incl = info->cond->biomeToFindM & (1ULL << (id-128));
|
||||
excl = info->cond->biomeToExclM & (1ULL << (id-128));
|
||||
}
|
||||
if (incl != 0)
|
||||
{
|
||||
if (info->imax && info->n < *info->imax)
|
||||
info->cent[info->n] = Pos{x, z};
|
||||
info->xsum += x;
|
||||
info->zsum += z;
|
||||
info->n++;
|
||||
return 1;
|
||||
}
|
||||
if (excl != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Tests if a condition is satisfied with 'at' as origin for a search pass.
|
||||
* If sufficiently satisfied (check return value) then:
|
||||
* when 'imax' is NULL, the center position is written to 'cent[0]'
|
||||
@ -933,9 +1037,26 @@ testCondAt(
|
||||
return COND_FAILED;
|
||||
}
|
||||
|
||||
if (cond->rmax > 0)
|
||||
{
|
||||
rmax = cond->rmax - 1;
|
||||
x1 = at.x - rmax;
|
||||
z1 = at.z - rmax;
|
||||
x2 = at.x + rmax;
|
||||
z2 = at.z + rmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
rmax = 0;
|
||||
x1 = cond->x1 + at.x;
|
||||
z1 = cond->z1 + at.z;
|
||||
x2 = cond->x2 + at.x;
|
||||
z2 = cond->z2 + at.z;
|
||||
}
|
||||
|
||||
switch (cond->type)
|
||||
{
|
||||
case F_SPIRAL_1:
|
||||
case F_SPIRAL:
|
||||
case F_SPIRAL_4:
|
||||
case F_SPIRAL_16:
|
||||
case F_SPIRAL_64:
|
||||
@ -968,10 +1089,10 @@ testCondAt(
|
||||
n = sizeof(low20QuadHutBarely) / sizeof(uint64_t);
|
||||
|
||||
L_qh_any:
|
||||
rx1 = ((cond->x1 << 9) + at.x) >> 9;
|
||||
rz1 = ((cond->z1 << 9) + at.z) >> 9;
|
||||
rx2 = ((cond->x2 << 9) + at.x) >> 9;
|
||||
rz2 = ((cond->z2 << 9) + at.z) >> 9;
|
||||
rx1 = x1 >> 9;
|
||||
rz1 = z1 >> 9;
|
||||
rx2 = x2 >> 9;
|
||||
rz2 = z2 >> 9;
|
||||
|
||||
n = scanForQuads(
|
||||
sconf, 128, (env->seed) & MASK48, seeds, n, 20, sconf.salt,
|
||||
@ -1009,10 +1130,10 @@ L_qh_any:
|
||||
case F_QM_90: qual = 58*58*4 * 90 / 100;
|
||||
L_qm_any:
|
||||
|
||||
rx1 = ((cond->x1 << 9) + at.x) >> 9;
|
||||
rz1 = ((cond->z1 << 9) + at.z) >> 9;
|
||||
rx2 = ((cond->x2 << 9) + at.x) >> 9;
|
||||
rz2 = ((cond->z2 << 9) + at.z) >> 9;
|
||||
rx1 = x1 >> 9;
|
||||
rz1 = z1 >> 9;
|
||||
rx2 = x2 >> 9;
|
||||
rz2 = z2 >> 9;
|
||||
// we don't really need to check for more than one instance here
|
||||
n = scanForQuads(
|
||||
sconf, 160, (env->seed) & MASK48, g_qm_90,
|
||||
@ -1068,23 +1189,6 @@ L_qm_any:
|
||||
case F_ENDCITY:
|
||||
case F_GATEWAY:
|
||||
|
||||
if (cond->rmax > 0)
|
||||
{
|
||||
rmax = (cond->rmax-1) * (cond->rmax-1) + 1;
|
||||
x1 = at.x - cond->rmax;
|
||||
z1 = at.z - cond->rmax;
|
||||
x2 = at.x + cond->rmax;
|
||||
z2 = at.z + cond->rmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
rmax = 0;
|
||||
x1 = cond->x1 + at.x;
|
||||
z1 = cond->z1 + at.z;
|
||||
x2 = cond->x2 + at.x;
|
||||
z2 = cond->z2 + at.z;
|
||||
}
|
||||
|
||||
if (sconf.regionSize == 32)
|
||||
{
|
||||
rx1 = x1 >> 9;
|
||||
@ -1239,41 +1343,12 @@ L_qm_any:
|
||||
|
||||
case F_MINESHAFT:
|
||||
|
||||
if (cond->rmax > 0)
|
||||
{
|
||||
rmax = (cond->rmax-1) * (cond->rmax-1) + 1;
|
||||
x1 = at.x - cond->rmax;
|
||||
z1 = at.z - cond->rmax;
|
||||
x2 = at.x + cond->rmax;
|
||||
z2 = at.z + cond->rmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
rmax = 0;
|
||||
x1 = cond->x1 + at.x;
|
||||
z1 = cond->z1 + at.z;
|
||||
x2 = cond->x2 + at.x;
|
||||
z2 = cond->z2 + at.z;
|
||||
}
|
||||
rx1 = x1 >> 4;
|
||||
rz1 = z1 >> 4;
|
||||
rx2 = x2 >> 4;
|
||||
rz2 = z2 >> 4;
|
||||
|
||||
if (cond->count <= 0)
|
||||
{ // exclusion
|
||||
icnt = getMineshafts(env->mc, env->seed, rx1, rz1, rx2, rz2, cent, 1);
|
||||
if (icnt == 1 && cond->skipref && cent->x == at.x && cent->z == at.z)
|
||||
icnt = 0;
|
||||
cent->x = (x1 + x2) >> 1;
|
||||
cent->z = (z1 + z2) >> 1;
|
||||
if (icnt == 0)
|
||||
{
|
||||
if (imax) *imax = 1;
|
||||
return COND_OK;
|
||||
}
|
||||
}
|
||||
else if (imax)
|
||||
if (imax && cond->count > 0)
|
||||
{ // just check there are at least *inst (== cond->count) instances
|
||||
*imax = icnt =
|
||||
getMineshafts(env->mc, env->seed, rx1, rz1, rx2, rz2, cent, *imax);
|
||||
@ -1328,7 +1403,17 @@ L_qm_any:
|
||||
zt += p[i].z;
|
||||
j++;
|
||||
}
|
||||
if (j >= cond->count)
|
||||
if (cond->count <= 0)
|
||||
{
|
||||
cent->x = (x1 + x2) >> 1;
|
||||
cent->z = (z1 + z2) >> 1;
|
||||
if (j == 0)
|
||||
{
|
||||
if (imax) *imax = 1;
|
||||
return COND_OK;
|
||||
}
|
||||
}
|
||||
else if (j >= cond->count)
|
||||
{
|
||||
cent->x = xt / j;
|
||||
cent->z = zt / j;
|
||||
@ -1344,22 +1429,6 @@ L_qm_any:
|
||||
if (pass != PASS_FULL_64)
|
||||
return COND_MAYBE_POS_INVAL;
|
||||
|
||||
if (cond->rmax > 0)
|
||||
{
|
||||
rmax = (cond->rmax-1) * (cond->rmax-1) + 1;
|
||||
x1 = at.x - cond->rmax;
|
||||
z1 = at.z - cond->rmax;
|
||||
x2 = at.x + cond->rmax;
|
||||
z2 = at.z + cond->rmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
rmax = 0;
|
||||
x1 = cond->x1 + at.x;
|
||||
z1 = cond->z1 + at.z;
|
||||
x2 = cond->x2 + at.x;
|
||||
z2 = cond->z2 + at.z;
|
||||
}
|
||||
if (*abort) return COND_FAILED;
|
||||
env->init4Dim(DIM_OVERWORLD);
|
||||
pc = getSpawn(&env->g);
|
||||
@ -1398,10 +1467,6 @@ L_qm_any:
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = cond->x1 + at.x;
|
||||
z1 = cond->z1 + at.z;
|
||||
x2 = cond->x2 + at.x;
|
||||
z2 = cond->z2 + at.z;
|
||||
if (pc.x < x1 || pc.x > x2 || pc.z < z1 || pc.z > z2)
|
||||
return COND_FAILED;
|
||||
}
|
||||
@ -1564,10 +1629,10 @@ L_qm_any:
|
||||
|
||||
case F_SLIME:
|
||||
|
||||
rx1 = ((cond->x1 << 4) + at.x) >> 4;
|
||||
rz1 = ((cond->z1 << 4) + at.z) >> 4;
|
||||
rx2 = ((cond->x2 << 4) + at.x) >> 4;
|
||||
rz2 = ((cond->z2 << 4) + at.z) >> 4;
|
||||
rx1 = x1 >> 4;
|
||||
rz1 = z1 >> 4;
|
||||
rx2 = x2 >> 4;
|
||||
rz2 = z2 >> 4;
|
||||
|
||||
icnt = 0;
|
||||
xt = zt = 0;
|
||||
@ -1602,8 +1667,8 @@ L_qm_any:
|
||||
}
|
||||
if (cond->count == 0)
|
||||
{ // exclusion filter
|
||||
cent->x = (rx1 + rx2) << 3;
|
||||
cent->z = (rz1 + rz2) << 3;
|
||||
cent->x = (x1 + x2) >> 1;
|
||||
cent->z = (z1 + z2) >> 1;
|
||||
if (imax) *imax = 1;
|
||||
return COND_OK;
|
||||
}
|
||||
@ -1613,13 +1678,65 @@ L_qm_any:
|
||||
}
|
||||
else if (icnt)
|
||||
{
|
||||
cent->x = (xt << 4) / icnt;
|
||||
cent->z = (zt << 4) / icnt;
|
||||
cent->x = (xt << 4) / icnt + 8;
|
||||
cent->z = (zt << 4) / icnt + 8;
|
||||
}
|
||||
if (icnt >= cond->count)
|
||||
return COND_OK;
|
||||
return COND_FAILED;
|
||||
|
||||
|
||||
case F_BIOME_SAMPLE:
|
||||
|
||||
if (pass != PASS_FULL_64)
|
||||
return COND_MAYBE_POS_INVAL;
|
||||
if (cond->confidence <= 0 || cond->confidence >= 1)
|
||||
return COND_FAILED;
|
||||
if (cond->converage <= 0 || cond->converage > 1)
|
||||
return COND_FAILED;
|
||||
s = finfo.pow2;
|
||||
rx1 = x1 >> s;
|
||||
rz1 = z1 >> s;
|
||||
rx2 = x2 >> s;
|
||||
rz2 = z2 >> s;
|
||||
{
|
||||
int w = rx2 - rx1 + 1;
|
||||
int h = rz2 - rz1 + 1;
|
||||
Range r = {1<<s, rx1, rz1, w, h, s == 0 ? cond->y : cond->y >> 2, 1};
|
||||
env->init4Dim(DIM_OVERWORLD);
|
||||
sample_boime_t sample;
|
||||
sample.cond = cond;
|
||||
sample.at = at;
|
||||
sample.n = 0;
|
||||
sample.xsum = 0;
|
||||
sample.zsum = 0;
|
||||
sample.imax = imax;
|
||||
sample.cent = cent;
|
||||
sample.stop = abort;
|
||||
|
||||
uint64_t rng;
|
||||
setSeed(&rng, env->seed);
|
||||
|
||||
int ok = monteCarloBiomes(
|
||||
&env->g, r, &rng, cond->converage, cond->confidence,
|
||||
&f_biome_sampler, &sample);
|
||||
if (imax)
|
||||
{
|
||||
*imax = sample.n;
|
||||
}
|
||||
else if (sample.n)
|
||||
{
|
||||
cent->x = sample.xsum / sample.n + 2;
|
||||
cent->z = sample.zsum / sample.n + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*cent = at;
|
||||
}
|
||||
return ok == 1 ? COND_OK : COND_FAILED;
|
||||
}
|
||||
return COND_FAILED;
|
||||
|
||||
// biome filters reference specific layers
|
||||
// MAYBE: options for layers in different versions?
|
||||
case F_BIOME:
|
||||
@ -1632,12 +1749,12 @@ L_qm_any:
|
||||
if (env->mc >= MC_1_18)
|
||||
return COND_FAILED;
|
||||
s = finfo.pow2;
|
||||
rx1 = ((cond->x1 << s) + at.x) >> s;
|
||||
rz1 = ((cond->z1 << s) + at.z) >> s;
|
||||
rx2 = ((cond->x2 << s) + at.x) >> s;
|
||||
rz2 = ((cond->z2 << s) + at.z) >> s;
|
||||
cent->x = ((rx1 + rx2) << s) >> 1;
|
||||
cent->z = ((rz1 + rz2) << s) >> 1;
|
||||
rx1 = x1 >> s;
|
||||
rz1 = z1 >> s;
|
||||
rx2 = x2 >> s;
|
||||
rz2 = z2 >> s;
|
||||
cent->x = (x1 + x2) >> 1;
|
||||
cent->z = (z1 + z2) >> 1;
|
||||
if (pass == PASS_FAST_48)
|
||||
return COND_MAYBE_POS_VALID;
|
||||
if (pass == PASS_FULL_48)
|
||||
@ -1663,12 +1780,12 @@ L_qm_any:
|
||||
case F_TEMPS:
|
||||
if (env->mc >= MC_1_18)
|
||||
return COND_FAILED;
|
||||
rx1 = ((cond->x1 << 10) + at.x) >> 10;
|
||||
rz1 = ((cond->z1 << 10) + at.z) >> 10;
|
||||
rx2 = ((cond->x2 << 10) + at.x) >> 10;
|
||||
rz2 = ((cond->z2 << 10) + at.z) >> 10;
|
||||
cent->x = ((rx1 + rx2) << 10) >> 1;
|
||||
cent->z = ((rz1 + rz2) << 10) >> 1;
|
||||
rx1 = x1 >> 10;
|
||||
rz1 = z1 >> 10;
|
||||
rx2 = x2 >> 10;
|
||||
rz2 = z2 >> 10;
|
||||
cent->x = (x1 + x2) >> 1;
|
||||
cent->z = (z1 + z2) >> 1;
|
||||
if (pass != PASS_FULL_64)
|
||||
return COND_MAYBE_POS_VALID;
|
||||
env->init4Dim(DIM_OVERWORLD);
|
||||
@ -1692,12 +1809,12 @@ L_qm_any:
|
||||
|
||||
L_noise_biome:
|
||||
s = finfo.pow2;
|
||||
rx1 = ((cond->x1 << s) + at.x) >> s;
|
||||
rz1 = ((cond->z1 << s) + at.z) >> s;
|
||||
rx2 = ((cond->x2 << s) + at.x) >> s;
|
||||
rz2 = ((cond->z2 << s) + at.z) >> s;
|
||||
cent->x = ((rx1 + rx2) << s) >> 1;
|
||||
cent->z = ((rz1 + rz2) << s) >> 1;
|
||||
rx1 = x1 >> s;
|
||||
rz1 = z1 >> s;
|
||||
rx2 = x2 >> s;
|
||||
rz2 = z2 >> s;
|
||||
cent->x = (x1 + x2) >> 1;
|
||||
cent->z = (z1 + z2) >> 1;
|
||||
if (pass == PASS_FAST_48)
|
||||
return COND_MAYBE_POS_VALID;
|
||||
// the Nether and End require only the 48-bit seed
|
||||
@ -1720,13 +1837,13 @@ L_noise_biome:
|
||||
if (pass == PASS_FULL_64)
|
||||
{
|
||||
s = finfo.pow2;
|
||||
rx1 = ((cond->x1 << s) + at.x) >> s;
|
||||
rz1 = ((cond->z1 << s) + at.z) >> s;
|
||||
rx2 = ((cond->x2 << s) + at.x) >> s;
|
||||
rz2 = ((cond->z2 << s) + at.z) >> s;
|
||||
rx1 = x1 >> s;
|
||||
rz1 = z1 >> s;
|
||||
rx2 = x2 >> s;
|
||||
rz2 = z2 >> s;
|
||||
int w = rx2 - rx1 + 1;
|
||||
int h = rz2 - rz1 + 1;
|
||||
Range r = {finfo.step, rx1, rz1, w, h, cond->y >> 2, 1};
|
||||
Range r = {1<<s, rx1, rz1, w, h, cond->y >> 2, 1};
|
||||
env->init4Dim(DIM_OVERWORLD);
|
||||
|
||||
if (cond->count == 0)
|
||||
@ -1737,8 +1854,8 @@ L_noise_biome:
|
||||
);
|
||||
if (icnt == 0)
|
||||
{
|
||||
cent->x = (rx1 + rx2) << 1;
|
||||
cent->z = (rz1 + rz2) << 1;
|
||||
cent->x = (x1 + x2) >> 1;
|
||||
cent->z = (z1 + z2) >> 1;
|
||||
if (imax) *imax = 1;
|
||||
return COND_OK;
|
||||
}
|
||||
@ -1782,8 +1899,8 @@ L_noise_biome:
|
||||
}
|
||||
if (j >= cond->count)
|
||||
{
|
||||
cent->x = xt / j;
|
||||
cent->z = zt / j;
|
||||
cent->x = xt / j + (1 << s) / 2;
|
||||
cent->z = zt / j + (1 << s) / 2;
|
||||
return COND_OK;
|
||||
}
|
||||
}
|
||||
@ -1794,10 +1911,10 @@ L_noise_biome:
|
||||
case F_CLIMATE_MINMAX:
|
||||
if (env->mc < MC_1_18 || cond->para >= NP_MAX)
|
||||
return COND_FAILED;
|
||||
rx1 = ((cond->x1 << 2) + at.x) >> 2;
|
||||
rz1 = ((cond->z1 << 2) + at.z) >> 2;
|
||||
rx2 = ((cond->x2 << 2) + at.x) >> 2;
|
||||
rz2 = ((cond->z2 << 2) + at.z) >> 2;
|
||||
rx1 = x1 >> 2;
|
||||
rz1 = z1 >> 2;
|
||||
rx2 = x2 >> 2;
|
||||
rz2 = z2 >> 2;
|
||||
if (pass != PASS_FULL_64)
|
||||
return COND_MAYBE_POS_INVAL;
|
||||
{
|
||||
@ -1836,12 +1953,12 @@ L_noise_biome:
|
||||
case F_CLIMATE_NOISE:
|
||||
if (env->mc < MC_1_18)
|
||||
return COND_FAILED;
|
||||
rx1 = ((cond->x1 << 2) + at.x) >> 2;
|
||||
rz1 = ((cond->z1 << 2) + at.z) >> 2;
|
||||
rx2 = ((cond->x2 << 2) + at.x) >> 2;
|
||||
rz2 = ((cond->z2 << 2) + at.z) >> 2;
|
||||
cent->x = ((rx1 + rx2) << 2) >> 1;
|
||||
cent->z = ((rz1 + rz2) << 2) >> 1;
|
||||
rx1 = x1 >> 2;
|
||||
rz1 = z1 >> 2;
|
||||
rx2 = x2 >> 2;
|
||||
rz2 = z2 >> 2;
|
||||
cent->x = (x1 + x2) >> 1;
|
||||
cent->z = (z1 + z2) >> 1;
|
||||
if (pass != PASS_FULL_64)
|
||||
return COND_MAYBE_POS_VALID;
|
||||
{
|
||||
@ -1897,10 +2014,10 @@ L_noise_biome:
|
||||
|
||||
|
||||
case F_HEIGHT:
|
||||
rx1 = ((cond->x1 << 2) + at.x) >> 2;
|
||||
rz1 = ((cond->z1 << 2) + at.z) >> 2;
|
||||
cent->x = rx1 << 2;
|
||||
cent->z = rz1 << 2;
|
||||
rx1 = x1 >> 2;
|
||||
rz1 = z1 >> 2;
|
||||
cent->x = x1;
|
||||
cent->z = z1;
|
||||
if (pass != PASS_FULL_64)
|
||||
return COND_MAYBE_POS_VALID;
|
||||
env->init4Dim(DIM_OVERWORLD);
|
||||
@ -2015,3 +2132,4 @@ void findQuadStructs(int styp, Generator *g, QVector<QuadInfo> *out)
|
||||
|
||||
|
||||
|
||||
|
||||
|
215
src/search.h
215
src/search.h
@ -69,7 +69,7 @@ enum
|
||||
F_PORTALN,
|
||||
F_GATEWAY,
|
||||
F_MINESHAFT,
|
||||
F_SPIRAL_1,
|
||||
F_SPIRAL,
|
||||
F_SPIRAL_16,
|
||||
F_SPIRAL_64,
|
||||
F_SPIRAL_256,
|
||||
@ -91,22 +91,35 @@ enum
|
||||
F_LUA,
|
||||
F_WELL,
|
||||
F_TRAILS,
|
||||
F_BIOME_SAMPLE,
|
||||
// new filters should be added here at the end to keep some downwards compatibility
|
||||
FILTER_MAX,
|
||||
};
|
||||
|
||||
struct FilterInfo
|
||||
{
|
||||
enum {
|
||||
LOC_1 = 1, LOC_2 = 2, LOC_R = 4,
|
||||
LOC_NIL = 0x0,
|
||||
LOC_POS = 0x1,
|
||||
LOC_REC = 0x3,
|
||||
LOC_RAD = 0x7,
|
||||
};
|
||||
enum {
|
||||
BR_NONE = 0, // one position - no branching
|
||||
BR_FIRST = 1, // choose only first, no branching
|
||||
BR_SPLIT = 2, // branches are examined separately
|
||||
BR_CLUST = 3, // allow clustering to avoid branching
|
||||
};
|
||||
|
||||
int cat; // seed source category
|
||||
bool dep64; // depends on 64-bit seed
|
||||
bool coord; // requires coordinate entry
|
||||
bool area; // requires area entry
|
||||
bool rmax; // supports radial range
|
||||
int loc;
|
||||
int layer; // associated generator layer
|
||||
int stype; // structure type
|
||||
int step; // coordinate multiplier
|
||||
int pow2; // bit position of step
|
||||
int count; // can have instances
|
||||
int grid; // coordinate multiplier
|
||||
int pow2; // bit position of grid
|
||||
int branch; // branching behaviour
|
||||
int mcmin; // minimum version
|
||||
int mcmax; // maximum version
|
||||
int dim; // dimension
|
||||
@ -118,7 +131,7 @@ struct FilterInfo
|
||||
};
|
||||
|
||||
// global table of filter data (as constants with enum indexing)
|
||||
static const struct FilterList
|
||||
static const struct FilterList : private FilterInfo
|
||||
{
|
||||
FilterInfo list[FILTER_MAX];
|
||||
|
||||
@ -127,13 +140,13 @@ static const struct FilterList
|
||||
int disp = 0; // display order
|
||||
|
||||
list[F_SELECT] = FilterInfo{
|
||||
CAT_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, MC_UNDEF, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_NONE, 0, LOC_NIL, 0, 0, 0, 0, BR_NONE, MC_UNDEF, MC_NEWEST, 0, 0, disp++,
|
||||
NULL,
|
||||
"",
|
||||
""
|
||||
};
|
||||
list[F_LOGIC_OR] = FilterInfo{
|
||||
CAT_HELPER, 0, 0, 0, 0, 0, 0, 1, 0, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
CAT_HELPER, 0, LOC_NIL, 0, 0, 1, 0, BR_NONE, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"helper",
|
||||
QT_TRANSLATE_NOOP("Filter", "OR logic gate"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -142,7 +155,7 @@ static const struct FilterList
|
||||
"defined, it defaults to true.")
|
||||
};
|
||||
list[F_LOGIC_NOT] = FilterInfo{
|
||||
CAT_HELPER, 0, 0, 0, 0, 0, 0, 1, 0, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
CAT_HELPER, 0, LOC_NIL, 0, 0, 1, 0, BR_NONE, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"helper",
|
||||
QT_TRANSLATE_NOOP("Filter", "NOT logic gate"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -151,79 +164,41 @@ static const struct FilterList
|
||||
"defined, it defaults to true.")
|
||||
};
|
||||
list[F_LUA] = FilterInfo{
|
||||
CAT_HELPER, 0, 0, 0, 0, 0, 0, 1, 0, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
CAT_HELPER, 0, LOC_NIL, 0, 0, 1, 0, BR_NONE, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"helper",
|
||||
QT_TRANSLATE_NOOP("Filter", "Lua"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Define custom conditions using Lua scripts.")
|
||||
};
|
||||
list[F_SCALE_TO_NETHER] = FilterInfo{
|
||||
CAT_HELPER, 0, 0, 0, 0, 0, 0, 1, 0, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
CAT_HELPER, 0, LOC_NIL, 0, 0, 1, 0, BR_NONE, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"portal_lit",
|
||||
QT_TRANSLATE_NOOP("Filter", "Coordinate factor x/8"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Divides relative location by 8, from Overworld to Nether.")
|
||||
};
|
||||
list[F_SCALE_TO_OVERWORLD] = FilterInfo{
|
||||
CAT_HELPER, 0, 0, 0, 0, 0, 0, 1, 0, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
CAT_HELPER, 0, LOC_NIL, 0, 0, 1, 0, BR_NONE, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"portal_lit",
|
||||
QT_TRANSLATE_NOOP("Filter", "Coordinate factor x*8"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Multiplies relative location by 8, from Nether to Overworld.")
|
||||
};
|
||||
const char *spiral_desc = QT_TRANSLATE_NOOP("Filter",
|
||||
list[F_SPIRAL] = FilterInfo{
|
||||
CAT_HELPER, 0, LOC_RAD, 0, 0, 1, 0, BR_FIRST, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"reference",
|
||||
QT_TRANSLATE_NOOP("Filter", "Spiral iterator"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"<html><head/><body>"
|
||||
"Spiral iterator conditions can be used to move a testing position across "
|
||||
"a given area using a certain step size. Other conditions that refer to it "
|
||||
"as a relative location will be checked at each step. The iteration is "
|
||||
"performed in a spiral, so positions closer to the center get priority."
|
||||
"</body></html>"
|
||||
);
|
||||
list[F_SPIRAL_1] = FilterInfo{
|
||||
CAT_HELPER, 0, 1, 1, 0, 0, 0, 1, 0, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"reference",
|
||||
QT_TRANSLATE_NOOP("Filter", "Spiral iterator 1:1"),
|
||||
spiral_desc
|
||||
};
|
||||
list[F_SPIRAL_4] = FilterInfo{
|
||||
CAT_HELPER, 0, 1, 1, 0, 0, 0, 4, 2, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"reference",
|
||||
QT_TRANSLATE_NOOP("Filter", "Spiral iterator 1:4"),
|
||||
spiral_desc
|
||||
};
|
||||
list[F_SPIRAL_16] = FilterInfo{
|
||||
CAT_HELPER, 0, 1, 1, 0, 0, 0, 16, 4, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"reference",
|
||||
QT_TRANSLATE_NOOP("Filter", "Spiral iterator 1:16"),
|
||||
spiral_desc
|
||||
};
|
||||
list[F_SPIRAL_64] = FilterInfo{
|
||||
CAT_HELPER, 0, 1, 1, 0, 0, 0, 64, 6, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"reference",
|
||||
QT_TRANSLATE_NOOP("Filter", "Spiral iterator 1:64"),
|
||||
spiral_desc
|
||||
};
|
||||
list[F_SPIRAL_256] = FilterInfo{
|
||||
CAT_HELPER, 0, 1, 1, 0, 0, 0, 256, 8, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"reference",
|
||||
QT_TRANSLATE_NOOP("Filter", "Spiral iterator 1:256"),
|
||||
spiral_desc
|
||||
};
|
||||
list[F_SPIRAL_512] = FilterInfo{
|
||||
CAT_HELPER, 0, 1, 1, 0, 0, 0, 512, 9, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"reference",
|
||||
QT_TRANSLATE_NOOP("Filter", "Spiral iterator 1:512"),
|
||||
spiral_desc
|
||||
};
|
||||
list[F_SPIRAL_1024] = FilterInfo{
|
||||
CAT_HELPER, 0, 1, 1, 0, 0, 0, 1024, 10, 0, MC_UNDEF, MC_NEWEST, DIM_UNDEF, 0, disp++,
|
||||
"reference",
|
||||
QT_TRANSLATE_NOOP("Filter", "Spiral iterator 1:1024"),
|
||||
spiral_desc
|
||||
"</body></html>")
|
||||
};
|
||||
|
||||
list[F_QH_IDEAL] = FilterInfo{
|
||||
CAT_QUAD, 0, 1, 1, 0, 0, Swamp_Hut, 512, 9, 0, MC_1_4, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_QUAD, 0, LOC_REC, 0, Swamp_Hut, 512, 9, BR_FIRST, MC_1_4, MC_NEWEST, 0, 0, disp++,
|
||||
"quad",
|
||||
QT_TRANSLATE_NOOP("Filter", "Quad-hut (ideal)"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -232,7 +207,7 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_QH_CLASSIC] = FilterInfo{
|
||||
CAT_QUAD, 0, 1, 1, 0, 0, Swamp_Hut, 512, 9, 0, MC_1_4, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_QUAD, 0, LOC_REC, 0, Swamp_Hut, 512, 9, BR_FIRST, MC_1_4, MC_NEWEST, 0, 0, disp++,
|
||||
"quad",
|
||||
QT_TRANSLATE_NOOP("Filter", "Quad-hut (classic)"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -243,7 +218,7 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_QH_NORMAL] = FilterInfo{
|
||||
CAT_QUAD, 0, 1, 1, 0, 0, Swamp_Hut, 512, 9, 0, MC_1_4, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_QUAD, 0, LOC_REC, 0, Swamp_Hut, 512, 9, BR_FIRST, MC_1_4, MC_NEWEST, 0, 0, disp++,
|
||||
"quad",
|
||||
QT_TRANSLATE_NOOP("Filter", "Quad-hut (normal)"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -254,7 +229,7 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_QH_BARELY] = FilterInfo{
|
||||
CAT_QUAD, 0, 1, 1, 0, 0, Swamp_Hut, 512, 9, 0, MC_1_4, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_QUAD, 0, LOC_REC, 0, Swamp_Hut, 512, 9, BR_FIRST, MC_1_4, MC_NEWEST, 0, 0, disp++,
|
||||
"quad",
|
||||
QT_TRANSLATE_NOOP("Filter", "Quad-hut (barely)"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -264,7 +239,7 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_QM_95] = FilterInfo{
|
||||
CAT_QUAD, 0, 1, 1, 0, 0, Monument, 512, 9, 0, MC_1_8, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_QUAD, 0, LOC_REC, 0, Monument, 512, 9, BR_FIRST, MC_1_8, MC_NEWEST, 0, 0, disp++,
|
||||
"quad",
|
||||
QT_TRANSLATE_NOOP("Filter", "Quad-ocean-monument (>95%)"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -274,7 +249,7 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_QM_90] = FilterInfo{
|
||||
CAT_QUAD, 0, 1, 1, 0, 0, Monument, 512, 9, 0, MC_1_8, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_QUAD, 0, LOC_REC, 0, Monument, 512, 9, BR_FIRST, MC_1_8, MC_NEWEST, 0, 0, disp++,
|
||||
"quad",
|
||||
QT_TRANSLATE_NOOP("Filter", "Quad-ocean-monument (>90%)"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -283,8 +258,17 @@ static const struct FilterList
|
||||
"location.")
|
||||
};
|
||||
|
||||
list[F_BIOME_SAMPLE] = FilterInfo{
|
||||
CAT_BIOMES, 1, LOC_RAD, 0, 0, 1, 0, BR_SPLIT, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Biome samples"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Samples biomes in a given area to find if a proportion of the "
|
||||
"biomes match a set of allowed biomes.")
|
||||
};
|
||||
|
||||
list[F_BIOME] = FilterInfo{
|
||||
CAT_BIOMES, 1, 1, 1, 0, L_VORONOI_1, 0, 1, 0, 0, MC_B1_7, MC_1_17, 0, 1, disp++, // disable for 1.18
|
||||
CAT_BIOMES, 1, LOC_REC, L_VORONOI_1, 0, 1, 0, BR_NONE, MC_B1_7, MC_1_17, 0, 1, disp++, // disable for 1.18
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Biomes 1:1"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -293,7 +277,7 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_BIOME_4] = FilterInfo{
|
||||
CAT_BIOMES, 1, 1, 1, 0, 0, 0, 4, 2, 0, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
CAT_BIOMES, 1, LOC_REC, 0, 0, 4, 2, BR_NONE, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Biomes 1:4"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -301,7 +285,7 @@ static const struct FilterList
|
||||
"discard those that have biomes that are explicitly excluded (-).")
|
||||
};
|
||||
list[F_BIOME_16] = FilterInfo{
|
||||
CAT_BIOMES, 1, 1, 1, 0, 0, 0, 16, 4, 0, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
CAT_BIOMES, 1, LOC_REC, 0, 0, 16, 4, BR_NONE, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Biomes 1:16"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -309,7 +293,7 @@ static const struct FilterList
|
||||
"discard those that have biomes that are explicitly excluded (-).")
|
||||
};
|
||||
list[F_BIOME_64] = FilterInfo{
|
||||
CAT_BIOMES, 1, 1, 1, 0, 0, 0, 64, 6, 0, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
CAT_BIOMES, 1, LOC_REC, 0, 0, 64, 6, BR_NONE, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Biomes 1:64"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -317,7 +301,7 @@ static const struct FilterList
|
||||
"discard those that have biomes that are explicitly excluded (-).")
|
||||
};
|
||||
list[F_BIOME_256] = FilterInfo{
|
||||
CAT_BIOMES, 1, 1, 1, 0, 0, 0, 256, 8, 0, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
CAT_BIOMES, 1, LOC_REC, 0, 0, 256, 8, BR_NONE, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Biomes 1:256"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -326,7 +310,7 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_BIOME_4_RIVER] = FilterInfo{
|
||||
CAT_BIOMES, 1, 1, 1, 0, L_RIVER_MIX_4, 0, 4, 2, 0, MC_1_13, MC_1_17, 0, 0, disp++,
|
||||
CAT_BIOMES, 1, LOC_REC, L_RIVER_MIX_4, 0, 4, 2, BR_NONE, MC_1_13, MC_1_17, 0, 0, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Biomes 1:4 RIVER"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -336,7 +320,7 @@ static const struct FilterList
|
||||
"This layer does not generate ocean variants.")
|
||||
};
|
||||
list[F_BIOME_256_OTEMP] = FilterInfo{
|
||||
CAT_BIOMES, 0, 1, 1, 0, L_OCEAN_TEMP_256, 0, 256, 8, 0, MC_1_13, MC_1_17, 0, 0, disp++,
|
||||
CAT_BIOMES, 0, LOC_REC, L_OCEAN_TEMP_256, 0, 256, 8, BR_NONE, MC_1_13, MC_1_17, 0, 0, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Biomes 1:256 O.TEMP"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -346,7 +330,7 @@ static const struct FilterList
|
||||
"This generation layer depends only on the lower 48-bits of the seed.")
|
||||
};
|
||||
list[F_CLIMATE_NOISE] = FilterInfo{
|
||||
CAT_BIOMES, 0, 1, 1, 0, 0, 0, 4, 2, 0, MC_1_18, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_BIOMES, 0, LOC_REC, 0, 0, 4, 2, BR_NONE, MC_1_18, MC_NEWEST, 0, 0, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Climate parameters 1:4"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -354,28 +338,28 @@ static const struct FilterList
|
||||
"the specified area should cover.")
|
||||
};
|
||||
list[F_CLIMATE_MINMAX] = FilterInfo{
|
||||
CAT_BIOMES, 0, 1, 1, 0, 0, 0, 4, 2, 0, MC_1_18, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_BIOMES, 0, LOC_REC, 0, 0, 4, 2, BR_NONE, MC_1_18, MC_NEWEST, 0, 0, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Locate climate extreme 1:4"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Finds the location where a climate parameter reaches its minimum or maximum.")
|
||||
};
|
||||
list[F_BIOME_CENTER] = FilterInfo{
|
||||
CAT_BIOMES, 1, 1, 1, 0, 0, 0, 4, 2, 1, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
CAT_BIOMES, 1, LOC_REC, 0, 0, 4, 2, BR_CLUST, MC_B1_7, MC_NEWEST, 0, 1, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Locate biome center 1:4"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Finds the center position of a given biome.")
|
||||
};
|
||||
list[F_BIOME_CENTER_256] = FilterInfo{
|
||||
CAT_BIOMES, 1, 1, 1, 0, 0, 0, 256, 8, 1, MC_B1_7, MC_1_17, 0, 1, disp++,
|
||||
CAT_BIOMES, 1, LOC_REC, 0, 0, 256, 8, BR_CLUST, MC_B1_7, MC_1_17, 0, 1, disp++,
|
||||
"map",
|
||||
QT_TRANSLATE_NOOP("Filter", "Locate biome center 1:256"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Finds the center position of a given biome. Based on the 1:256 biome layer.")
|
||||
};
|
||||
list[F_TEMPS] = FilterInfo{
|
||||
CAT_BIOMES, 1, 1, 1, 0, 0, 0, 1024, 10, 0, MC_1_7, MC_1_17, 0, 0, disp++,
|
||||
CAT_BIOMES, 1, LOC_REC, 0, 0, 1024, 10, BR_NONE, MC_1_7, MC_1_17, 0, 0, disp++,
|
||||
"tempcat",
|
||||
QT_TRANSLATE_NOOP("Filter", "Temperature categories"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -383,35 +367,35 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_BIOME_NETHER_1] = FilterInfo{
|
||||
CAT_NETHER, 1, 1, 1, 0, 0, 0, 1, 0, 0, MC_1_16_1, 0, -1, 1, disp++, // disabled
|
||||
CAT_NETHER, 1, LOC_REC, 0, 0, 1, 0, BR_NONE, MC_1_16_1, 0, -1, 1, disp++, // disabled
|
||||
"nether",
|
||||
QT_TRANSLATE_NOOP("Filter", "Nether biomes 1:1 (disabled)"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Nether biomes after voronoi scaling to 1:1.")
|
||||
};
|
||||
list[F_BIOME_NETHER_4] = FilterInfo{
|
||||
CAT_NETHER, 0, 1, 1, 0, 0, 0, 4, 2, 0, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
CAT_NETHER, 0, LOC_REC, 0, 0, 4, 2, BR_NONE, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
"nether",
|
||||
QT_TRANSLATE_NOOP("Filter", "Nether biomes 1:4"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Nether biomes with normal noise sampling at scale 1:4.")
|
||||
};
|
||||
list[F_BIOME_NETHER_16] = FilterInfo{
|
||||
CAT_NETHER, 0, 1, 1, 0, 0, 0, 16, 4, 0, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
CAT_NETHER, 0, LOC_REC, 0, 0, 16, 4, BR_NONE, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
"nether",
|
||||
QT_TRANSLATE_NOOP("Filter", "Nether biomes 1:16"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Nether biomes, but only sampled at scale 1:16.")
|
||||
};
|
||||
list[F_BIOME_NETHER_64] = FilterInfo{
|
||||
CAT_NETHER, 0, 1, 1, 0, 0, 0, 64, 6, 0, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
CAT_NETHER, 0, LOC_REC, 0, 0, 64, 6, BR_NONE, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
"nether",
|
||||
QT_TRANSLATE_NOOP("Filter", "Nether biomes 1:64"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"Nether biomes, but only sampled at scale 1:64.")
|
||||
};
|
||||
list[F_BIOME_NETHER_256] = FilterInfo{
|
||||
CAT_NETHER, 0, 1, 1, 0, 0, 0, 256, 8, 0, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
CAT_NETHER, 0, LOC_REC, 0, 0, 256, 8, BR_NONE, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
"nether",
|
||||
QT_TRANSLATE_NOOP("Filter", "Nether biomes 1:256"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -419,28 +403,28 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_BIOME_END_1] = FilterInfo{
|
||||
CAT_END, 1, 1, 1, 0, 0, 0, 1, 0, 0, MC_1_9, 0, +1, 1, disp++, // disabled
|
||||
CAT_END, 1, LOC_REC, 0, 0, 1, 0, BR_NONE, MC_1_9, 0, +1, 1, disp++, // disabled
|
||||
"the_end",
|
||||
QT_TRANSLATE_NOOP("Filter", "End biomes 1:1 (disabled)"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"End biomes after voronoi scaling to 1:1.")
|
||||
};
|
||||
list[F_BIOME_END_4] = FilterInfo{
|
||||
CAT_END, 0, 1, 1, 0, 0, 0, 4, 2, 0, MC_1_9, MC_NEWEST, +1, 0, disp++,
|
||||
CAT_END, 0, LOC_REC, 0, 0, 4, 2, BR_NONE, MC_1_9, MC_NEWEST, +1, 0, disp++,
|
||||
"the_end",
|
||||
QT_TRANSLATE_NOOP("Filter", "End biomes 1:4"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"End biomes sampled at scale 1:4. Note this is just a simple upscale of 1:16.")
|
||||
};
|
||||
list[F_BIOME_END_16] = FilterInfo{
|
||||
CAT_END, 0, 1, 1, 0, 0, 0, 16, 4, 0, MC_1_9, MC_NEWEST, +1, 0, disp++,
|
||||
CAT_END, 0, LOC_REC, 0, 0, 16, 4, BR_NONE, MC_1_9, MC_NEWEST, +1, 0, disp++,
|
||||
"the_end",
|
||||
QT_TRANSLATE_NOOP("Filter", "End biomes 1:16"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
"End biomes with normal sampling at scale 1:16.")
|
||||
};
|
||||
list[F_BIOME_END_64] = FilterInfo{
|
||||
CAT_END, 0, 1, 1, 0, 0, 0, 64, 6, 0, MC_1_9, MC_NEWEST, +1, 0, disp++,
|
||||
CAT_END, 0, LOC_REC, 0, 0, 64, 6, BR_NONE, MC_1_9, MC_NEWEST, +1, 0, disp++,
|
||||
"the_end",
|
||||
QT_TRANSLATE_NOOP("Filter", "End biomes 1:64"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -448,20 +432,20 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_SPAWN] = FilterInfo{
|
||||
CAT_OTHER, 1, 1, 1, 1, 0, 0, 1, 0, 0, MC_B1_8, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_OTHER, 1, LOC_RAD, 0, 0, 1, 0, BR_NONE, MC_B1_8, MC_NEWEST, 0, 0, disp++,
|
||||
"spawn",
|
||||
QT_TRANSLATE_NOOP("Filter", "Spawn"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_SLIME] = FilterInfo{
|
||||
CAT_OTHER, 0, 1, 1, 0, 0, 0, 16, 4, 1, MC_UNDEF, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_OTHER, 0, LOC_REC, 0, 0, 16, 4, BR_CLUST, MC_UNDEF, MC_NEWEST, 0, 0, disp++,
|
||||
"slime",
|
||||
QT_TRANSLATE_NOOP("Filter", "Slime chunk"),
|
||||
""
|
||||
};
|
||||
list[F_HEIGHT] = FilterInfo{
|
||||
CAT_OTHER, 0, 1, 0, 0, 0, 0, 4, 2, 0, MC_1_1, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_OTHER, 0, LOC_POS, 0, 0, 4, 2, BR_NONE, MC_1_1, MC_NEWEST, 0, 0, disp++,
|
||||
"height",
|
||||
QT_TRANSLATE_NOOP("Filter", "Surface height"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -469,7 +453,7 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_FIRST_STRONGHOLD] = FilterInfo{
|
||||
CAT_OTHER, 0, 1, 1, 1, 0, 0, 1, 0, 0, MC_B1_8, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_OTHER, 0, LOC_RAD, 0, 0, 1, 0, BR_NONE, MC_B1_8, MC_NEWEST, 0, 0, disp++,
|
||||
"stronghold",
|
||||
QT_TRANSLATE_NOOP("Filter", "First stronghold"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -478,28 +462,28 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_STRONGHOLD] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, 0, 1, 0, 1, MC_B1_8, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, 0, 1, 0, BR_CLUST, MC_B1_8, MC_NEWEST, 0, 0, disp++,
|
||||
"stronghold",
|
||||
QT_TRANSLATE_NOOP("Filter", "Stronghold"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_VILLAGE] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Village, 1, 0, 1, MC_B1_8, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Village, 1, 0, BR_CLUST, MC_B1_8, MC_NEWEST, 0, 0, disp++,
|
||||
"village",
|
||||
QT_TRANSLATE_NOOP("Filter", "Village"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_MINESHAFT] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 0, 0, Mineshaft, 1, 0, 1, MC_B1_8, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Mineshaft, 1, 0, BR_CLUST, MC_B1_8, MC_NEWEST, 0, 0, disp++,
|
||||
"mineshaft",
|
||||
QT_TRANSLATE_NOOP("Filter", "Abandoned mineshaft"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_DESERT] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Desert_Pyramid, 1, 0, 1, MC_1_3, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Desert_Pyramid, 1, 0, BR_CLUST, MC_1_3, MC_NEWEST, 0, 0, disp++,
|
||||
"desert",
|
||||
QT_TRANSLATE_NOOP("Filter", "Desert pyramid"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -508,7 +492,7 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_JUNGLE] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Jungle_Temple, 1, 0, 1, MC_1_3, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Jungle_Temple, 1, 0, BR_CLUST, MC_1_3, MC_NEWEST, 0, 0, disp++,
|
||||
"jungle",
|
||||
QT_TRANSLATE_NOOP("Filter", "Jungle temple"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -517,28 +501,28 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_HUT] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Swamp_Hut, 1, 0, 1, MC_1_4, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Swamp_Hut, 1, 0, BR_CLUST, MC_1_4, MC_NEWEST, 0, 0, disp++,
|
||||
"hut",
|
||||
QT_TRANSLATE_NOOP("Filter", "Swamp hut"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_MONUMENT] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Monument, 1, 0, 1, MC_1_8, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Monument, 1, 0, BR_CLUST, MC_1_8, MC_NEWEST, 0, 0, disp++,
|
||||
"monument",
|
||||
QT_TRANSLATE_NOOP("Filter", "Ocean monument"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_IGLOO] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Igloo, 1, 0, 1, MC_1_9, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Igloo, 1, 0, BR_CLUST, MC_1_9, MC_NEWEST, 0, 0, disp++,
|
||||
"igloo",
|
||||
QT_TRANSLATE_NOOP("Filter", "Igloo"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_MANSION] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Mansion, 1, 0, 1, MC_1_11, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Mansion, 1, 0, BR_CLUST, MC_1_11, MC_NEWEST, 0, 0, disp++,
|
||||
"mansion",
|
||||
QT_TRANSLATE_NOOP("Filter", "Woodland mansion"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -547,21 +531,21 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_RUINS] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Ocean_Ruin, 1, 0, 1, MC_1_13, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Ocean_Ruin, 1, 0, BR_CLUST, MC_1_13, MC_NEWEST, 0, 0, disp++,
|
||||
"ruins",
|
||||
QT_TRANSLATE_NOOP("Filter", "Ocean ruins"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_SHIPWRECK] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Shipwreck, 1, 0, 1, MC_1_13, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Shipwreck, 1, 0, BR_CLUST, MC_1_13, MC_NEWEST, 0, 0, disp++,
|
||||
"shipwreck",
|
||||
QT_TRANSLATE_NOOP("Filter", "Shipwreck"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_TREASURE] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Treasure, 1, 0, 1, MC_1_13, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Treasure, 1, 0, BR_CLUST, MC_1_13, MC_NEWEST, 0, 0, disp++,
|
||||
"treasure",
|
||||
QT_TRANSLATE_NOOP("Filter", "Buried treasure"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -571,70 +555,70 @@ static const struct FilterList
|
||||
};
|
||||
|
||||
list[F_WELL] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Desert_Well, 1, 0, 1, MC_1_13, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Desert_Well, 1, 0, BR_CLUST, MC_1_13, MC_NEWEST, 0, 0, disp++,
|
||||
"well",
|
||||
QT_TRANSLATE_NOOP("Filter", "Desert well"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_OUTPOST] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Outpost, 1, 0, 1, MC_1_14, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Outpost, 1, 0, BR_CLUST, MC_1_14, MC_NEWEST, 0, 0, disp++,
|
||||
"outpost",
|
||||
QT_TRANSLATE_NOOP("Filter", "Pillager outpost"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_ANCIENT_CITY] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Ancient_City, 1, 0, 1, MC_1_19, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Ancient_City, 1, 0, BR_CLUST, MC_1_19, MC_NEWEST, 0, 0, disp++,
|
||||
"ancient_city",
|
||||
QT_TRANSLATE_NOOP("Filter", "Ancient city"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_TRAILS] = FilterInfo{
|
||||
CAT_STRUCT, 1, 1, 1, 1, 0, Trail_Ruin, 1, 0, 1, MC_1_20, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 1, LOC_RAD, 0, Trail_Ruin, 1, 0, BR_CLUST, MC_1_20, MC_NEWEST, 0, 0, disp++,
|
||||
"trails",
|
||||
QT_TRANSLATE_NOOP("Filter", "Trail ruins"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_PORTAL] = FilterInfo{
|
||||
CAT_STRUCT, 0, 1, 1, 1, 0, Ruined_Portal, 1, 0, 1, MC_1_16_1, MC_NEWEST, 0, 0, disp++,
|
||||
CAT_STRUCT, 0, LOC_RAD, 0, Ruined_Portal, 1, 0, BR_CLUST, MC_1_16_1, MC_NEWEST, 0, 0, disp++,
|
||||
"portal",
|
||||
QT_TRANSLATE_NOOP("Filter", "Ruined portal (overworld)"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_PORTALN] = FilterInfo{
|
||||
CAT_STRUCT, 0, 1, 1, 1, 0, Ruined_Portal_N, 1, 0, 1, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
CAT_STRUCT, 0, LOC_RAD, 0, Ruined_Portal_N, 1, 0, BR_CLUST, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
"portal",
|
||||
QT_TRANSLATE_NOOP("Filter", "Ruined portal (nether)"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_FORTRESS] = FilterInfo{
|
||||
CAT_STRUCT, 0, 1, 1, 1, 0, Fortress, 1, 0, 1, MC_1_0, MC_NEWEST, -1, 0, disp++,
|
||||
CAT_STRUCT, 0, LOC_RAD, 0, Fortress, 1, 0, BR_CLUST, MC_1_0, MC_NEWEST, -1, 0, disp++,
|
||||
"fortress",
|
||||
QT_TRANSLATE_NOOP("Filter", "Nether fortress"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_BASTION] = FilterInfo{
|
||||
CAT_STRUCT, 0, 1, 1, 1, 0, Bastion, 1, 0, 1, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
CAT_STRUCT, 0, LOC_RAD, 0, Bastion, 1, 0, BR_CLUST, MC_1_16_1, MC_NEWEST, -1, 0, disp++,
|
||||
"bastion",
|
||||
QT_TRANSLATE_NOOP("Filter", "Bastion remnant"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_ENDCITY] = FilterInfo{
|
||||
CAT_STRUCT, 0, 1, 1, 1, 0, End_City, 1, 0, 1, MC_1_9, MC_NEWEST, +1, 0, disp++,
|
||||
CAT_STRUCT, 0, LOC_RAD, 0, End_City, 1, 0, BR_CLUST, MC_1_9, MC_NEWEST, +1, 0, disp++,
|
||||
"endcity",
|
||||
QT_TRANSLATE_NOOP("Filter", "End city"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_GATEWAY] = FilterInfo{
|
||||
CAT_STRUCT, 0, 1, 1, 1, 0, End_Gateway, 1, 0, 1, MC_1_13, MC_NEWEST, +1, 0, disp++,
|
||||
CAT_STRUCT, 0, LOC_RAD, 0, End_Gateway, 1, 0, BR_CLUST, MC_1_13, MC_NEWEST, +1, 0, disp++,
|
||||
"gateway",
|
||||
QT_TRANSLATE_NOOP("Filter", "End gateway"),
|
||||
QT_TRANSLATE_NOOP("Filter",
|
||||
@ -656,7 +640,8 @@ struct /*__attribute__((packed))*/ Condition
|
||||
VER_2_3_0 = 1,
|
||||
VER_2_4_0 = 2,
|
||||
VER_3_4_0 = 3,
|
||||
VER_CURRENT = VER_3_4_0,
|
||||
VER_4_0_0 = 4,
|
||||
VER_CURRENT = VER_4_0_0,
|
||||
};
|
||||
enum { // meta flags
|
||||
DISABLED = 0x0001,
|
||||
@ -699,7 +684,7 @@ struct /*__attribute__((packed))*/ Condition
|
||||
uint8_t minmax;
|
||||
uint8_t para;
|
||||
uint8_t octave;
|
||||
uint8_t pad2[2]; // legacy zero initialized
|
||||
uint16_t step;
|
||||
uint16_t version; // condition data version
|
||||
uint64_t biomeToExcl, biomeToExclM; // exclusion biomes
|
||||
int32_t temps[9];
|
||||
@ -714,6 +699,8 @@ struct /*__attribute__((packed))*/ Condition
|
||||
int32_t limex[NP_MAX][2];
|
||||
float vmin;
|
||||
float vmax;
|
||||
float converage;
|
||||
float confidence;
|
||||
|
||||
// generated members - initialized when the search is started
|
||||
uint8_t generated_start[0]; // address dummy
|
||||
@ -732,7 +719,7 @@ struct /*__attribute__((packed))*/ Condition
|
||||
};
|
||||
|
||||
static_assert(
|
||||
offsetof(Condition, generated_start) == 312,
|
||||
offsetof(Condition, generated_start) == 320,
|
||||
"Layout of Condition has changed!"
|
||||
);
|
||||
|
||||
|
@ -261,7 +261,7 @@ bool SearchMaster::set(QWidget *widget, const Session& s)
|
||||
{
|
||||
Generator tmp;
|
||||
setupGenerator(&tmp, s.wi.mc, 0);
|
||||
const Layer *l = getLayerForScale(&tmp, finfo.step);
|
||||
const Layer *l = getLayerForScale(&tmp, finfo.grid);
|
||||
if (l)
|
||||
layerId = l - tmp.ls.layers;
|
||||
}
|
||||
@ -281,12 +281,12 @@ bool SearchMaster::set(QWidget *widget, const Session& s)
|
||||
}
|
||||
if (c.type == F_TEMPS)
|
||||
{
|
||||
int w = c.x2 - c.x1 + 1;
|
||||
int h = c.z2 - c.z1 + 1;
|
||||
int w = (c.x2 >> 10) - (c.x1 >> 10) + 1;
|
||||
int h = (c.z2 >> 10) - (c.z1 >> 10) + 1;
|
||||
if (c.count > w * h)
|
||||
{
|
||||
QString msg = tr("Temperature category condition with ID %1 has too "
|
||||
"many restrictions (%2) for the area (%3 x %4).");
|
||||
"many restrictions (%2) for the area (%3 x %4 @ scale 1:1024).");
|
||||
warn(widget, msg.arg(cid).arg(c.count).arg(w).arg(h));
|
||||
return false;
|
||||
}
|
||||
@ -733,6 +733,7 @@ void SearchMaster::stop()
|
||||
}
|
||||
}
|
||||
workers.clear();
|
||||
|
||||
emit searchFinish(false);
|
||||
}
|
||||
|
||||
|
@ -836,17 +836,14 @@ void TabBiomes::on_pushExport_clicked()
|
||||
void TabBiomes::on_buttonFromVisible_clicked()
|
||||
{
|
||||
MapView *mapview = parent->getMapView();
|
||||
qreal uiw = mapview->width() * mapview->getScale();
|
||||
qreal uih = mapview->height() * mapview->getScale();
|
||||
int bx0 = (int) floor(mapview->getX() - uiw/2);
|
||||
int bz0 = (int) floor(mapview->getZ() - uih/2);
|
||||
int bx1 = (int) ceil(mapview->getX() + uiw/2);
|
||||
int bz1 = (int) ceil(mapview->getZ() + uih/2);
|
||||
|
||||
ui->lineX1->setText( QString::number(bx0) );
|
||||
ui->lineZ1->setText( QString::number(bz0) );
|
||||
ui->lineX2->setText( QString::number(bx1) );
|
||||
ui->lineZ2->setText( QString::number(bz1) );
|
||||
int x1, z1, x2, z2;
|
||||
mapview->getVisible(&x1, &z1, &x2, &z2);
|
||||
|
||||
ui->lineX1->setText( QString::number(x1) );
|
||||
ui->lineZ1->setText( QString::number(z1) );
|
||||
ui->lineX2->setText( QString::number(x2) );
|
||||
ui->lineZ2->setText( QString::number(z2) );
|
||||
}
|
||||
|
||||
void TabBiomes::on_radioFullSample_toggled(bool checked)
|
||||
|
437
src/tablocations.cpp
Normal file
437
src/tablocations.cpp
Normal file
@ -0,0 +1,437 @@
|
||||
#include "tablocations.h"
|
||||
#include "ui_tablocations.h"
|
||||
|
||||
#include "message.h"
|
||||
#include "util.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QFileDialog>
|
||||
#include <QTextStream>
|
||||
#include <QFileInfo>
|
||||
#include <QIntValidator>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
|
||||
#define SAMPLES_MAX 9999999
|
||||
|
||||
static
|
||||
QTreeWidgetItem *setConditionTreeItems(ConditionTree& ctree, int node, int64_t seed, Pos cpos[], QTreeWidgetItem* parent, bool posval)
|
||||
{
|
||||
Condition& c = ctree.condvec[node];
|
||||
Pos p = cpos[c.save];
|
||||
const std::vector<char>& branches = ctree.references[c.save];
|
||||
QTreeWidgetItem* item;
|
||||
|
||||
if (c.type == 0)
|
||||
{
|
||||
item = parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = new QTreeWidgetItem(parent);
|
||||
item->setText(0, c.summary(false));
|
||||
|
||||
if ((p.x == -1 && p.z == -1) || c.type == F_LOGIC_NOT)
|
||||
posval = false;
|
||||
if (posval)
|
||||
{
|
||||
const FilterInfo& finfo = g_filterinfo.list[c.type];
|
||||
double dist = sqrt((double)p.x*p.x + (double)p.z*p.z);
|
||||
item->setText(1, QString::number(p.x));
|
||||
item->setText(2, QString::number(p.z));
|
||||
item->setText(3, QString::asprintf("%.0f", dist));
|
||||
item->setData(0, Qt::UserRole+0, QVariant::fromValue(seed));
|
||||
item->setData(0, Qt::UserRole+1, QVariant::fromValue(finfo.dim));
|
||||
item->setData(0, Qt::UserRole+2, QVariant::fromValue(p));
|
||||
}
|
||||
}
|
||||
if (!branches.empty())
|
||||
{
|
||||
for (char b : branches)
|
||||
setConditionTreeItems(ctree, b, seed, cpos, item, posval);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
QString AnalysisLocations::set(WorldInfo wi, const QVector<Condition>& conds)
|
||||
{
|
||||
this->wi = wi;
|
||||
QString err = condtree.set(conds, wi.mc);
|
||||
if (err.isEmpty())
|
||||
err = env.init(wi.mc, wi.large, &condtree);
|
||||
if (!err.isEmpty())
|
||||
env.setSeed(wi.seed);
|
||||
return err;
|
||||
}
|
||||
|
||||
void AnalysisLocations::run()
|
||||
{
|
||||
stop = false;
|
||||
|
||||
for (idx = 0; idx < (long)pos.size(); idx++)
|
||||
{
|
||||
if (stop) break;
|
||||
|
||||
Pos at = pos[idx.load()];
|
||||
Pos cpos[MAX_INSTANCES] = {};
|
||||
if (testTreeAt(at, &env, PASS_FULL_64, &stop, cpos)
|
||||
!= COND_OK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double dist = sqrt((double)at.x*at.x + (double)at.z*at.z);
|
||||
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
item->setText(0, tr("origin"));
|
||||
item->setText(1, QString::number(at.x));
|
||||
item->setText(2, QString::number(at.z));
|
||||
item->setText(3, QString::asprintf("%.0f", dist));
|
||||
item->setData(0, Qt::UserRole+0, QVariant::fromValue(env.seed));
|
||||
item->setData(0, Qt::UserRole+1, QVariant::Invalid);
|
||||
item->setData(0, Qt::UserRole+2, QVariant::fromValue(at));
|
||||
|
||||
setConditionTreeItems(condtree, 0, env.seed, cpos, item, true);
|
||||
emit itemDone(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum { SMODE_RADIAL_GRID, SMODE_SQUARE_SPIRAL, SMODE_NORMAL };
|
||||
|
||||
TabLocations::TabLocations(MainWindow *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::TabLocations)
|
||||
, parent(parent)
|
||||
, thread()
|
||||
, timer()
|
||||
, maxresults(1)
|
||||
, nextupdate()
|
||||
, updt(20)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->treeWidget->setSortingEnabled(false); // sortable triggers are not necessary
|
||||
|
||||
ui->comboSampling->addItem(tr("Lattice points in radial order") + ", ||α·n, α·m|| < r", SMODE_RADIAL_GRID);
|
||||
ui->comboSampling->addItem(tr("Square spiral") + ", (α·n, α·m)", SMODE_SQUARE_SPIRAL);
|
||||
ui->comboSampling->addItem(tr("Random Gaussian samples") + ", (α·norm(), α·norm())", SMODE_NORMAL);
|
||||
|
||||
ui->lineN->setValidator(new QIntValidator(1, SAMPLES_MAX, this));
|
||||
ui->lineA->setValidator(new QIntValidator(1, (int)3e7, this));
|
||||
ui->lineX->setValidator(new QIntValidator((int)-3e7, (int)3e7, this));
|
||||
ui->lineZ->setValidator(new QIntValidator((int)-3e7, (int)3e7, this));
|
||||
|
||||
connect(&thread, &AnalysisLocations::warning, this, &TabLocations::warning, Qt::BlockingQueuedConnection);
|
||||
connect(&thread, &AnalysisLocations::itemDone, this, &TabLocations::onAnalysisItemDone, Qt::BlockingQueuedConnection);
|
||||
connect(&thread, &AnalysisLocations::finished, this, &TabLocations::onAnalysisFinished);
|
||||
|
||||
connect(&timer, &QTimer::timeout, this, QOverload<>::of(&TabLocations::onProgressTimeout));
|
||||
}
|
||||
|
||||
TabLocations::~TabLocations()
|
||||
{
|
||||
timer.stop();
|
||||
thread.stop = true;
|
||||
thread.wait(500);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool TabLocations::event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LayoutRequest)
|
||||
{
|
||||
QFontMetrics fm = QFontMetrics(ui->treeWidget->font());
|
||||
ui->treeWidget->setColumnWidth(0, fm.horizontalAdvance('#') * 32);
|
||||
ui->treeWidget->setColumnWidth(1, fm.horizontalAdvance('#') * 9);
|
||||
ui->treeWidget->setColumnWidth(2, fm.horizontalAdvance('#') * 9);
|
||||
ui->treeWidget->setColumnWidth(3, fm.horizontalAdvance('#') * 9);
|
||||
}
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
void TabLocations::save(QSettings& settings)
|
||||
{
|
||||
settings.setValue("analysis/samplemode", ui->comboSampling->currentData().toInt());
|
||||
settings.setValue("analysis/samplecnt", ui->lineN->text().toInt());
|
||||
settings.setValue("analysis/samplesep", ui->lineA->text().toInt());
|
||||
settings.setValue("analysis/offx", ui->lineX->text().toInt());
|
||||
settings.setValue("analysis/offz", ui->lineZ->text().toInt());
|
||||
}
|
||||
|
||||
static void loadLine(QSettings *s, QLineEdit *line, const char *key)
|
||||
{
|
||||
qlonglong x = line->text().toLongLong();
|
||||
line->setText( QString::number(s->value(key, x).toLongLong()) );
|
||||
}
|
||||
void TabLocations::load(QSettings& settings)
|
||||
{
|
||||
loadLine(&settings, ui->lineN, "analysis/samplecnt");
|
||||
loadLine(&settings, ui->lineA, "analysis/samplesep");
|
||||
loadLine(&settings, ui->lineX, "analysis/offx");
|
||||
loadLine(&settings, ui->lineZ, "analysis/offz");
|
||||
QVariant mode = settings.value("analysis/samplemode", ui->comboSampling->currentData());
|
||||
ui->comboSampling->setCurrentIndex(ui->comboSampling->findData(mode));
|
||||
|
||||
maxresults = settings.value("config/maxMatching", maxresults).toInt();
|
||||
}
|
||||
|
||||
int TabLocations::warning(QString text, QMessageBox::StandardButtons buttons)
|
||||
{
|
||||
return warn(parent, text, buttons);
|
||||
}
|
||||
|
||||
void TabLocations::onAnalysisItemDone(QTreeWidgetItem *item)
|
||||
{
|
||||
if (qbuf.size() + ui->treeWidget->topLevelItemCount() >= maxresults)
|
||||
{
|
||||
thread.stop = true;
|
||||
}
|
||||
|
||||
qbuf.push_back(item);
|
||||
quint64 ns = elapsed.nsecsElapsed();
|
||||
if (ns > nextupdate)
|
||||
{
|
||||
nextupdate = ns + updt * 1e6;
|
||||
QTimer::singleShot(updt, this, &TabLocations::onBufferTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
void TabLocations::onAnalysisFinished()
|
||||
{
|
||||
timer.stop();
|
||||
onBufferTimeout();
|
||||
ui->pushExport->setEnabled(ui->treeWidget->topLevelItemCount() > 0);
|
||||
ui->pushStart->setChecked(false);
|
||||
ui->pushStart->setText(tr("Analyze"));
|
||||
}
|
||||
|
||||
void TabLocations::onBufferTimeout()
|
||||
{
|
||||
uint64_t t = -elapsed.elapsed();
|
||||
|
||||
if (!qbuf.empty())
|
||||
{
|
||||
ui->treeWidget->setUpdatesEnabled(false);
|
||||
ui->treeWidget->addTopLevelItems(qbuf);
|
||||
ui->treeWidget->setUpdatesEnabled(true);
|
||||
qbuf.clear();
|
||||
onProgressTimeout();
|
||||
}
|
||||
|
||||
QApplication::processEvents(); // force processing of events so we can time correctly
|
||||
|
||||
t += elapsed.elapsed();
|
||||
if (8*t > updt)
|
||||
updt = 4*t;
|
||||
nextupdate = elapsed.nsecsElapsed() + 1e6 * updt;
|
||||
}
|
||||
|
||||
void TabLocations::onProgressTimeout()
|
||||
{
|
||||
QString progress = QString::asprintf(" (%ld/%zu)", thread.idx.load(), thread.pos.size());
|
||||
ui->pushStart->setText(tr("Stop") + progress);
|
||||
}
|
||||
|
||||
void TabLocations::on_pushStart_clicked()
|
||||
{
|
||||
if (thread.isRunning())
|
||||
{
|
||||
thread.stop = true;
|
||||
return;
|
||||
}
|
||||
updt = 20;
|
||||
nextupdate = 0;
|
||||
elapsed.start();
|
||||
|
||||
thread.pos.clear();
|
||||
int mode = ui->comboSampling->currentData().toInt();
|
||||
int a = ui->lineA->text().toInt();
|
||||
uint64_t n = ui->lineN->text().toULongLong();
|
||||
int x0 = ui->lineX->text().toInt();
|
||||
int z0 = ui->lineZ->text().toInt();
|
||||
|
||||
if (a == 0)
|
||||
return;
|
||||
if (n > SAMPLES_MAX)
|
||||
return;
|
||||
|
||||
WorldInfo wi;
|
||||
parent->getSeed(&wi);
|
||||
QVector<Condition> conds = parent->formCond->getConditions();
|
||||
|
||||
QString err = thread.set(wi, conds);
|
||||
if (!err.isEmpty())
|
||||
{
|
||||
emit warning(err, QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == SMODE_RADIAL_GRID)
|
||||
{
|
||||
struct P {
|
||||
int x, z;
|
||||
uint64_t rsq;
|
||||
bool operator< (const P& x) const { return rsq < x.rsq; }
|
||||
};
|
||||
std::vector<P> v;
|
||||
uint64_t rsqmax = (uint64_t) ceil(n / M_PI);
|
||||
int64_t r = (int64_t) sqrt(rsqmax);
|
||||
|
||||
for (int64_t x = -r; x <= r; x++)
|
||||
{
|
||||
for (int64_t z = -r; z <= r; z++)
|
||||
{
|
||||
uint64_t rsq = (uint64_t)(x * x + z * z);
|
||||
if (rsq <= rsqmax)
|
||||
v.push_back(P{(int)x, (int)z, rsq});
|
||||
}
|
||||
}
|
||||
std::sort(v.begin(), v.end());
|
||||
for (uint64_t i = 0; i < n && i < v.size(); i++)
|
||||
{
|
||||
Pos p = { a*v[i].x + x0, a*v[i].z + z0};
|
||||
thread.pos.push_back(p);
|
||||
}
|
||||
}
|
||||
else if (mode == SMODE_SQUARE_SPIRAL)
|
||||
{
|
||||
int rx = 0;
|
||||
int rz = 0;
|
||||
int i = 0, dl = 1;
|
||||
int dx = 1, dz = 0;
|
||||
for (uint64_t j = 0; j < n; j++)
|
||||
{
|
||||
Pos p = { a*rx + x0, a*rz + z0 };
|
||||
thread.pos.push_back(p);
|
||||
rx += dx;
|
||||
rz += dz;
|
||||
if (++i == dl)
|
||||
{
|
||||
i = 0;
|
||||
int tmp = dx;
|
||||
dx = -dz;
|
||||
dz = tmp;
|
||||
if (dz == 0)
|
||||
dl++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mode == SMODE_NORMAL)
|
||||
{
|
||||
thread_local RandGen rng;
|
||||
std::normal_distribution<double> norm = std::normal_distribution<double>(0.0, 1.0);
|
||||
|
||||
for (uint64_t j = 0; j < n; j++)
|
||||
{
|
||||
int x = (int) round( a * norm(rng.mt) );
|
||||
int z = (int) round( a * norm(rng.mt) );
|
||||
Pos p = { x + x0, z + z0 };
|
||||
thread.pos.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
//ui->treeWidget->setSortingEnabled(false);
|
||||
while (ui->treeWidget->topLevelItemCount() > 0)
|
||||
delete ui->treeWidget->takeTopLevelItem(0);
|
||||
|
||||
ui->pushExport->setEnabled(false);
|
||||
ui->pushStart->setChecked(true);
|
||||
QString progress = QString::asprintf(" (0/%zu)", thread.pos.size());
|
||||
ui->pushStart->setText(tr("Stop") + progress);
|
||||
timer.start(250);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
void TabLocations::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
|
||||
{
|
||||
(void) column;
|
||||
QVariant dat;
|
||||
dat = item->data(0, Qt::UserRole+0);
|
||||
if (dat.isValid())
|
||||
{
|
||||
uint64_t seed = qvariant_cast<uint64_t>(dat);
|
||||
dat = item->data(0, Qt::UserRole+1);
|
||||
int dim = dat.isValid() ? dat.toInt() : DIM_UNDEF;
|
||||
WorldInfo wi;
|
||||
parent->getSeed(&wi);
|
||||
wi.seed = seed;
|
||||
parent->setSeed(wi, dim);
|
||||
}
|
||||
|
||||
dat = item->data(0, Qt::UserRole+2);
|
||||
if (dat.isValid())
|
||||
{
|
||||
Pos p = qvariant_cast<Pos>(dat);
|
||||
parent->getMapView()->setView(p.x+0.5, p.z+0.5);
|
||||
}
|
||||
}
|
||||
|
||||
void TabLocations::on_pushExpand_clicked()
|
||||
{
|
||||
bool expand = false;
|
||||
for (QTreeWidgetItemIterator it(ui->treeWidget); *it; ++it)
|
||||
if (!(*it)->isExpanded())
|
||||
expand = true;
|
||||
if (expand)
|
||||
ui->treeWidget->expandAll();
|
||||
else
|
||||
ui->treeWidget->collapseAll();
|
||||
}
|
||||
|
||||
static
|
||||
void csvline(QTextStream& stream, const QString& qte, const QString& sep, QStringList& cols)
|
||||
{
|
||||
if (qte.isEmpty())
|
||||
{
|
||||
for (QString& s : cols)
|
||||
if (s.contains(sep))
|
||||
s = "\"" + s + "\"";
|
||||
}
|
||||
stream << qte << cols.join(sep) << qte << "\n";
|
||||
}
|
||||
|
||||
void TabLocations::on_pushExport_clicked()
|
||||
{
|
||||
QString fnam = QFileDialog::getSaveFileName(
|
||||
this, tr("Export trigger analysis"), parent->prevdir, tr("Text files (*.txt *csv);;Any files (*)"));
|
||||
if (fnam.isEmpty())
|
||||
return;
|
||||
|
||||
QFileInfo finfo(fnam);
|
||||
QFile file(fnam);
|
||||
parent->prevdir = finfo.absolutePath();
|
||||
|
||||
if (!file.open(QIODevice::WriteOnly))
|
||||
{
|
||||
warn(parent, tr("Failed to open file for export:\n\"%1\"").arg(fnam));
|
||||
return;
|
||||
}
|
||||
|
||||
QString qte = parent->config.quote;
|
||||
QString sep = parent->config.separator;
|
||||
|
||||
QTextStream stream(&file);
|
||||
stream << "Sep=" + sep + "\n";
|
||||
sep = qte + sep + qte;
|
||||
|
||||
QStringList header = { tr("condition"), tr("x"), tr("z") };
|
||||
csvline(stream, qte, sep, header);
|
||||
|
||||
QTreeWidgetItemIterator it(ui->treeWidget);
|
||||
for (; *it; ++it)
|
||||
{
|
||||
QTreeWidgetItem *item = *it;
|
||||
QStringList cols;
|
||||
for (int i = 0, n = item->columnCount(); i < n; i++)
|
||||
{
|
||||
QString s = item->text(i);
|
||||
if (s == "-") s = "";
|
||||
cols.append(s);
|
||||
}
|
||||
csvline(stream, qte, sep, cols);
|
||||
}
|
||||
}
|
||||
|
78
src/tablocations.h
Normal file
78
src/tablocations.h
Normal file
@ -0,0 +1,78 @@
|
||||
#ifndef TABLOCATIONS_H
|
||||
#define TABLOCATIONS_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QThread>
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "search.h"
|
||||
#include "world.h"
|
||||
|
||||
namespace Ui {
|
||||
class TabLocations;
|
||||
}
|
||||
|
||||
class AnalysisLocations : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AnalysisLocations(QObject *parent = nullptr)
|
||||
: QThread(parent), wi(),stop(),idx() {}
|
||||
|
||||
QString set(WorldInfo wi, const QVector<Condition>& conds);
|
||||
|
||||
virtual void run() override;
|
||||
|
||||
signals:
|
||||
void itemDone(QTreeWidgetItem *item);
|
||||
int warning(QString text, QMessageBox::StandardButtons buttons);
|
||||
|
||||
public:
|
||||
WorldInfo wi;
|
||||
ConditionTree condtree;
|
||||
SearchThreadEnv env;
|
||||
std::vector<Pos> pos;
|
||||
std::atomic_bool stop;
|
||||
std::atomic_long idx;
|
||||
};
|
||||
|
||||
class TabLocations : public QWidget, public ISaveTab
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TabLocations(MainWindow *parent = nullptr);
|
||||
~TabLocations();
|
||||
|
||||
virtual bool event(QEvent *e) override;
|
||||
|
||||
virtual void save(QSettings& settings) override;
|
||||
virtual void load(QSettings& settings) override;
|
||||
|
||||
private slots:
|
||||
int warning(QString text, QMessageBox::StandardButtons buttons);
|
||||
void onAnalysisItemDone(QTreeWidgetItem *item);
|
||||
void onAnalysisFinished();
|
||||
void onBufferTimeout();
|
||||
void onProgressTimeout();
|
||||
|
||||
void on_pushStart_clicked();
|
||||
void on_pushExpand_clicked();
|
||||
void on_pushExport_clicked();
|
||||
void on_treeWidget_itemClicked(QTreeWidgetItem *item, int column);
|
||||
|
||||
private:
|
||||
Ui::TabLocations *ui;
|
||||
MainWindow *parent;
|
||||
AnalysisLocations thread;
|
||||
QTimer timer;
|
||||
int maxresults;
|
||||
|
||||
QElapsedTimer elapsed;
|
||||
uint64_t nextupdate;
|
||||
uint64_t updt;
|
||||
QList<QTreeWidgetItem*> qbuf;
|
||||
};
|
||||
|
||||
#endif // TABLOCATIONS_H
|
175
src/tablocations.ui
Normal file
175
src/tablocations.ui
Normal file
@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TabLocations</class>
|
||||
<widget class="QWidget" name="TabLocations">
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Centered on:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Sampling strategy:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>X:</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="4">
|
||||
<widget class="QLineEdit" name="lineA">
|
||||
<property name="text">
|
||||
<string>512</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="comboSampling">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QLineEdit" name="lineZ"/>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="5">
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::NoDragDrop</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="expandsOnDoubleClick">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>100</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>condition</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>x</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>z</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>distance</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLineEdit" name="lineX"/>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="5">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushExport">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Export...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushExpand">
|
||||
<property name="text">
|
||||
<string>Expand all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushStart">
|
||||
<property name="text">
|
||||
<string>Analyze</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Spread (α):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="4">
|
||||
<widget class="QLineEdit" name="lineN">
|
||||
<property name="text">
|
||||
<string>1000</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Number of samples:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -607,17 +607,14 @@ void TabStructures::on_pushExport_clicked()
|
||||
void TabStructures::on_buttonFromVisible_clicked()
|
||||
{
|
||||
MapView *mapview = parent->getMapView();
|
||||
qreal uiw = mapview->width() * mapview->getScale();
|
||||
qreal uih = mapview->height() * mapview->getScale();
|
||||
int bx0 = (int) floor(mapview->getX() - uiw/2);
|
||||
int bz0 = (int) floor(mapview->getZ() - uih/2);
|
||||
int bx1 = (int) ceil(mapview->getX() + uiw/2);
|
||||
int bz1 = (int) ceil(mapview->getZ() + uih/2);
|
||||
|
||||
ui->lineX1->setText( QString::number(bx0) );
|
||||
ui->lineZ1->setText( QString::number(bz0) );
|
||||
ui->lineX2->setText( QString::number(bx1) );
|
||||
ui->lineZ2->setText( QString::number(bz1) );
|
||||
int x1, z1, x2, z2;
|
||||
mapview->getVisible(&x1, &z1, &x2, &z2);
|
||||
|
||||
ui->lineX1->setText( QString::number(x1) );
|
||||
ui->lineZ1->setText( QString::number(z1) );
|
||||
ui->lineX2->setText( QString::number(x2) );
|
||||
ui->lineZ2->setText( QString::number(z2) );
|
||||
}
|
||||
|
||||
void TabStructures::on_tabWidget_currentChanged(int)
|
||||
|
@ -136,15 +136,12 @@ bool TabTriggers::event(QEvent *e)
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
void TabTriggers::save(QSettings& settings)
|
||||
void TabTriggers::save(QSettings&)
|
||||
{
|
||||
settings.setValue("analysis/seedsrc", ui->comboSeedSource->currentIndex());
|
||||
}
|
||||
|
||||
void TabTriggers::load(QSettings& settings)
|
||||
void TabTriggers::load(QSettings&)
|
||||
{
|
||||
int idx = settings.value("analysis/seedsrc", ui->comboSeedSource->currentIndex()).toInt();
|
||||
ui->comboSeedSource->setCurrentIndex(idx);
|
||||
}
|
||||
|
||||
int TabTriggers::warning(QString text, QMessageBox::StandardButtons buttons)
|
||||
@ -251,7 +248,14 @@ void TabTriggers::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
|
||||
|
||||
void TabTriggers::on_pushExpand_clicked()
|
||||
{
|
||||
ui->treeWidget->expandAll();
|
||||
bool expand = false;
|
||||
for (QTreeWidgetItemIterator it(ui->treeWidget); *it; ++it)
|
||||
if (!(*it)->isExpanded())
|
||||
expand = true;
|
||||
if (expand)
|
||||
ui->treeWidget->expandAll();
|
||||
else
|
||||
ui->treeWidget->collapseAll();
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -83,7 +83,7 @@
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="labelDescription">
|
||||
<property name="text">
|
||||
<string>Analyze the search condition triggers.</string>
|
||||
<string>Examine how the conditions are evaluated.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
30
src/util.cpp
30
src/util.cpp
@ -160,30 +160,24 @@ QString getBiomeDisplay(int mc, int id)
|
||||
return name ? name : "";
|
||||
}
|
||||
|
||||
RandGen::RandGen()
|
||||
{
|
||||
std::random_device rd;
|
||||
if (rd.entropy())
|
||||
mt = std::mt19937_64(rd());
|
||||
else
|
||||
mt = std::mt19937_64(time(0));
|
||||
}
|
||||
|
||||
// get a random 64-bit integer
|
||||
uint64_t getRnd64()
|
||||
{
|
||||
static QMutex mutex;
|
||||
static std::random_device rd;
|
||||
static std::mt19937_64 mt(rd());
|
||||
static uint64_t x = (uint64_t) time(0);
|
||||
static RandGen rng;
|
||||
uint64_t ret = 0;
|
||||
mutex.lock();
|
||||
if (rd.entropy())
|
||||
{
|
||||
std::uniform_int_distribution<int64_t> d;
|
||||
ret = d(mt);
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint64_t c = 0xd6e8feb86659fd93ULL;
|
||||
x ^= x >> 32;
|
||||
x *= c;
|
||||
x ^= x >> 32;
|
||||
x *= c;
|
||||
x ^= x >> 32;
|
||||
ret = x;
|
||||
}
|
||||
std::uniform_int_distribution<uint64_t> d;
|
||||
ret = d(rng.mt);
|
||||
mutex.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
@ -64,6 +64,12 @@ QString getStartPieceName(int stype, const StructureVariant *sv);
|
||||
|
||||
QString getBiomeDisplay(int mc, int id);
|
||||
|
||||
struct RandGen
|
||||
{
|
||||
RandGen();
|
||||
std::mt19937_64 mt;
|
||||
};
|
||||
|
||||
// get a random 64-bit integer
|
||||
uint64_t getRnd64();
|
||||
|
||||
|
@ -1224,6 +1224,8 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
|
||||
painter.drawImage(rec, slimeimg);
|
||||
}
|
||||
|
||||
// draw bounding boxes and shapes
|
||||
painter.setPen(QPen(QColor(192, 0, 0, 160), 1));
|
||||
|
||||
if (showBB && blocks2pix >= 1.0 && qsinfo && dim == 0)
|
||||
{
|
||||
@ -1237,7 +1239,6 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
|
||||
qreal x = vw/2.0 + (qi.afk.x - focusx) * blocks2pix;
|
||||
qreal y = vh/2.0 + (qi.afk.z - focusz) * blocks2pix;
|
||||
qreal r = 128.0 * blocks2pix;
|
||||
painter.setPen(QPen(QColor(192, 0, 0, 160), 1));
|
||||
painter.drawEllipse(QRectF(x-r, y-r, 2*r, 2*r));
|
||||
r = 16;
|
||||
painter.drawLine(QPointF(x-r,y), QPointF(x+r,y));
|
||||
@ -1245,6 +1246,29 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
|
||||
}
|
||||
}
|
||||
|
||||
for (Shape& s : shapes)
|
||||
{
|
||||
if (s.dim != dim)
|
||||
continue;
|
||||
qreal x1 = vw/2.0 + (s.p1.x - focusx) * blocks2pix;
|
||||
qreal y1 = vh/2.0 + (s.p1.z - focusz) * blocks2pix;
|
||||
qreal x2 = vw/2.0 + (s.p2.x - focusx) * blocks2pix;
|
||||
qreal y2 = vh/2.0 + (s.p2.z - focusz) * blocks2pix;
|
||||
qreal r = s.r * blocks2pix;
|
||||
switch (s.type)
|
||||
{
|
||||
case Shape::RECT:
|
||||
painter.drawRect(QRectF(x1, y1, x2-x1, y2-y1));
|
||||
break;
|
||||
case Shape::LINE:
|
||||
painter.drawLine(QLineF(x1, y1, x2, y2));
|
||||
break;
|
||||
case Shape::CIRCLE:
|
||||
painter.drawEllipse(QPointF(x1, y1), r, r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int sopt = D_DESERT; sopt < D_SPAWN; sopt++)
|
||||
{
|
||||
Level& l = lvs[sopt];
|
||||
|
11
src/world.h
11
src/world.h
@ -121,6 +121,14 @@ struct PosElement
|
||||
Pos p;
|
||||
};
|
||||
|
||||
struct Shape
|
||||
{
|
||||
enum { RECT, LINE, CIRCLE } type;
|
||||
int dim;
|
||||
int r;
|
||||
Pos p1, p2;
|
||||
};
|
||||
|
||||
class MapWorker : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -206,6 +214,9 @@ public:
|
||||
QImage slimeimg;
|
||||
long slimex, slimez;
|
||||
|
||||
// shapes to overlay
|
||||
std::vector<Shape> shapes;
|
||||
|
||||
// structure selection from mouse position
|
||||
bool seldo;
|
||||
qreal selx, selz;
|
||||
|
Loading…
Reference in New Issue
Block a user