Changes for 3.3.0

added biome noise visualization for beta 1.7 climates (#212)
added keyboard controls to navigate the map (#217)
added desert wells map option and finders (#218)
added trail ruins map option and finders
added amethyst geode map option
added indicator for igloos with basement
added command line option --reset-all to clear the sessions and settings
added visibility toggles for structures that can be used to de-clutter the toolbar
updated structure icons, replacing several amidst icons that had non-standard sizes
changed UI so multiple conditions can be enabled/disabled at once (#216)
changed warning message for small areas to be more informative (#220)
changed compiler flags for debug builds
changed the toolbar position to its anchor is resored upon restart
changed preferences dialog to be non-blocking
fixed missing y-level option for locate biome center finders (#221)
fixed incorrect stronghold positions for 1.6- (#228)
fixed secondary spawn pass for 1.18+ (#219)
This commit is contained in:
Cubitect 2023-05-21 15:27:47 +02:00
parent c7d6062fe4
commit 09e6bfd1e2
100 changed files with 1531 additions and 872 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
cubiomes-viewer.pro.user
build
src/libwinsane/*.o
**/.directory

@ -1 +1 @@
Subproject commit 119f3e7d7604d7ec2a2dd45a2374d482823eda13
Subproject commit f2c96306c77e216120beb4c65b90624c526a3ba5

View File

@ -12,13 +12,13 @@ QT += core widgets
CHARSET = -finput-charset=UTF-8 -fexec-charset=UTF-8
QMAKE_CFLAGS = $$CHARSET -fwrapv -DSTRUCT_CONFIG_OVERRIDE=1
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -std=gnu++11
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -std=gnu++11 -Wno-deprecated-copy
QMAKE_CXXFLAGS_RELEASE *= -O3
win32: {
CONFIG += static_gnu
# thanks to nullprogram for dealing with the Windows UTF-16 nonsense
# thank you nullprogram for dealing with the Windows UTF-16 nonsense
LIBWINSANE = $$PWD/src/libwinsane
libwinsane.target = libwinsane
libwinsane.output = $$LIBWINSANE/libwinsane.o
@ -33,12 +33,15 @@ static_gnu: {
LIBS += -static -static-libgcc -static-libstdc++
}
# compile cubiomes
release: {
CUTARGET = release
} else: { # may need the release target to be disabled: qmake CONFIG-=release
CONFIG(debug, debug|release): {
CUTARGET = debug
QMAKE_CFLAGS += -fsanitize=undefined
LIBS += -lubsan -ldl
} else {
CUTARGET = release
}
# compile cubiomes
CUPATH = $$PWD/cubiomes
QMAKE_PRE_LINK += $(MAKE) -C $$CUPATH -f $$CUPATH/makefile CFLAGS=\"$$QMAKE_CFLAGS\" $$CUTARGET
QMAKE_CLEAN += $$CUPATH/*.o $$CUPATH/libcubiomes.a
@ -85,6 +88,7 @@ SOURCES += \
src/biomecolordialog.cpp \
src/collapsible.cpp \
src/conditiondialog.cpp \
src/config.cpp \
src/configdialog.cpp \
src/extgendialog.cpp \
src/exportdialog.cpp \
@ -147,6 +151,7 @@ HEADERS += \
src/biomecolordialog.h \
src/collapsible.h \
src/conditiondialog.h \
src/config.h \
src/configdialog.h \
src/extgendialog.h \
src/exportdialog.h \
@ -169,7 +174,6 @@ HEADERS += \
src/tabstructures.h \
src/tabtriggers.h \
src/mainwindow.h \
src/settings.h \
src/structuredialog.h \
src/world.h

View File

@ -72,5 +72,13 @@
<file>icons/check_include_d.png</file>
<file>icons/check_unchecked.png</file>
<file>icons/height.png</file>
<file>icons/trail.png</file>
<file>icons/missing.png</file>
<file>icons/well.png</file>
<file>icons/well_d.png</file>
<file>icons/trail_d.png</file>
<file>icons/geode_d.png</file>
<file>icons/geode.png</file>
<file>icons/igloo_basement.png</file>
</qresource>
</RCC>

View File

@ -1,4 +0,0 @@
[Dolphin]
PreviewsShown=true
Timestamp=2022,8,24,16,47,37
Version=3

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 437 B

BIN
rc/icons/geode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

BIN
rc/icons/geode_d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 644 B

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 703 B

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 B

After

Width:  |  Height:  |  Size: 308 B

BIN
rc/icons/igloo_basement.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 234 B

BIN
rc/icons/missing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 999 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 918 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 B

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 646 B

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 642 B

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 665 B

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 B

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 546 B

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 620 B

BIN
rc/icons/trail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

BIN
rc/icons/trail_d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 B

After

Width:  |  Height:  |  Size: 354 B

BIN
rc/icons/well.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

BIN
rc/icons/well_d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 423 B

View File

@ -5,8 +5,8 @@
#include <QString>
#define VERS_MAJOR 3
#define VERS_MINOR 2
#define VERS_PATCH 1 // negative patch number designates a development version
#define VERS_MINOR 3
#define VERS_PATCH -1 // negative patch number designates a development version
// returns +1 if newer, -1 if older and 0 if equal
inline int cmpVers(int major, int minor, int patch)

View File

@ -2,7 +2,7 @@
#include "ui_biomecolordialog.h"
#include "cutil.h"
#include "settings.h"
#include "config.h"
#include <QPixmap>
#include <QPainter>

View File

@ -122,7 +122,7 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
ui->lineRadius->setValidator(uintval);
ui->lineBiomeSize->setValidator(new QIntValidator(1, INT_MAX, this));
ui->lineTollerance->setValidator(new QIntValidator(0, 255, this));
ui->lineTolerance->setValidator(new QIntValidator(0, 255, this));
ui->comboY->lineEdit()->setValidator(new QIntValidator(-64, 320, this));
@ -293,7 +293,6 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
ui->checkSkipRef->setChecked(false);
ui->radioSquare->setChecked(true);
ui->checkRadius->setChecked(false);
ui->lineBiomeSize->setText("");
onCheckStartChanged(false);
on_comboClimatePara_currentIndexChanged(0);
@ -352,7 +351,10 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
if (ui->comboY->itemText(i).section(' ', 0, 0).toInt() == cond.y)
break;
if (i >= n)
{
ui->comboY->addItem(QString::number(cond.y));
ui->comboY2->addItem(QString::number(cond.y));
}
ui->comboY->setCurrentIndex(i);
if (cond.x1 == cond.z1 && cond.x1 == -cond.x2 && cond.x1 == -cond.z2)
@ -400,8 +402,8 @@ ConditionDialog::ConditionDialog(FormConditions *parent, Config *config, int mcv
}
}
ui->lineBiomeSize->setText(QString::number(cond.biomeSize));
ui->lineTollerance->setText(QString::number(cond.tol));
ui->lineBiomeSize->setText(QString::number(cond.biomeSize ? cond.biomeSize : 1));
ui->lineTolerance->setText(QString::number(cond.tol));
auto totristate = [](uint16_t st, uint16_t msk) {
return (st & msk) ? (st & Condition::VAR_NOT) ? Qt::Checked : Qt::PartiallyChecked : Qt::Unchecked;
@ -795,7 +797,10 @@ int ConditionDialog::warnIfBad(Condition cond)
int h = cond.z2 - cond.z1 + 1;
if ((unsigned int)(w * h) < cond.count * cond.biomeSize)
{
QString text = tr("Area is too small for the required biome size.");
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);
QMessageBox::warning(this, tr("Area Insufficient"), text, QMessageBox::Ok);
return QMessageBox::Cancel;
}
@ -964,6 +969,8 @@ void ConditionDialog::on_buttonOk_clicked()
else
c.rmax = 0;
c.y = ui->comboY->currentText().section(' ', 0, 0).toInt();
if (ui->stackedWidget->currentWidget() == ui->pageBiomes)
{
c.biomeToFind = c.biomeToFindM = 0;
@ -993,7 +1000,7 @@ void ConditionDialog::on_buttonOk_clicked()
{
c.biomeId = ui->comboMatchBiome->currentData().toInt();
c.biomeSize = ui->lineBiomeSize->text().toInt();
c.tol = ui->lineTollerance->text().toInt();
c.tol = ui->lineTolerance->text().toInt();
}
if (ui->stackedWidget->currentWidget() == ui->pageMinMax)
{
@ -1016,8 +1023,6 @@ void ConditionDialog::on_buttonOk_clicked()
}
}
c.y = ui->comboY->currentText().section(' ', 0, 0).toInt();
c.flags = 0;
if (ui->checkApprox->isChecked())
c.flags |= Condition::FLG_APPROX;
@ -1450,3 +1455,16 @@ void ConditionDialog::on_comboClimatePara_currentIndexChanged(int)
ui->comboOctaves->addItems(items);
}
void ConditionDialog::on_comboY_currentTextChanged(const QString &text)
{
if (ui->comboY2->currentText() != text)
ui->comboY2->setCurrentText(text);
}
void ConditionDialog::on_comboY2_currentTextChanged(const QString &text)
{
if (ui->comboY->currentText() != text)
ui->comboY->setCurrentText(text);
}

View File

@ -175,6 +175,9 @@ private slots:
void on_comboClimatePara_currentIndexChanged(int index);
void on_comboY_currentTextChanged(const QString &text);
void on_comboY2_currentTextChanged(const QString &text);
private:
Ui::ConditionDialog *ui;
QTextEdit *textDescription;

View File

@ -489,7 +489,7 @@
<number>0</number>
</property>
<property name="currentIndex">
<number>5</number>
<number>2</number>
</property>
<widget class="QWidget" name="pageNone">
<property name="enabled">
@ -701,8 +701,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>60</width>
<height>20</height>
<width>634</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
@ -744,7 +744,28 @@
<string>Locate boime center</string>
</property>
<layout class="QGridLayout" name="gridLayout_19">
<item row="3" column="1">
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Border tolerance:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Biome:</string>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QLineEdit" name="lineBiomeSize">
<property name="text">
<string>1</string>
</property>
</widget>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -757,17 +778,28 @@
</property>
</spacer>
</item>
<item row="0" column="2" colspan="2">
<widget class="QComboBox" name="comboMatchBiome">
<property name="editable">
<bool>true</bool>
</property>
<property name="maxVisibleItems">
<number>20</number>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Minimum area:</string>
</property>
</widget>
</item>
<item row="1" column="3">
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="labelY_2">
<property name="text">
<string>Sample at height (Y):</string>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QLineEdit" name="lineTolerance">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QLabel" name="labelBiomeSize">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
@ -780,39 +812,79 @@
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="lineBiomeSize">
<property name="text">
<string>1</string>
<item row="0" column="2" colspan="3">
<widget class="QComboBox" name="comboMatchBiome">
<property name="editable">
<bool>true</bool>
</property>
<property name="maxVisibleItems">
<number>20</number>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Minimum area:</string>
<item row="1" column="2" colspan="3">
<widget class="QComboBox" name="comboY2">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Border tollerance:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Biome:</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="lineTollerance">
<property name="text">
<string>0</string>
<property name="maxVisibleItems">
<number>12</number>
</property>
<item>
<property name="text">
<string>256 (Surface)</string>
</property>
</item>
<item>
<property name="text">
<string>128 (Nether Roof)</string>
</property>
</item>
<item>
<property name="text">
<string>62 (Sea Level)</string>
</property>
</item>
<item>
<property name="text">
<string>48</string>
</property>
</item>
<item>
<property name="text">
<string>32</string>
</property>
</item>
<item>
<property name="text">
<string>16</string>
</property>
</item>
<item>
<property name="text">
<string>0</string>
</property>
</item>
<item>
<property name="text">
<string>-16</string>
</property>
</item>
<item>
<property name="text">
<string>-32</string>
</property>
</item>
<item>
<property name="text">
<string>-48</string>
</property>
</item>
<item>
<property name="text">
<string>-64 (Bedrock)</string>
</property>
</item>
</widget>
</item>
</layout>
@ -1404,8 +1476,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>60</width>
<height>20</height>
<width>634</width>
<height>335</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3_1">
@ -1461,8 +1533,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>60</width>
<height>20</height>
<width>634</width>
<height>335</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3_2">
@ -1566,8 +1638,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>60</width>
<height>20</height>
<width>634</width>
<height>335</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3_3">

414
src/config.cpp Normal file
View File

@ -0,0 +1,414 @@
#include "config.h"
#include "cutil.h"
#include <QThread>
void ExtGenConfig::reset()
{
experimentalVers = false;
estimateTerrain = true;
saltOverride = false;
for (int i = 0; i < FEATURE_NUM; i++)
salts[i] = ~(uint64_t)0;
}
void ExtGenConfig::load(QSettings& settings)
{
experimentalVers = settings.value("world/experimentalVers", experimentalVers).toBool();
estimateTerrain = settings.value("world/estimateTerrain", estimateTerrain).toBool();
saltOverride = settings.value("world/saltOverride", saltOverride).toBool();
for (int st = 0; st < FEATURE_NUM; st++)
{
QVariant v = QVariant::fromValue(~(qulonglong)0);
salts[st] = settings.value(QString("world/salt_") + struct2str(st), v).toULongLong();
}
}
void ExtGenConfig::save(QSettings& settings)
{
settings.setValue("world/experimentalVers", experimentalVers);
settings.setValue("world/estimateTerrain", estimateTerrain);
settings.setValue("world/saltOverride", saltOverride);
for (int st = 0; st < FEATURE_NUM; st++)
{
uint64_t salt = salts[st];
if (salt <= MASK48)
settings.setValue(QString("world/salt_") + struct2str(st), (qulonglong)salt);
}
}
bool WorldInfo::equals(const WorldInfo& wi) const
{
return mc == wi.mc && large == wi.large && seed == wi.seed && y == wi.y;
}
void WorldInfo::reset()
{
mc = MC_NEWEST;
large = false;
seed = 0;
y = 255;
}
void WorldInfo::load(QSettings& settings)
{
mc = settings.value("map/mc", mc).toInt();
large = settings.value("map/large", large).toBool();
seed = settings.value("map/seed", (qlonglong)seed).toLongLong();
y = settings.value("map/y", y).toInt();
}
void WorldInfo::save(QSettings& settings)
{
settings.setValue("map/mc", mc);
settings.setValue("map/large", large);
settings.setValue("map/seed", (qlonglong)seed);
settings.setValue("map/y", y);
}
bool WorldInfo::read(const QString& line)
{
QByteArray ba = line.toLocal8Bit();
const char *p = ba.data();
char buf[9];
int tmp;
if (sscanf(p, "#MC: %8[^\n]", buf) == 1)
{
mc = str2mc(buf);
if (mc < 0)
mc = MC_NEWEST;
return true;
}
if (sscanf(p, "#Large: %d", &tmp) == 1)
{
large = tmp;
return true;
}
return false;
}
void WorldInfo::write(QTextStream& stream)
{
stream << "#MC: " << mc2str(mc) << "\n";
stream << "#Large: " << large << "\n";
}
void LayerOpt::reset()
{
mode = LOPT_BIOMES;
memset(disp, 0, sizeof(disp));
}
int LayerOpt::activeDisp() const
{
return disp[mode];
}
bool LayerOpt::activeDifference(const LayerOpt& l) const
{
return mode != l.mode || disp[l.mode] != l.disp[l.mode];
}
bool LayerOpt::isClimate(int mc) const
{
if (mc <= MC_B1_7)
return mode == LOPT_BETA_T_1 || mode == LOPT_BETA_H_1;
if (mc <= MC_1_17)
return false;
return mode >= LOPT_NOISE_T_4 && mode <= LOPT_NOISE_W_4;
}
const char *mapopt2str(int opt)
{
switch (opt)
{
case D_GRID: return "grid";
case D_SLIME: return "slime";
case D_DESERT: return "desert";
case D_JUNGLE: return "jungle";
case D_IGLOO: return "igloo";
case D_HUT: return "hut";
case D_VILLAGE: return "village";
case D_MANSION: return "mansion";
case D_MONUMENT: return "monument";
case D_RUINS: return "ruins";
case D_SHIPWRECK: return "shipwreck";
case D_TREASURE: return "treasure";
case D_MINESHAFT: return "mineshaft";
case D_WELL: return "well";
case D_GEODE: return "geode";
case D_OUTPOST: return "outpost";
case D_ANCIENTCITY: return "ancient_city";
case D_TRAIL: return "trails";
case D_PORTAL: return "portal";
case D_PORTALN: return "portaln";
case D_SPAWN: return "spawn";
case D_STRONGHOLD: return "stronghold";
case D_FORTESS: return "fortress";
case D_BASTION: return "bastion";
case D_ENDCITY: return "endcity";
case D_GATEWAY: return "gateway";
default: return "";
}
}
int str2mapopt(const char *s)
{
if (!strcmp(s, "grid")) return D_GRID;
if (!strcmp(s, "slime")) return D_SLIME;
if (!strcmp(s, "desert")) return D_DESERT;
if (!strcmp(s, "jungle")) return D_JUNGLE;
if (!strcmp(s, "igloo")) return D_IGLOO;
if (!strcmp(s, "hut")) return D_HUT;
if (!strcmp(s, "village")) return D_VILLAGE;
if (!strcmp(s, "mansion")) return D_MANSION;
if (!strcmp(s, "monument")) return D_MONUMENT;
if (!strcmp(s, "ruins")) return D_RUINS;
if (!strcmp(s, "shipwreck")) return D_SHIPWRECK;
if (!strcmp(s, "treasure")) return D_TREASURE;
if (!strcmp(s, "mineshaft")) return D_MINESHAFT;
if (!strcmp(s, "well")) return D_WELL;
if (!strcmp(s, "geode")) return D_GEODE;
if (!strcmp(s, "outpost")) return D_OUTPOST;
if (!strcmp(s, "ancient_city")) return D_ANCIENTCITY;
if (!strcmp(s, "trail")) return D_TRAIL;
if (!strcmp(s, "portal")) return D_PORTAL;
if (!strcmp(s, "portaln")) return D_PORTALN;
if (!strcmp(s, "spawn")) return D_SPAWN;
if (!strcmp(s, "stronghold")) return D_STRONGHOLD;
if (!strcmp(s, "fortress")) return D_FORTESS;
if (!strcmp(s, "bastion")) return D_BASTION;
if (!strcmp(s, "endcity")) return D_ENDCITY;
if (!strcmp(s, "gateway")) return D_GATEWAY;
return D_NONE;
}
int mapopt2stype(int opt)
{
switch (opt)
{
case D_DESERT: return Desert_Pyramid;
case D_JUNGLE: return Jungle_Pyramid;
case D_IGLOO: return Igloo;
case D_HUT: return Swamp_Hut;
case D_VILLAGE: return Village;
case D_MANSION: return Mansion;
case D_MONUMENT: return Monument;
case D_RUINS: return Ocean_Ruin;
case D_SHIPWRECK: return Shipwreck;
case D_TREASURE: return Treasure;
case D_MINESHAFT: return Mineshaft;
case D_WELL: return Desert_Well;
case D_GEODE: return Geode;
case D_OUTPOST: return Outpost;
case D_ANCIENTCITY: return Ancient_City;
case D_TRAIL: return Trail_Ruin;
case D_PORTAL: return Ruined_Portal;
case D_PORTALN: return Ruined_Portal_N;
case D_FORTESS: return Fortress;
case D_BASTION: return Bastion;
case D_ENDCITY: return End_City;
case D_GATEWAY: return End_Gateway;
default:
return -1;
}
}
MapConfig::MapConfig(bool init)
{
if (init)
reset();
else
opts[0].scale = -1;
}
bool MapConfig::equals(const MapConfig& a) const
{
return memcmp(opts, a.opts, sizeof(opts)) == 0;
}
void MapConfig::reset()
{
for (int i = D_DESERT; i < D_SPAWN; i++)
{
opts[i].scale = 32;
opts[i].enabled = true;
opts[i].valid = true;
}
opts[D_GEODE].scale = 16;
}
void MapConfig::load(QSettings& settings)
{
reset();
for (int opt = D_DESERT; opt < D_SPAWN; opt++)
{
if (!valid(opt))
continue;
const char *name = mapopt2str(opt);
double x = scale(opt);
if (!enabled(opt))
x = -x;
x = settings.value(QString("structscale/") + name, x).toDouble();
opts[opt].scale = fabs(x);
opts[opt].enabled = x > 0;
}
}
void MapConfig::save(QSettings& settings)
{
for (int opt = D_DESERT; opt < D_SPAWN; opt++)
{
const char *name = mapopt2str(opt);
double x = scale(opt);
if (!enabled(opt))
x = -x;
settings.setValue(QString("structscale/") + name, x);
}
}
void Config::reset()
{
smoothMotion = true;
showBBoxes = true;
restoreSession = true;
checkForUpdates = false;
autosaveCycle = 10;
uistyle = STYLE_SYSTEM;
maxMatching = 65536;
gridSpacing = 0;
gridMultiplier = 0;
mapCacheSize = 256;
mapThreads = 0;
biomeColorPath = "";
separator = ";";
quote = "";
}
void Config::load(QSettings& settings)
{
smoothMotion = settings.value("config/smoothMotion", smoothMotion).toBool();
showBBoxes = settings.value("config/showBBoxes", showBBoxes).toBool();
restoreSession = settings.value("config/restoreSession", restoreSession).toBool();
checkForUpdates = settings.value("config/checkForUpdates", checkForUpdates).toBool();
autosaveCycle = settings.value("config/autosaveCycle", autosaveCycle).toInt();
uistyle = settings.value("config/uistyle", uistyle).toInt();
maxMatching = settings.value("config/maxMatching", maxMatching).toInt();
gridSpacing = settings.value("config/gridSpacing", gridSpacing).toInt();
gridMultiplier = settings.value("config/gridMultiplier", gridMultiplier).toInt();
mapCacheSize = settings.value("config/mapCacheSize", mapCacheSize).toInt();
mapThreads = settings.value("config/mapThreads", mapThreads).toInt();
biomeColorPath = settings.value("config/biomeColorPath", biomeColorPath).toString();
separator = settings.value("config/separator", separator).toString();
quote = settings.value("config/quote", quote).toString();
}
void Config::save(QSettings& settings)
{
settings.setValue("config/smoothMotion", smoothMotion);
settings.setValue("config/showBBoxes", showBBoxes);
settings.setValue("config/restoreSession", restoreSession);
settings.setValue("config/checkForUpdates", checkForUpdates);
settings.setValue("config/autosaveCycle", autosaveCycle);
settings.setValue("config/uistyle", uistyle);
settings.setValue("config/maxMatching", maxMatching);
settings.setValue("config/gridSpacing", gridSpacing);
settings.setValue("config/gridMultiplier", gridMultiplier);
settings.setValue("config/mapCacheSize", mapCacheSize);
settings.setValue("config/mapThreads", mapThreads);
settings.setValue("config/biomeColorPath", biomeColorPath);
settings.setValue("config/separator", separator);
settings.setValue("config/quote", quote);
}
void Gen48Config::reset()
{
mode = GEN48_AUTO;
slist48path = "";
salt = 0;
listsalt = 0;
qual = IDEAL;
qmarea = 13028;
manualarea = false;
x1 = z1 = x2 = z2 = 0;
}
bool Gen48Config::read(const QString& line)
{
QByteArray ba = line.toLocal8Bit();
const char *p = ba.data();
if (sscanf(p, "#Mode48: %d", &mode) == 1) return true;
if (line.startsWith("#List48: ")) { slist48path = line.mid(11).trimmed(); return true; }
if (sscanf(p, "#Salt: %" PRIu64, &salt) == 1) return true;
if (sscanf(p, "#LSalt: %" PRIu64, &listsalt) == 1) return true;
if (sscanf(p, "#HutQual: %d", &qual) == 1) return true;
if (sscanf(p, "#MonArea: %d", &qmarea) == 1) return true;
if (sscanf(p, "#Gen48X1: %d", &x1) == 1) { manualarea = true; return true; }
if (sscanf(p, "#Gen48Z1: %d", &z1) == 1) { manualarea = true; return true; }
if (sscanf(p, "#Gen48X2: %d", &x2) == 1) { manualarea = true; return true; }
if (sscanf(p, "#Gen48Z2: %d", &z2) == 1) { manualarea = true; return true; }
return false;
}
void Gen48Config::write(QTextStream& stream)
{
stream << "#Mode48: " << mode << "\n";
if (!slist48path.isEmpty())
stream << "#List48: " << slist48path.replace("\n", "") << "\n";
stream << "#HutQual: " << qual << "\n";
stream << "#MonArea: " << qmarea << "\n";
if (salt != 0)
stream << "#Salt: " << salt << "\n";
if (listsalt != 0)
stream << "#LSalt: " << listsalt << "\n";
if (manualarea)
{
stream << "#Gen48X1: " << x1 << "\n";
stream << "#Gen48Z1: " << z1 << "\n";
stream << "#Gen48X2: " << x2 << "\n";
stream << "#Gen48Z2: " << z2 << "\n";
}
}
void SearchConfig::reset()
{
searchtype = SEARCH_INC;
slist64path = "";
threads = QThread::idealThreadCount();
startseed = 0;
stoponres = true;
smin = 0;
smax = ~(uint64_t)0;
}
bool SearchConfig::read(const QString& line)
{
QByteArray ba = line.toLocal8Bit();
const char *p = ba.data();
int tmp;
if (sscanf(p, "#Search: %d", &searchtype) == 1) return true;
if (line.startsWith("#List64: ")) { slist64path = line.mid(11).trimmed(); return true; }
if (sscanf(p, "#Threads: %d", &threads) == 1) return true;
if (sscanf(p, "#Progress: %" PRId64, &startseed) == 1) return true;
if (sscanf(p, "#ResStop: %d", &tmp) == 1) { stoponres = tmp; return true; }
if (sscanf(p, "#SMin: %" PRIu64, &smin) == 1) return true;
if (sscanf(p, "#SMax: %" PRIu64, &smax) == 1) return true;
return false;
}
void SearchConfig::write(QTextStream& stream)
{
stream << "#Search: " << searchtype << "\n";
if (!slist64path.isEmpty())
stream << "#List64: " << slist64path.replace("\n", "") << "\n";
stream << "#Progress: " << startseed << "\n";
stream << "#Threads: " << threads << "\n";
stream << "#ResStop: " << (int)stoponres << "\n";
if (smin != 0)
stream << "#SMin: " << smin << "\n";
if (smax != ~(uint64_t)0)
stream << "#SMax: " << smax << "\n";
}

236
src/config.h Normal file
View File

@ -0,0 +1,236 @@
#ifndef CONFIG_H
#define CONFIG_H
#include "cubiomes/finders.h"
#include <QSettings>
#include <QString>
#include <QFont>
#include <QTextStream>
#include <vector>
#define APP_STRING "cubiomes-viewer"
struct ExtGenConfig
{
bool experimentalVers;
bool estimateTerrain;
bool saltOverride;
uint64_t salts[FEATURE_NUM];
ExtGenConfig() { reset(); }
void reset();
void load(QSettings& settings);
void save(QSettings& settings);
void load() { QSettings s(APP_STRING, APP_STRING); load(s); }
void save() { QSettings s(APP_STRING, APP_STRING); save(s); }
};
extern unsigned char g_biomeColors[256][3];
extern unsigned char g_tempsColors[256][3];
// Keep the extended generator settings in global scope.
extern ExtGenConfig g_extgen;
// global references to the default fonts
extern QFont *gp_font_default;
extern QFont *gp_font_mono;
struct WorldInfo
{
int mc;
bool large;
uint64_t seed;
int y;
WorldInfo() { reset(); }
bool equals(const WorldInfo& wi) const;
void reset();
void load(QSettings& settings);
void save(QSettings& settings);
void load() { QSettings s(APP_STRING, APP_STRING); load(s); }
void save() { QSettings s(APP_STRING, APP_STRING); save(s); }
bool read(const QString& line);
void write(QTextStream& stream);
};
enum {
LOPT_BIOMES,
LOPT_NOISE_PARA,
LOPT_NOISE_T_4 = LOPT_NOISE_PARA,
LOPT_NOISE_H_4,
LOPT_NOISE_C_4,
LOPT_NOISE_E_4,
LOPT_NOISE_D_4,
LOPT_NOISE_W_4,
LOPT_RIVER_4,
LOPT_OCEAN_256,
LOPT_NOOCEAN_1,
LOPT_BETA_T_1,
LOPT_BETA_H_1,
LOPT_HEIGHT_4,
LOPT_STRUCTS,
LOPT_MAX,
};
struct LayerOpt
{
int8_t mode;
int8_t disp[LOPT_MAX];
LayerOpt() { reset(); }
void reset();
int activeDisp() const;
bool activeDifference(const LayerOpt& l) const;
bool isClimate(int mc) const;
};
enum {
D_NONE = -1,
// generics
D_GRID,
D_SLIME,
// structures
D_DESERT,
D_JUNGLE,
D_IGLOO,
D_HUT,
D_VILLAGE,
D_MANSION,
D_MONUMENT,
D_RUINS,
D_SHIPWRECK,
D_TREASURE,
D_MINESHAFT,
D_WELL,
D_GEODE,
D_OUTPOST,
D_ANCIENTCITY,
D_TRAIL,
D_PORTAL,
D_PORTALN,
D_FORTESS,
D_BASTION,
D_ENDCITY,
D_GATEWAY,
// non-recurring structures
D_SPAWN,
D_STRONGHOLD,
D_STRUCT_NUM
};
const char *mapopt2str(int opt);
int str2mapopt(const char *s);
int mapopt2stype(int opt);
struct MapConfig
{
struct Opt
{
double scale;
bool enabled;
bool valid;
Opt() : scale(),enabled(),valid() {}
};
Opt opts[D_STRUCT_NUM];
MapConfig(bool init = true);
double scale(int opt) const { return opts[opt].scale; }
bool enabled(int opt) const { return opts[opt].enabled; }
bool valid(int opt) const { return (unsigned)opt < D_STRUCT_NUM && opts[opt].valid; }
bool equals(const MapConfig& a) const;
void reset();
void load(QSettings& settings);
void save(QSettings& settings);
void load() { QSettings s(APP_STRING, APP_STRING); load(s); }
void save() { QSettings s(APP_STRING, APP_STRING); save(s); }
};
enum { STYLE_SYSTEM, STYLE_DARK };
struct Config
{
bool smoothMotion;
bool showBBoxes;
bool restoreSession;
bool checkForUpdates;
int autosaveCycle;
int uistyle;
int maxMatching;
int gridSpacing;
int gridMultiplier;
int mapCacheSize;
int mapThreads;
QString biomeColorPath;
QString separator;
QString quote;
Config() { reset(); }
void reset();
void load(QSettings& settings);
void save(QSettings& settings);
void load() { QSettings s(APP_STRING, APP_STRING); load(s); }
void save() { QSettings s(APP_STRING, APP_STRING); save(s); }
};
enum { GEN48_AUTO, GEN48_QH, GEN48_QM, GEN48_LIST, GEN48_NONE };
enum { IDEAL, CLASSIC, NORMAL, BARELY, IDEAL_SALTED };
struct Gen48Config
{
int mode;
QString slist48path;
uint64_t salt;
uint64_t listsalt;
int qual;
int qmarea;
bool manualarea;
int x1, z1, x2, z2;
Gen48Config() { reset(); }
void reset();
bool read(const QString& line);
void write(QTextStream& stream);
};
// search type options from combobox
enum { SEARCH_INC = 0, SEARCH_BLOCKS = 1, SEARCH_LIST = 2 };
struct SearchConfig
{
int searchtype;
QString slist64path;
int threads;
uint64_t startseed;
bool stoponres;
uint64_t smin;
uint64_t smax;
SearchConfig() { reset(); }
void reset();
bool read(const QString& line);
void write(QTextStream& stream);
};
Q_DECLARE_METATYPE(int64_t)
Q_DECLARE_METATYPE(uint64_t)
Q_DECLARE_METATYPE(Pos)
Q_DECLARE_METATYPE(Config)
#endif // CONFIG_H

View File

@ -15,7 +15,6 @@
ConfigDialog::ConfigDialog(QWidget *parent, Config *config)
: QDialog(parent)
, ui(new Ui::ConfigDialog)
, visModified()
{
ui->setupUi(this);
@ -33,8 +32,7 @@ ConfigDialog::ConfigDialog(QWidget *parent, Config *config)
ui->lineMatching->setValidator(new QIntValidator(1, 99999999, ui->lineMatching));
ui->spinThreads->setRange(1, QThread::idealThreadCount());
initSettings(config);
visModified = false;
initConfig(config);
}
ConfigDialog::~ConfigDialog()
@ -42,7 +40,7 @@ ConfigDialog::~ConfigDialog()
delete ui;
}
void ConfigDialog::initSettings(Config *config)
void ConfigDialog::initConfig(Config *config)
{
ui->checkSmooth->setChecked(config->smoothMotion);
ui->checkBBoxes->setChecked(config->showBBoxes);
@ -64,7 +62,7 @@ void ConfigDialog::initSettings(Config *config)
setBiomeColorPath(config->biomeColorPath);
}
Config ConfigDialog::getSettings()
Config ConfigDialog::getConfig()
{
conf.smoothMotion = ui->checkSmooth->isChecked();
conf.showBBoxes = ui->checkBBoxes->isChecked();
@ -133,10 +131,16 @@ void ConfigDialog::setBiomeColorPath(QString path)
void ConfigDialog::on_buttonBox_clicked(QAbstractButton *button)
{
if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole)
int role = ui->buttonBox->buttonRole(button);
if (role == QDialogButtonBox::ResetRole)
{
conf.reset();
initSettings(&conf);
initConfig(&conf);
}
else if (role == QDialogButtonBox::AcceptRole || role == QDialogButtonBox::ApplyRole)
{
getConfig().save();
emit updateConfig();
}
}
@ -144,7 +148,10 @@ void ConfigDialog::on_buttonBiomeColorEditor_clicked()
{
BiomeColorDialog *dialog = new BiomeColorDialog(this, conf.biomeColorPath, -1, DIM_UNDEF);
if (dialog->exec() == QDialog::Accepted)
setBiomeColorPath(dialog->getRc());
{
QString rc = dialog->getRc();
setBiomeColorPath(rc);
}
}
void ConfigDialog::on_buttonBiomeColor_clicked()
@ -162,11 +169,13 @@ void ConfigDialog::on_buttonBiomeColor_clicked()
void ConfigDialog::on_buttonStructVisEdit_clicked()
{
StructureDialog *dialog = new StructureDialog(this);
if (dialog->exec() == QDialog::Accepted)
{
if ((visModified |= dialog->modified))
saveStructVis(dialog->structvis);
}
connect(dialog, SIGNAL(updateMapConfig()), this, SLOT(onUpdateMapConfig()));
dialog->show();
}
void ConfigDialog::onUpdateMapConfig()
{
emit updateMapConfig();
}
void ConfigDialog::on_buttonClear_clicked()

View File

@ -4,7 +4,7 @@
#include <QDialog>
#include <QAbstractButton>
#include "settings.h"
#include "config.h"
namespace Ui {
@ -20,13 +20,18 @@ public:
explicit ConfigDialog(QWidget *parent, Config *config);
~ConfigDialog();
void initSettings(Config *config);
Config getSettings();
void initConfig(Config *config);
Config getConfig();
void setBiomeColorPath(QString path);
signals:
void updateConfig();
void updateMapConfig();
private slots:
void onUpdateMapConfig();
void on_buttonBox_clicked(QAbstractButton *button);
void on_buttonBiomeColorEditor_clicked();
@ -43,8 +48,6 @@ private slots:
private:
Ui::ConfigDialog *ui;
Config conf;
public:
bool visModified;
};
#endif // CONFIGDIALOG_H

View File

@ -55,7 +55,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>

View File

@ -24,15 +24,18 @@ inline const char* struct2str(int stype)
case Monument: return "monument";
case Mansion: return "mansion";
case Outpost: return "outpost";
case Ruined_Portal: return "ruined_portal";
case Ruined_Portal_N: return "ruined_portal (nether)";
case Treasure: return "treasure";
case Mineshaft: return "mineshaft";
case Desert_Well: return "desert_well";
case Ruined_Portal: return "ruined_portal";
case Ruined_Portal_N: return "ruined_portal (nether)";
case Geode: return "amethyst_geode";
case Ancient_City: return "ancient_city";
case Trail_Ruin: return "trail_ruins";
case Fortress: return "fortress";
case Bastion: return "bastion";
case End_City: return "end_city";
case End_Gateway: return "end_gateway";
case Ancient_City: return "ancient_city";
}
return "?";
}

View File

@ -9,7 +9,7 @@
#include <QMutex>
#include <QDir>
#include "settings.h"
#include "config.h"
namespace Ui {
class ExportDialog;

View File

@ -5,7 +5,7 @@
#include <QGridLayout>
ExtGenDialog::ExtGenDialog(QWidget *parent, ExtGenSettings *extgen)
ExtGenDialog::ExtGenDialog(QWidget *parent, ExtGenConfig *extgen)
: QDialog(parent)
, ui(new Ui::ExtGenDialog)
, checkSalts{}
@ -59,7 +59,7 @@ ExtGenDialog::~ExtGenDialog()
delete ui;
}
void ExtGenDialog::initSettings(ExtGenSettings *extgen)
void ExtGenDialog::initSettings(ExtGenConfig *extgen)
{
ui->checkExperimental->setChecked(extgen->experimentalVers);
@ -89,7 +89,7 @@ void ExtGenDialog::initSettings(ExtGenSettings *extgen)
ui->groupSalts->setChecked(extgen->saltOverride);
}
ExtGenSettings ExtGenDialog::getSettings()
ExtGenConfig ExtGenDialog::getSettings()
{
extgen.experimentalVers = ui->checkExperimental->isChecked();
extgen.estimateTerrain = ui->checkEstimate->isChecked();

View File

@ -6,7 +6,7 @@
#include <QCheckBox>
#include <QLineEdit>
#include "settings.h"
#include "config.h"
namespace Ui {
@ -19,12 +19,12 @@ class ExtGenDialog : public QDialog
Q_OBJECT
public:
explicit ExtGenDialog(QWidget *parent, ExtGenSettings *extgen);
explicit ExtGenDialog(QWidget *parent, ExtGenConfig *extgen);
~ExtGenDialog();
void initSettings(ExtGenSettings *extgen);
void initSettings(ExtGenConfig *extgen);
ExtGenSettings getSettings();
ExtGenConfig getSettings();
private slots:
void on_buttonBox_clicked(QAbstractButton *button);
@ -36,7 +36,7 @@ private:
QCheckBox *checkSalts[FEATURE_NUM];
QLineEdit *lineSalts[FEATURE_NUM];
ExtGenSettings extgen;
ExtGenConfig extgen;
};
#endif // EXTGENDIALOG_H

View File

@ -70,25 +70,32 @@ void FormConditions::updateSensitivity()
{
ui->buttonRemove->setEnabled(false);
ui->buttonEdit->setEnabled(false);
ui->buttonDisable->setEnabled(false);
}
else if (selected.size() == 1)
{
ui->buttonRemove->setEnabled(true);
ui->buttonEdit->setEnabled(true);
ui->buttonDisable->setEnabled(true);
Condition c = qvariant_cast<Condition>(selected[0]->data(Qt::UserRole));
if (c.meta & Condition::DISABLED)
ui->buttonDisable->setText(tr("Enable"));
else
ui->buttonDisable->setText(tr("Disable"));
}
else
{
ui->buttonRemove->setEnabled(true);
ui->buttonEdit->setEnabled(false);
ui->buttonDisable->setEnabled(false);
}
int disabled = 0;
for (int i = 0; i < selected.size(); i++)
{
Condition c = qvariant_cast<Condition>(selected[i]->data(Qt::UserRole));
if (c.meta & Condition::DISABLED)
disabled++;
}
if (disabled == 0)
ui->buttonDisable->setText(tr("Disable"));
else if (disabled == selected.size())
ui->buttonDisable->setText(tr("Enable"));
else
ui->buttonDisable->setText(tr("Toggle"));
ui->buttonDisable->setEnabled(!selected.empty());
}

View File

@ -17,7 +17,16 @@
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<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" colspan="5">
@ -72,7 +81,7 @@
<item>
<widget class="QPushButton" name="buttonDisable">
<property name="text">
<string>Disable</string>
<string>Dis-/Enable</string>
</property>
</widget>
</item>

View File

@ -82,8 +82,8 @@ FormGen48::FormGen48(MainWindow *parent)
ui->lineList48->setFont(*gp_font_mono);
cond.type = 0;
Gen48Settings defaults;
setSettings(defaults, true);
Gen48Config defaults;
setConfig(defaults, true);
}
FormGen48::~FormGen48()
@ -150,7 +150,7 @@ bool FormGen48::setList48(QString path, bool quiet)
void FormGen48::setSettings(const Gen48Settings& gen48, bool quiet)
void FormGen48::setConfig(const Gen48Config& gen48, bool quiet)
{
ui->tabWidget->setCurrentIndex(gen48.mode);
ui->comboLow20->setCurrentIndex(gen48.qual);
@ -172,9 +172,9 @@ void FormGen48::setSettings(const Gen48Settings& gen48, bool quiet)
on_tabWidget_currentChanged(gen48.mode);
}
Gen48Settings FormGen48::getSettings(bool resolveauto)
Gen48Config FormGen48::getConfig(bool resolveauto)
{
Gen48Settings s;
Gen48Config s;
s.mode = ui->tabWidget->currentIndex();
s.qual = ui->comboLow20->currentIndex();
@ -205,7 +205,7 @@ Gen48Settings FormGen48::getSettings(bool resolveauto)
uint64_t FormGen48::estimateSeedCnt()
{
const Gen48Settings& gen48 = getSettings(true);
const Gen48Config& gen48 = getConfig(true);
uint64_t cnt = 0;
if (gen48.mode == GEN48_QH)
{

View File

@ -4,7 +4,7 @@
#include <QWidget>
#include <QThread>
#include "settings.h"
#include "config.h"
#include "search.h"
namespace Ui {
@ -22,8 +22,8 @@ public:
explicit FormGen48(MainWindow *parent);
~FormGen48();
void setSettings(const Gen48Settings& gen48, bool quiet);
Gen48Settings getSettings(bool resolveauto = false);
void setConfig(const Gen48Config& gen48, bool quiet);
Gen48Config getConfig(bool resolveauto = false);
bool setList48(QString path, bool quiet);
const std::vector<uint64_t>& getList48() { return slist48; }

View File

@ -341,7 +341,7 @@ void FormSearchControl::on_buttonStart_clicked()
if (ok)
{
Gen48Settings gen48 = parent->formGen48->getSettings(true);
Gen48Config gen48 = parent->formGen48->getConfig(true);
// the search can either use a full list or a 48-bit list
if (sc.searchtype == SEARCH_LIST)
slist = slist64;

View File

@ -13,7 +13,7 @@
#include "searchthread.h"
#include "protobasedialog.h"
#include "settings.h"
#include "config.h"
namespace Ui {
class FormSearchControl;

View File

@ -1,7 +1,7 @@
#include "layerdialog.h"
#include "ui_layerdialog.h"
#include "settings.h"
#include "config.h"
const char *getLayerOptionText(int mode, int disp)
@ -139,6 +139,8 @@ LayerDialog::LayerDialog(QWidget *parent, int mc)
radio[LOPT_RIVER_4] = ui->radioRiver;
radio[LOPT_OCEAN_256] = ui->radioOcean;
radio[LOPT_NOOCEAN_1] = ui->radioNoOcean;
radio[LOPT_BETA_T_1] = ui->radioBetaT;
radio[LOPT_BETA_H_1] = ui->radioBetaH;
radio[LOPT_HEIGHT_4] = ui->radioHeight;
radio[LOPT_STRUCTS] = ui->radioStruct;
@ -185,7 +187,7 @@ LayerDialog::LayerDialog(QWidget *parent, int mc)
{
radio[i]->setEnabled(mc > MC_1_12 && mc <= MC_1_17);
}
if (i == LOPT_NOOCEAN_1)
if (i == LOPT_NOOCEAN_1 || i == LOPT_BETA_T_1 || i == LOPT_BETA_H_1)
{
radio[i]->setEnabled(mc <= MC_B1_7);
}

View File

@ -5,7 +5,7 @@
#include <QRadioButton>
#include <QComboBox>
#include "settings.h"
#include "config.h"
namespace Ui {
class LayerDialog;

View File

@ -10,84 +10,6 @@
<normaloff>:/icons/logo.png</normaloff>:/icons/logo.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="5" column="1">
<widget class="QComboBox" name="comboNoiseC"/>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="comboNoiseE"/>
</item>
<item row="13" column="0">
<widget class="QRadioButton" name="radioStruct">
<property name="text">
<string>Structure potential</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QRadioButton" name="radioNoiseW">
<property name="text">
<string>Weirdness octaves</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QRadioButton" name="radioRiver">
<property name="text">
<string>River layer</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="radioBiomes">
<property name="text">
<string>Biome scale:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QRadioButton" name="radioNoiseH">
<property name="text">
<string>Humidity octaves:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QRadioButton" name="radioNoiseE">
<property name="text">
<string>Erosion octaves:</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QRadioButton" name="radioHeight">
<property name="text">
<string>Approx. surface height:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="radioNoiseT">
<property name="text">
<string>Temperature octaves:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="comboNoiseH"/>
</item>
<item row="14" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QComboBox" name="comboHeight"/>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBiomes">
<property name="minimumSize">
@ -106,20 +28,44 @@
<item row="8" column="1">
<widget class="QComboBox" name="comboNoiseW"/>
</item>
<item row="5" column="0">
<widget class="QRadioButton" name="radioNoiseC">
<item row="7" column="0">
<widget class="QRadioButton" name="radioNoiseD">
<property name="text">
<string>Contnentalness octaves:</string>
<string>Depth</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QRadioButton" name="radioNoiseW">
<property name="text">
<string>Weirdness octaves</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="radioBiomes">
<property name="text">
<string>Biome scale:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboNoiseT"/>
</item>
<item row="7" column="0">
<widget class="QRadioButton" name="radioNoiseD">
<item row="16" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="radioNoiseT">
<property name="text">
<string>Depth</string>
<string>Temperature octaves:</string>
</property>
</widget>
</item>
@ -130,6 +76,19 @@
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QComboBox" name="comboHeight"/>
</item>
<item row="14" column="0">
<widget class="QRadioButton" name="radioHeight">
<property name="text">
<string>Approx. surface height:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="comboNoiseH"/>
</item>
<item row="11" column="0">
<widget class="QRadioButton" name="radioNoOcean">
<property name="text">
@ -137,6 +96,61 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QRadioButton" name="radioNoiseC">
<property name="text">
<string>Contnentalness octaves:</string>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QRadioButton" name="radioStruct">
<property name="text">
<string>Structure potential</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QRadioButton" name="radioNoiseE">
<property name="text">
<string>Erosion octaves:</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QRadioButton" name="radioRiver">
<property name="text">
<string>River layer</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="comboNoiseC"/>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="comboNoiseE"/>
</item>
<item row="4" column="0">
<widget class="QRadioButton" name="radioNoiseH">
<property name="text">
<string>Humidity octaves:</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QRadioButton" name="radioBetaT">
<property name="text">
<string>Beta temperature</string>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QRadioButton" name="radioBetaH">
<property name="text">
<string>Beta humidity</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources>

View File

@ -2,6 +2,8 @@
#include <QApplication>
#include <QTranslator>
#include <QFontDatabase>
#include <QStandardPaths>
#include <QDir>
#include "world.h"
@ -13,7 +15,7 @@
unsigned char g_biomeColors[256][3];
unsigned char g_tempsColors[256][3];
ExtGenSettings g_extgen;
ExtGenConfig g_extgen;
QFont *gp_font_default;
QFont *gp_font_mono;
@ -32,7 +34,7 @@ int getStructureConfig_override(int stype, int mc, StructureConfig *sconf)
}
return ok;
}
#include "QDebug"
int main(int argc, char *argv[])
{
initBiomes();
@ -40,7 +42,23 @@ int main(int argc, char *argv[])
initBiomeTypeColors(g_tempsColors);
QApplication app(argc, argv);
QCoreApplication::setApplicationName("cubiomes-viewer");
QCoreApplication::setApplicationName(APP_STRING);
for (int i = 1; i < argc; i++)
{
if (strcmp(argv[i], "--reset-all") == 0)
{
QSettings settings(APP_STRING, APP_STRING);
settings.clear();
QString path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
QDir dir(path);
if (dir.exists() && path.contains(APP_STRING))
{
dir.removeRecursively();
}
}
}
QTranslator translator;
translator.load("en_US", ":/lang");

View File

@ -45,6 +45,7 @@ MainWindow::MainWindow(QWidget *parent)
, formControl()
, lopt()
, config()
, mconfig(false)
, prevdir(".")
, autosaveTimer()
, prevtab(-1)
@ -83,6 +84,8 @@ MainWindow::MainWindow(QWidget *parent)
laction[LOPT_RIVER_4] = ui->actionRiver;
laction[LOPT_OCEAN_256] = ui->actionOceanTemp;
laction[LOPT_NOOCEAN_1] = ui->actionNoOceans;
laction[LOPT_BETA_T_1] = ui->actionBetaTemperature;
laction[LOPT_BETA_H_1] = ui->actionBetaHumidity;
laction[LOPT_HEIGHT_4] = ui->actionHeight;
laction[LOPT_STRUCTS] = ui->actionStructures;
@ -125,9 +128,8 @@ MainWindow::MainWindow(QWidget *parent)
dimgroup->addAction(dimactions[i]);
}
dimactions[0]->setChecked(true);
ui->toolBar->addSeparator();
saction.resize(STRUCT_NUM);
saction.resize(D_STRUCT_NUM);
addMapAction(D_GRID, "grid", tr("Show grid"));
addMapAction(D_SLIME, "slime", tr("Show slime chunks"));
addMapAction(D_SPAWN, "spawn", tr("Show world spawn"));
@ -143,9 +145,12 @@ MainWindow::MainWindow(QWidget *parent)
addMapAction(D_RUINS, "ruins", tr("Show ocean ruins"));
addMapAction(D_SHIPWRECK, "shipwreck", tr("Show shipwrecks"));
addMapAction(D_TREASURE, "treasure", tr("Show buried treasures"));
addMapAction(D_WELL, "well", tr("Show desert wells"));
addMapAction(D_GEODE, "geode", tr("Show amethyst geodes"));
addMapAction(D_OUTPOST, "outpost", tr("Show pillager outposts"));
addMapAction(D_PORTAL, "portal", tr("Show ruined portals"));
addMapAction(D_ANCIENTCITY, "ancient_city", tr("Show ancient cities"));
addMapAction(D_TRAIL, "trail", tr("Show trail ruins"));
ui->toolBar->addSeparator();
addMapAction(D_FORTESS, "fortress", tr("Show nether fortresses"));
addMapAction(D_BASTION, "bastion", tr("Show bastions"));
@ -198,7 +203,7 @@ MainWindow::MainWindow(QWidget *parent)
// 48-bit generator settings are not all that interesting unless we are
// using them, so start as collapsed if they are on the "Auto" setting.
Gen48Settings gen48 = formGen48->getSettings(false);
Gen48Config gen48 = formGen48->getConfig(false);
ui->collapseGen48->init(tr("Seed generator (48-bit)"), formGen48, gen48.mode == GEN48_AUTO);
connect(formGen48, &FormGen48::changed, this, &MainWindow::onGen48Changed);
ui->collapseGen48->setInfo(
@ -297,7 +302,8 @@ bool MainWindow::getSeed(WorldInfo *wi, bool applyrand)
wi->mc = str2mc(mcs.c_str());
if (wi->mc < 0)
{
qDebug() << "Unknown MC version: " << mcs.c_str();
if (applyrand)
qDebug() << "Unknown MC version: " << mcs.c_str();
wi->mc = MC_NEWEST;
ok = false;
}
@ -363,6 +369,12 @@ bool MainWindow::setSeed(WorldInfo wi, int dim)
ui->menuHistory->setEnabled(true);
}
// temporarily disable UI to prevent recursive setSeed() updates
ui->comboBoxMC->setEnabled(false);
ui->checkLarge->setEnabled(false);
ui->seedEdit->setEnabled(false);
ui->comboY->setEnabled(false);
ui->checkLarge->setChecked(wi.large);
int i, n = ui->comboY->count();
for (i = 0; i < n; i++)
@ -376,7 +388,10 @@ bool MainWindow::setSeed(WorldInfo wi, int dim)
ui->seedEdit->setText(QString::asprintf("%" PRId64, (int64_t)wi.seed));
getMapView()->setSeed(wi, dim, lopt);
ui->comboBoxMC->setEnabled(true);
ui->checkLarge->setEnabled(wi.mc >= MC_1_3);
ui->seedEdit->setEnabled(true);
ui->comboY->setEnabled(true);
ISaveTab *tab = dynamic_cast<ISaveTab*>(ui->tabContainer->currentWidget());
if (tab)
@ -398,50 +413,28 @@ int MainWindow::getDim()
void MainWindow::saveSettings()
{
QSettings settings("cubiomes-viewer", "cubiomes-viewer");
QSettings settings(APP_STRING, APP_STRING);
settings.setValue("mainwindow/size", size());
settings.setValue("mainwindow/pos", pos());
settings.setValue("mainwindow/prevdir", prevdir);
settings.setValue("config/smoothMotion", config.smoothMotion);
settings.setValue("config/showBBoxes", config.showBBoxes);
settings.setValue("config/restoreSession", config.restoreSession);
settings.setValue("config/checkForUpdates", config.checkForUpdates);
settings.setValue("config/autosaveCycle", config.autosaveCycle);
settings.setValue("config/uistyle", config.uistyle);
settings.setValue("config/maxMatching", config.maxMatching);
settings.setValue("config/gridSpacing", config.gridSpacing);
settings.setValue("config/gridMultiplier", config.gridMultiplier);
settings.setValue("config/mapCacheSize", config.mapCacheSize);
settings.setValue("config/mapThreads", config.mapThreads);
settings.setValue("config/biomeColorPath", config.biomeColorPath);
settings.setValue("config/separator", config.separator);
settings.setValue("config/quote", config.quote);
settings.setValue("toolbar/area", toolBarArea(ui->toolBar));
settings.setValue("world/experimentalVers", g_extgen.experimentalVers);
settings.setValue("world/estimateTerrain", g_extgen.estimateTerrain);
settings.setValue("world/saltOverride", g_extgen.saltOverride);
for (int st = 0; st < FEATURE_NUM; st++)
{
uint64_t salt = g_extgen.salts[st];
if (salt <= MASK48)
settings.setValue(QString("world/salt_") + struct2str(st), (qulonglong)salt);
}
config.save(settings);
g_extgen.save(settings);
on_tabContainer_currentChanged(-1);
WorldInfo wi;
getSeed(&wi, false);
settings.setValue("map/mc", wi.mc);
settings.setValue("map/large", wi.large);
settings.setValue("map/seed", (qlonglong)wi.seed);
wi.save(settings);
settings.setValue("map/dim", getDim());
settings.setValue("map/x", getMapView()->getX());
settings.setValue("map/y", wi.y);
settings.setValue("map/z", getMapView()->getZ());
settings.setValue("map/scale", getMapView()->getScale());
for (int stype = 0; stype < STRUCT_NUM; stype++)
for (int stype = 0; stype < D_STRUCT_NUM; stype++)
{
QString s = QString("map/show_") + mapopt2str(stype);
settings.setValue(s, getMapView()->getShow(stype));
@ -460,7 +453,7 @@ void MainWindow::saveSettings()
void MainWindow::loadSettings()
{
QSettings settings("cubiomes-viewer", "cubiomes-viewer");
QSettings settings(APP_STRING, APP_STRING);
getMapView()->deleteWorld();
@ -468,38 +461,14 @@ void MainWindow::loadSettings()
move(settings.value("mainwindow/pos", pos()).toPoint());
prevdir = settings.value("mainwindow/prevdir", pos()).toString();
config.smoothMotion = settings.value("config/smoothMotion", config.smoothMotion).toBool();
config.showBBoxes = settings.value("config/showBBoxes", config.showBBoxes).toBool();
config.restoreSession = settings.value("config/restoreSession", config.restoreSession).toBool();
config.checkForUpdates = settings.value("config/checkForUpdates", config.checkForUpdates).toBool();
config.autosaveCycle = settings.value("config/autosaveCycle", config.autosaveCycle).toInt();
config.uistyle = settings.value("config/uistyle", config.uistyle).toInt();
config.maxMatching = settings.value("config/maxMatching", config.maxMatching).toInt();
config.gridSpacing = settings.value("config/gridSpacing", config.gridSpacing).toInt();
config.gridMultiplier = settings.value("config/gridMultiplier", config.gridMultiplier).toInt();
config.mapCacheSize = settings.value("config/mapCacheSize", config.mapCacheSize).toInt();
config.mapThreads = settings.value("config/mapThreads", config.mapThreads).toInt();
config.biomeColorPath = settings.value("config/biomeColorPath", config.biomeColorPath).toString();
config.separator = settings.value("config/separator", config.separator).toString();
config.quote = settings.value("config/quote", config.quote).toString();
if (!config.biomeColorPath.isEmpty())
onBiomeColorChange();
ui->seedEdit->setText(settings.value("map/seed").toString());
g_extgen.experimentalVers = settings.value("world/experimentalVers", g_extgen.experimentalVers).toBool();
g_extgen.estimateTerrain = settings.value("world/estimateTerrain", g_extgen.estimateTerrain).toBool();
g_extgen.saltOverride = settings.value("world/saltOverride", g_extgen.saltOverride).toBool();
for (int st = 0; st < FEATURE_NUM; st++)
int toolarea = toolBarArea(ui->toolBar);
int toolarea_new = settings.value("toolbar/area", toolarea).toInt();
if (toolarea != toolarea_new)
{
QVariant v = QVariant::fromValue(~(qulonglong)0);
g_extgen.salts[st] = settings.value(QString("world/salt_") + struct2str(st), v).toULongLong();
removeToolBar(ui->toolBar);
addToolBar((Qt::ToolBarArea) toolarea_new, ui->toolBar);
ui->toolBar->show();
}
setMCList(g_extgen.experimentalVers);
getMapView()->setConfig(config);
onStyleChanged(config.uistyle);
qreal x = getMapView()->getX();
qreal z = getMapView()->getZ();
@ -509,7 +478,7 @@ void MainWindow::loadSettings()
scale = settings.value("map/scale", scale).toDouble();
mapGoto(x, z, scale);
for (int sopt = 0; sopt < STRUCT_NUM; sopt++)
for (int sopt = 0; sopt < D_STRUCT_NUM; sopt++)
{
bool show = getMapView()->getShow(sopt);
QString soptstr = QString("map/show_") + mapopt2str(sopt);
@ -519,15 +488,19 @@ void MainWindow::loadSettings()
getMapView()->setShow(sopt, show);
}
g_extgen.load(settings);
setMCList(g_extgen.experimentalVers);
WorldInfo wi;
getSeed(&wi, false);
// NOTE: version can be wrong when the mc-enum changes, but the session file should correct it
wi.mc = settings.value("map/mc", wi.mc).toInt();
wi.large = settings.value("map/large", wi.large).toBool();
wi.y = settings.value("map/y", 256).toInt();
getSeed(&wi, false);
wi.load(settings);
int dim = settings.value("map/dim", getDim()).toInt();
setSeed(wi, dim);
onUpdateConfig();
onUpdateMapConfig();
if (config.restoreSession)
{
QString path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
@ -537,16 +510,6 @@ void MainWindow::loadSettings()
loadProgress(path, false, false);
}
}
if (config.autosaveCycle > 0)
{
autosaveTimer.setInterval(config.autosaveCycle * 60000);
autosaveTimer.start();
}
else
{
autosaveTimer.stop();
}
}
@ -562,7 +525,7 @@ bool MainWindow::saveProgress(QString fnam, bool quiet)
}
SearchConfig searchconf = formControl->getSearchConfig();
Gen48Settings gen48 = formGen48->getSettings(false);
Gen48Config gen48 = formGen48->getConfig(false);
QVector<Condition> condvec = formCond->getConditions();
QVector<uint64_t> results = formControl->getResults();
@ -573,36 +536,10 @@ bool MainWindow::saveProgress(QString fnam, bool quiet)
stream << "#Version: " << VERS_MAJOR << "." << VERS_MINOR << "." << VERS_PATCH << "\n";
stream << "#Time: " << QDateTime::currentDateTime().toString() << "\n";
// MC version of the session should take priority over the one in the settings
stream << "#MC: " << mc2str(wi.mc) << "\n";
stream << "#Large: " << wi.large << "\n";
wi.write(stream);
stream << "#Search: " << searchconf.searchtype << "\n";
if (!searchconf.slist64path.isEmpty())
stream << "#List64: " << searchconf.slist64path.replace("\n", "") << "\n";
stream << "#Progress: " << searchconf.startseed << "\n";
stream << "#Threads: " << searchconf.threads << "\n";
stream << "#ResStop: " << (int)searchconf.stoponres << "\n";
stream << "#Mode48: " << gen48.mode << "\n";
if (!gen48.slist48path.isEmpty())
stream << "#List48: " << gen48.slist48path.replace("\n", "") << "\n";
stream << "#HutQual: " << gen48.qual << "\n";
stream << "#MonArea: " << gen48.qmarea << "\n";
if (gen48.salt != 0)
stream << "#Salt: " << gen48.salt << "\n";
if (gen48.listsalt != 0)
stream << "#LSalt: " << gen48.listsalt << "\n";
if (gen48.manualarea)
{
stream << "#Gen48X1: " << gen48.x1 << "\n";
stream << "#Gen48Z1: " << gen48.z1 << "\n";
stream << "#Gen48X2: " << gen48.x2 << "\n";
stream << "#Gen48Z2: " << gen48.z2 << "\n";
}
if (searchconf.smin != 0)
stream << "#SMin: " << searchconf.smin << "\n";
if (searchconf.smax != ~(uint64_t)0)
stream << "#SMax: " << searchconf.smax << "\n";
searchconf.write(stream);
gen48.write(stream);
for (Condition &c : condvec)
stream << "#Cond: " << c.toHex() << "\n";
@ -626,12 +563,10 @@ bool MainWindow::loadProgress(QString fnam, bool keepresults, bool quiet)
int major = 0, minor = 0, patch = 0;
SearchConfig searchconf = formControl->getSearchConfig();
Gen48Settings gen48 = formGen48->getSettings(false);
Gen48Config gen48 = formGen48->getConfig(false);
QVector<Condition> condvec;
QVector<uint64_t> seeds;
char buf[4096];
int tmp;
WorldInfo wi;
getSeed(&wi, true);
@ -669,35 +604,16 @@ bool MainWindow::loadProgress(QString fnam, bool keepresults, bool quiet)
{
lno++;
line = stream.readLine();
QByteArray ba = line.toLocal8Bit();
const char *p = ba.data();
if (line.isEmpty()) continue;
if (line.startsWith("#Time:")) continue;
if (line.startsWith("#Title:")) continue;
if (line.startsWith("#Desc:")) continue;
else if (sscanf(p, "#MC: %8[^\n]", buf) == 1) { wi.mc = str2mc(buf); if (wi.mc < 0) wi.mc = MC_NEWEST; }
else if (sscanf(p, "#Large: %d", &tmp) == 1) { wi.large = tmp; }
// SearchConfig
else if (sscanf(p, "#Search: %d", &searchconf.searchtype) == 1) {}
else if (sscanf(p, "#Progress: %" PRId64, &searchconf.startseed) == 1) {}
else if (sscanf(p, "#Threads: %d", &searchconf.threads) == 1) {}
else if (sscanf(p, "#ResStop: %d", &tmp) == 1) { searchconf.stoponres = tmp; }
else if (line.startsWith("#List64: ")) { searchconf.slist64path = line.mid(11).trimmed(); }
// Gen48Settings
else if (sscanf(p, "#Mode48: %d", &gen48.mode) == 1) {}
else if (sscanf(p, "#HutQual: %d", &gen48.qual) == 1) {}
else if (sscanf(p, "#MonArea: %d", &gen48.qmarea) == 1) {}
else if (sscanf(p, "#Salt: %" PRIu64, &gen48.salt) == 1) {}
else if (sscanf(p, "#LSalt: %" PRIu64, &gen48.listsalt) == 1) {}
else if (sscanf(p, "#Gen48X1: %d", &gen48.x1) == 1) { gen48.manualarea = true; }
else if (sscanf(p, "#Gen48Z1: %d", &gen48.z1) == 1) { gen48.manualarea = true; }
else if (sscanf(p, "#Gen48X2: %d", &gen48.x2) == 1) { gen48.manualarea = true; }
else if (sscanf(p, "#Gen48Z2: %d", &gen48.z2) == 1) { gen48.manualarea = true; }
else if (line.startsWith("#List48: ")) { gen48.slist48path = line.mid(11).trimmed(); }
else if (sscanf(p, "#SMin: %" PRIu64, &searchconf.smin) == 1) {}
else if (sscanf(p, "#SMax: %" PRIu64, &searchconf.smax) == 1) {}
else if (line.startsWith("#Cond:"))
if (searchconf.read(line)) continue;
if (gen48.read(line)) continue;
if (wi.read(line)) continue;
if (line.startsWith("#Cond:"))
{ // Conditions
Condition c;
if (c.readHex(line.mid(6).trimmed()))
@ -718,8 +634,10 @@ bool MainWindow::loadProgress(QString fnam, bool keepresults, bool quiet)
}
else
{ // Seeds
QByteArray ba = line.toLocal8Bit();
const char *p = ba.data();
uint64_t s;
if (sscanf(line.toLocal8Bit().data(), "%" PRId64, (int64_t*)&s) == 1)
if (sscanf(p, "%" PRId64, (int64_t*)&s) == 1)
{
seeds.push_back(s);
}
@ -746,7 +664,7 @@ bool MainWindow::loadProgress(QString fnam, bool keepresults, bool quiet)
formCond->addItemCondition(item, c);
}
formGen48->setSettings(gen48, quiet);
formGen48->setConfig(gen48, quiet);
formGen48->updateCount();
if (!keepresults)
@ -767,6 +685,8 @@ void MainWindow::updateMapSeed()
bool state;
state = (wi.mc <= MC_B1_7);
ui->actionNoOceans->setEnabled(state);
ui->actionBetaTemperature->setEnabled(state);
ui->actionBetaHumidity->setEnabled(state);
state = (wi.mc >= MC_1_13 && wi.mc <= MC_1_17);
ui->actionRiver->setEnabled(state);
ui->actionOceanTemp->setEnabled(state);
@ -839,7 +759,7 @@ void MainWindow::setMCList(bool experimental)
{
if (!experimental && mc != wi.mc)
{
if (mc <= MC_1_0 || mc == MC_1_16_1 || mc == MC_1_19_2 || mc == MC_1_20)
if (mc <= MC_1_0 || mc == MC_1_16_1 || mc == MC_1_19_2)
continue;
}
const char *mcs = mc2str(mc);
@ -847,9 +767,11 @@ void MainWindow::setMCList(bool experimental)
mclist.append(mcs);
}
const QString s = mc2str(wi.mc);
ui->comboBoxMC->setEnabled(false);
ui->comboBoxMC->clear();
ui->comboBoxMC->addItems(mclist);
ui->comboBoxMC->setCurrentText(s);
ui->comboBoxMC->setEnabled(true);
}
int MainWindow::warning(QString text, QMessageBox::StandardButtons buttons)
@ -870,22 +792,23 @@ void MainWindow::setBiomeColorRc(QString rc)
void MainWindow::on_comboBoxMC_currentIndexChanged(int)
{
if (ui->comboBoxMC->count())
{
if (ui->comboBoxMC->isEnabled() && ui->comboBoxMC->count())
updateMapSeed();
}
}
void MainWindow::on_seedEdit_editingFinished()
{
updateMapSeed();
if (ui->seedEdit->isEnabled())
updateMapSeed();
}
void MainWindow::on_checkLarge_toggled()
{
updateMapSeed();
if (ui->checkLarge->isEnabled())
updateMapSeed();
}
void MainWindow::on_comboY_currentIndexChanged(int)
{
updateMapSeed();
if (ui->comboY->isEnabled())
updateMapSeed();
}
void MainWindow::on_seedEdit_textChanged(const QString &a)
@ -934,41 +857,9 @@ void MainWindow::on_actionQuit_triggered()
void MainWindow::on_actionPreferences_triggered()
{
ConfigDialog *dialog = new ConfigDialog(this, &config);
int status = dialog->exec();
if (status == QDialog::Accepted)
{
applyConfigChanges(config, dialog->getSettings());
}
if (dialog->visModified)
{
getMapView()->deleteWorld();
updateMapSeed();
}
}
void MainWindow::onBiomeColorChange()
{
QFile file(config.biomeColorPath);
if (!config.biomeColorPath.isEmpty() && file.open(QIODevice::ReadOnly))
{
char buf[32*1024];
qint64 siz = file.read(buf, sizeof(buf)-1);
file.close();
if (siz >= 0)
{
buf[siz] = 0;
initBiomeColors(g_biomeColors);
parseBiomeColors(g_biomeColors, buf);
}
}
else
{
initBiomeColors(g_biomeColors);
}
getMapView()->refreshBiomeColors();
ISaveTab *tab = dynamic_cast<ISaveTab*>(ui->tabContainer->currentWidget());
if (tab)
tab->refresh();
connect(dialog, SIGNAL(updateConfig()), this, SLOT(onUpdateConfig()));
connect(dialog, SIGNAL(updateMapConfig()), this, SLOT(onUpdateMapConfig()));
dialog->show();
}
void MainWindow::on_actionGo_to_triggered()
@ -989,11 +880,8 @@ void MainWindow::on_actionOpenShadow_triggered()
void MainWindow::on_actionStructure_visibility_triggered()
{
StructureDialog *dialog = new StructureDialog(this);
if (dialog->exec() != QDialog::Accepted || !dialog->modified)
return;
saveStructVis(dialog->structvis);
getMapView()->deleteWorld();
updateMapSeed();
connect(dialog, SIGNAL(updateMapConfig()), this, SLOT(onUpdateMapConfig()));
dialog->show();
}
void MainWindow::on_actionBiome_colors_triggered()
@ -1114,7 +1002,7 @@ void MainWindow::on_actionLayerDisplay_triggered()
void MainWindow::on_tabContainer_currentChanged(int index)
{
QSettings settings("cubiomes-viewer", "cubiomes-viewer");
QSettings settings(APP_STRING, APP_STRING);
ISaveTab *tabold = dynamic_cast<ISaveTab*>(ui->tabContainer->widget(prevtab));
ISaveTab *tabnew = dynamic_cast<ISaveTab*>(ui->tabContainer->widget(index));
if (tabold) tabold->save(settings);
@ -1200,6 +1088,70 @@ void MainWindow::onSearchStatusChanged(bool running)
formGen48->setEnabled(!running);
}
void MainWindow::onUpdateConfig()
{
Config old = config;
config.load();
getMapView()->setConfig(config);
if (old.uistyle != config.uistyle)
onStyleChanged(config.uistyle);
if (!old.biomeColorPath.isEmpty() || !config.biomeColorPath.isEmpty())
onBiomeColorChange();
if (config.autosaveCycle)
{
autosaveTimer.setInterval(config.autosaveCycle * 60000);
autosaveTimer.start();
}
else
{
autosaveTimer.stop();
}
}
void MainWindow::onUpdateMapConfig()
{
MapConfig old = mconfig;
mconfig.load();
if (!old.equals(mconfig))
{
for (int opt = D_GRID; opt < D_STRUCT_NUM; opt++)
{
if (saction[opt] && mconfig.valid(opt))
saction[opt]->setVisible(mconfig.enabled(opt));
}
getMapView()->deleteWorld();
updateMapSeed();
}
}
void MainWindow::onBiomeColorChange()
{
QFile file(config.biomeColorPath);
if (!config.biomeColorPath.isEmpty() && file.open(QIODevice::ReadOnly))
{
char buf[32*1024];
qint64 siz = file.read(buf, sizeof(buf)-1);
file.close();
if (siz >= 0)
{
buf[siz] = 0;
initBiomeColors(g_biomeColors);
parseBiomeColors(g_biomeColors, buf);
}
}
else
{
initBiomeColors(g_biomeColors);
}
getMapView()->refreshBiomeColors();
ISaveTab *tab = dynamic_cast<ISaveTab*>(ui->tabContainer->currentWidget());
if (tab)
tab->refresh();
}
void MainWindow::onStyleChanged(int style)
{
//QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, false);

View File

@ -115,8 +115,10 @@ private slots:
void onGen48Changed();
void onSelectedSeedChanged(uint64_t seed);
void onSearchStatusChanged(bool running);
void onStyleChanged(int style);
void onUpdateConfig();
void onUpdateMapConfig();
void onBiomeColorChange();
void onStyleChanged(int style);
void onDockFloating(bool floating);
public:
@ -129,6 +131,7 @@ public:
FormSearchControl *formControl;
LayerOpt lopt;
Config config;
MapConfig mconfig;
QString prevdir;
QTimer autosaveTimer;
int prevtab;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1280</width>
<height>800</height>
<width>1600</width>
<height>900</height>
</rect>
</property>
<property name="windowTitle">
@ -291,8 +291,8 @@ QToolButton {
<rect>
<x>0</x>
<y>0</y>
<width>1258</width>
<height>673</height>
<width>1577</width>
<height>773</height>
</rect>
</property>
<property name="sizePolicy">
@ -397,6 +397,9 @@ QSplitter {
<property name="windowTitle">
<string>Map controls</string>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
@ -418,7 +421,8 @@ QToolButton:!checked {
}
QToolButton:checked {
background-color: #8a9dc4;
}</string>
}
</string>
</property>
<property name="movable">
<bool>true</bool>
@ -426,6 +430,9 @@ QToolButton:checked {
<property name="allowedAreas">
<set>Qt::AllToolBarAreas</set>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="iconSize">
<size>
<width>20</width>
@ -447,7 +454,7 @@ QToolButton:checked {
<rect>
<x>0</x>
<y>0</y>
<width>1280</width>
<width>1600</width>
<height>22</height>
</rect>
</property>
@ -529,6 +536,8 @@ QToolButton:checked {
<addaction name="actionOceanTemp"/>
<addaction name="separator"/>
<addaction name="actionNoOceans"/>
<addaction name="actionBetaTemperature"/>
<addaction name="actionBetaHumidity"/>
<addaction name="separator"/>
<addaction name="actionHeight"/>
<addaction name="actionStructures"/>
@ -680,7 +689,7 @@ QToolButton:checked {
</action>
<action name="actionStructure_visibility">
<property name="text">
<string>Structure zoom limits...</string>
<string>Structure visibility...</string>
</property>
</action>
<action name="actionParaTemperature">
@ -797,6 +806,22 @@ QToolButton:checked {
<string>(Beta 1.7) No beta oceans</string>
</property>
</action>
<action name="actionBetaTemperature">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>(Beta 1.7) Temperature</string>
</property>
</action>
<action name="actionBetaHumidity">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>(Beta 1.7) Humidity</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -156,6 +156,24 @@ void MapView::animateView(qreal x_dst, qreal z_dst, qreal s_dst)
update(2);
}
void MapView::zoom(qreal factor)
{
qreal zoommin = 1.0 / 2048.0, zoommax = 128.0;
if (factor < 1 && blocks2pix < zoommin) return;
if (factor > 1 && blocks2pix > zoommax) return;
blocks2pix *= factor;
if (factor < 1 && blocks2pix < zoommin) blocks2pix = zoommin;
if (factor > 1 && blocks2pix > zoommax) blocks2pix = zoommax;
update();
}
bool MapView::getShow(int stype)
{
if (stype < 0 || stype >= D_STRUCT_NUM)
return false;
return sshow[stype];
}
void MapView::setShow(int stype, bool v)
{
sshow[stype] = v;
@ -180,7 +198,7 @@ void MapView::settingsToWorld()
{
if (!world)
return;
for (int s = 0; s < STRUCT_NUM; s++)
for (int s = 0; s < D_STRUCT_NUM; s++)
world->sshow[s] = sshow[s];
world->showBB = config.showBBoxes;
world->gridspacing = config.gridSpacing;
@ -291,12 +309,11 @@ void MapView::update(int cnt)
QWidget::update();
}
Pos MapView::getActivePos()
VarPos MapView::getActivePos()
{
Pos p = overlay->pos;
if (world && world->selopt != D_NONE)
p = world->selvp.p;
return p;
return world->selvp;
return VarPos(overlay->pos, -1);
}
QPixmap MapView::screenshot()
@ -322,22 +339,45 @@ void MapView::showContextMenu(const QPoint &pos)
if (world)
{
mstart = pos;
world->selx = mstart.x();
world->selz = mstart.y();
world->seldo = true;
world->selopt = D_NONE;
world->setSelectPos(mstart);
grab(); // invokes an immediate paint call
}
Pos p = getActivePos();
VarPos vp = getActivePos();
QString seed = world ? QString::asprintf("%" PRId64, (int64_t)world->wi.seed) : "";
QString tp = QString::asprintf("/tp @p %d ~ %d", p.x, p.z);
QString coords = QString::asprintf("%d %d", p.x, p.z);
QString chunk = QString::asprintf("%d %d", p.x >> 4, p.z >> 4);
QString region = QString::asprintf("%d %d", p.x >> 9, p.z >> 9);
QString tp = QString::asprintf("/tp @p %d ~ %d", vp.p.x, vp.p.z);
QString coords = QString::asprintf("%d %d", vp.p.x, vp.p.z);
QString chunk = QString::asprintf("%d %d", vp.p.x >> 4, vp.p.z >> 4);
QString region = QString::asprintf("%d %d", vp.p.x >> 9, vp.p.z >> 9);
menu.addAction(tr("Go to coordinates..."), this, &MapView::onGoto, QKeySequence(Qt::CTRL + Qt::Key_G));
menu.addAction(tr("Copy seed: ")+seed, this, &MapView::copySeed, QKeySequence::Copy);
if (vp.type != -1)
{ // structure has a known size / location
int midx, midy, midz;
if (vp.pieces.size() > 0)
{
const Piece& pc = vp.pieces[0];
midx = (pc.bb0.x + pc.bb1.x) >> 1;
midy = (pc.bb0.y);
midz = (pc.bb0.z + pc.bb1.z) >> 1;
}
else
{
midx = vp.p.x + vp.v.x + vp.v.sx / 2;
midy = vp.v.y;
midz = vp.p.z + vp.v.z + vp.v.sz / 2;
if (midy >= 320 && world)
{
midy = world->estimateSurface(Pos{midx, midz}) + 8;
if (midy < 63)
midy = 63;
}
}
QString tps = QString::asprintf("/tp @p %d %d %d", midx, midy, midz);
menu.addAction(tr("Copy tp: ")+tps, [=](){ this->copyText(tps); });
}
menu.addAction(tr("Copy tp: ")+tp, [=](){ this->copyText(tp); });
menu.addAction(tr("Copy block: ")+coords, [=](){ this->copyText(coords); });
menu.addAction(tr("Copy chunk: ")+chunk, [=](){ this->copyText(chunk); });
@ -469,16 +509,11 @@ void MapView::resizeEvent(QResizeEvent *e)
overlay->resize(width(), height());
}
void MapView::wheelEvent(QWheelEvent *e)
{
qreal zoommin = 1.0 / 2048.0, zoommax = 128.0;
const qreal ang = e->angleDelta().y() / 8; // e->delta() / 8;
if (ang < 0 && blocks2pix < zoommin) return;
if (ang > 0 && blocks2pix > zoommax) return;
blocks2pix *= pow(2, ang/100);
if (ang < 0 && blocks2pix < zoommin) blocks2pix = zoommin;
if (ang > 0 && blocks2pix > zoommax) blocks2pix = zoommax;
update();
zoom(pow(2, ang/100));
}
void MapView::mousePressEvent(QMouseEvent *e)
@ -503,9 +538,7 @@ void MapView::mousePressEvent(QMouseEvent *e)
if (world)
{
world->selx = mstart.x();
world->selz = mstart.y();
world->seldo = true;
world->setSelectPos(mstart);
update();
}
}
@ -559,18 +592,45 @@ void MapView::mouseReleaseEvent(QMouseEvent *e)
if (world && e->pos() == mstart)
{
world->selx = mstart.x();
world->selz = mstart.y();
world->seldo = true;
world->selopt = D_NONE;
world->setSelectPos(mstart);
}
}
}
void MapView::keyReleaseEvent(QKeyEvent *e)
void MapView::keyPressEvent(QKeyEvent *e)
{
if (e->matches(QKeySequence::Copy))
copySeed();
QWidget::keyReleaseEvent(e);
qreal step = 4 / blocks2pix;
switch (e->key())
{
case Qt::Key_0:
if (e->modifiers() == 0)
setView(0, 0);
break;
case Qt::Key_Plus:
zoom(pow(2, +0.125));
break;
case Qt::Key_Minus:
zoom(pow(2, -0.125));
break;
case Qt::Key_Up:
focusz -= step;
update();
break;
case Qt::Key_Down:
focusz += step;
update();
break;
case Qt::Key_Left:
focusx -= step;
update();
break;
case Qt::Key_Right:
focusx += step;
update();
break;
}
QWidget::keyPressEvent(e);
}

View File

@ -41,13 +41,16 @@ public:
void setSeed(WorldInfo wi, int dim, LayerOpt lopt);
void setView(qreal x, qreal z, qreal scale = 0);
void animateView(qreal x, qreal z, qreal scale);
void zoom(qreal factor);
// animation
qreal x_src, z_src, s_src;
qreal x_dst, z_dst, s_dst;
qreal s_mul;
qreal atime;
QElapsedTimer anielapsed;
bool getShow(int stype) { return stype >= 0 && stype < STRUCT_NUM ? sshow[stype] : false; }
bool getShow(int stype);
void setShow(int stype, bool v);
void setConfig(const Config& config);
void refreshBiomeColors();
@ -56,7 +59,7 @@ public:
void update(int cnt = 1);
Pos getActivePos();
VarPos getActivePos();
QPixmap screenshot();
@ -82,7 +85,7 @@ public slots:
void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE;
void keyReleaseEvent(QKeyEvent *) Q_DECL_OVERRIDE;
void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE;
public:
QWorld *world;
@ -107,7 +110,7 @@ private:
bool measure;
int updatecounter;
bool sshow[STRUCT_NUM];
bool sshow[D_STRUCT_NUM];
LayerOpt lopt;
Config config;
};

View File

@ -1,7 +1,7 @@
#ifndef EXAMPLESDIALOG_H
#define EXAMPLESDIALOG_H
#include "settings.h"
#include "config.h"
#include "formconditions.h"
#include <QDialog>

View File

@ -996,9 +996,11 @@ L_qm_any:
case F_RUINS:
case F_SHIPWRECK:
case F_TREASURE:
case F_WELL:
case F_PORTAL:
case F_PORTALN:
case F_ANCIENT_CITY:
case F_TRAILS:
case F_FORTRESS:
case F_BASTION:

View File

@ -1,7 +1,7 @@
#ifndef SEARCH_H
#define SEARCH_H
#include "settings.h"
#include "config.h"
#include "lua/src/lua.hpp"
@ -91,6 +91,8 @@ enum
F_CLIMATE_MINMAX,
F_HEIGHT,
F_LUA,
F_WELL,
F_TRAILS,
// new filters should be added here at the end to keep some downwards compatibility
FILTER_MAX,
};
@ -535,6 +537,13 @@ static const struct FilterList
"accordingly.")
};
list[F_WELL] = FilterInfo{
CAT_STRUCT, 1, 1, 1, 1, 0, Desert_Well, 1, 0, 1, MC_1_13, MC_NEWEST, 0, 0, disp++,
":icons/well.png",
_("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++,
":icons/outpost.png",
@ -549,6 +558,13 @@ static const struct FilterList
""
};
list[F_TRAILS] = FilterInfo{
CAT_STRUCT, 1, 1, 1, 1, 0, Trail_Ruin, 1, 0, 1, MC_1_20, MC_NEWEST, 0, 0, disp++,
":icons/trail.png",
_("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++,
":icons/portal.png",

View File

@ -47,7 +47,7 @@ SearchMaster::~SearchMaster()
bool SearchMaster::set(
WorldInfo wi,
const SearchConfig& sc,
const Gen48Settings& gen48,
const Gen48Config& gen48,
const Config& config,
std::vector<uint64_t>& slist,
const QVector<Condition>& cv
@ -235,7 +235,7 @@ bool SearchMaster::set(
static int check(uint64_t s48, void *data)
{
(void) data;
const StructureConfig sconf = {0,0,0,0,0};
const StructureConfig sconf = {0,0,0,0,0,0};
return isQuadBaseFeature24(sconf, s48, 7+1, 7+1, 9+1) != 0;
}
@ -319,7 +319,7 @@ static void genQHBases(QObject *qtobj, int qual, uint64_t salt, std::vector<uint
}
static bool applyTranspose(std::vector<uint64_t>& slist,
const Gen48Settings& gen48, uint64_t bufmax)
const Gen48Config& gen48, uint64_t bufmax)
{
std::vector<uint64_t> list48;

View File

@ -2,7 +2,7 @@
#define SEARCHTHREAD_H
#include "search.h"
#include "settings.h"
#include "config.h"
#include <QThread>
#include <QMutex>
@ -20,7 +20,7 @@ public:
SearchMaster(FormSearchControl *parent);
virtual ~SearchMaster();
bool set(WorldInfo wi, const SearchConfig& sc, const Gen48Settings& gen48, const Config& config,
bool set(WorldInfo wi, const SearchConfig& sc, const Gen48Config& gen48, const Config& config,
std::vector<uint64_t>& slist, const QVector<Condition>& cv);
void presearch();
@ -58,7 +58,7 @@ public:
ConditionTree condtree;
int itemsize; // number of seeds per search item
int threadcnt; // numbr of worker threads
Gen48Settings gen48; // 48-bit generator settings
Gen48Config gen48; // 48-bit generator settings
std::vector<uint64_t> slist; // candidate list
uint64_t idx; // index within candidate list
uint64_t scnt; // search space size

View File

@ -1,206 +0,0 @@
#ifndef SETTINGS_H
#define SETTINGS_H
#include "cubiomes/finders.h"
#include <QThread>
#include <QString>
#include <QFont>
#include <vector>
extern unsigned char g_biomeColors[256][3];
extern unsigned char g_tempsColors[256][3];
struct ExtGenSettings
{
bool experimentalVers;
bool estimateTerrain;
bool saltOverride;
uint64_t salts[FEATURE_NUM];
ExtGenSettings() { reset(); }
void reset()
{
experimentalVers = false;
estimateTerrain = true;
saltOverride = false;
for (int i = 0; i < FEATURE_NUM; i++)
salts[i] = ~(uint64_t)0;
}
};
// Keep the extended generator settings in global scope.
extern ExtGenSettings g_extgen;
// global references to the default fonts
extern QFont *gp_font_default;
extern QFont *gp_font_mono;
struct WorldInfo
{
int mc;
bool large;
uint64_t seed;
int y;
WorldInfo() { reset(); }
bool equals(const WorldInfo& wi) const
{
return mc == wi.mc && large == wi.large && seed == wi.seed && y == wi.y;
}
void reset()
{
mc = MC_NEWEST;
large = false;
seed = 0;
y = 255;
}
};
enum {
LOPT_BIOMES,
LOPT_NOISE_PARA,
LOPT_NOISE_T_4 = LOPT_NOISE_PARA,
LOPT_NOISE_H_4,
LOPT_NOISE_C_4,
LOPT_NOISE_E_4,
LOPT_NOISE_D_4,
LOPT_NOISE_W_4,
LOPT_RIVER_4,
LOPT_OCEAN_256,
LOPT_NOOCEAN_1,
LOPT_HEIGHT_4,
LOPT_STRUCTS,
LOPT_MAX,
};
struct LayerOpt
{
int8_t mode;
int8_t disp[LOPT_MAX];
LayerOpt() { reset(); }
void reset()
{
mode = LOPT_BIOMES;
memset(disp, 0, sizeof(disp));
}
int activeDisp() const { return disp[mode]; };
bool activeDifference(const LayerOpt& l) const
{
return mode != l.mode || disp[l.mode] != l.disp[l.mode];
}
};
enum { STYLE_SYSTEM, STYLE_DARK };
struct Config
{
bool smoothMotion;
bool showBBoxes;
bool restoreSession;
bool checkForUpdates;
int autosaveCycle;
int uistyle;
int maxMatching;
int gridSpacing;
int gridMultiplier;
int mapCacheSize;
int mapThreads;
QString biomeColorPath;
QString separator;
QString quote;
Config() { reset(); }
void reset()
{
smoothMotion = true;
showBBoxes = true;
restoreSession = true;
checkForUpdates = false;
autosaveCycle = 10;
uistyle = STYLE_SYSTEM;
maxMatching = 65536;
gridSpacing = 0;
gridMultiplier = 0;
mapCacheSize = 256;
mapThreads = 0;
biomeColorPath = "";
separator = ";";
quote = "";
}
};
enum { GEN48_AUTO, GEN48_QH, GEN48_QM, GEN48_LIST, GEN48_NONE };
enum { IDEAL, CLASSIC, NORMAL, BARELY, IDEAL_SALTED };
struct Gen48Settings
{
int mode;
QString slist48path;
uint64_t salt;
uint64_t listsalt;
int qual;
int qmarea;
bool manualarea;
int x1, z1, x2, z2;
Gen48Settings() { reset(); }
void reset()
{
mode = GEN48_AUTO;
slist48path = "";
salt = 0;
listsalt = 0;
qual = IDEAL;
qmarea = 13028;
manualarea = false;
x1 = z1 = x2 = z2 = 0;
}
};
// search type options from combobox
enum { SEARCH_INC = 0, SEARCH_BLOCKS = 1, SEARCH_LIST = 2 };
struct SearchConfig
{
int searchtype;
QString slist64path;
int threads;
uint64_t startseed;
bool stoponres;
uint64_t smin;
uint64_t smax;
SearchConfig() { reset(); }
void reset()
{
searchtype = SEARCH_INC;
slist64path = "";
threads = QThread::idealThreadCount();
startseed = 0;
stoponres = true;
smin = 0;
smax = ~(uint64_t)0;
}
};
Q_DECLARE_METATYPE(int64_t)
Q_DECLARE_METATYPE(uint64_t)
Q_DECLARE_METATYPE(Pos)
Q_DECLARE_METATYPE(Config)
#endif // SETTINGS_H

View File

@ -2,32 +2,37 @@
#include "ui_structuredialog.h"
#include <QLabel>
#include <QCheckBox>
#include <QLineEdit>
#include <QDoubleValidator>
#include <QPushButton>
#include "world.h"
#include "cutil.h"
#include "world.h"
StructureDialog::StructureDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::StructureDialog)
, mconfig()
, modified()
{
ui->setupUi(this);
QGridLayout *grid = new QGridLayout(ui->groupVis);
loadStructVis(structvis);
grid->addWidget(new QLabel(tr("blocks per pixel")), 0, 2);
grid->addWidget(new QLabel(tr("enabled")), 0, 0, 1, 3);
grid->addWidget(new QLabel(tr("blocks per pixel")), 0, 3);
int i = 1;
for (auto it : structvis)
for (int opt = D_DESERT; opt < D_SPAWN; opt++)
{
int opt = it.first;
double scale = it.second;
if (!mconfig.valid(opt))
continue;
int j = 0;
QCheckBox *check = new QCheckBox();
vui[opt].check = check;
grid->addWidget(check, i, j++);
QLabel *icon = new QLabel();
icon->setPixmap(getMapIcon(opt));
grid->addWidget(icon, i, j++);
@ -38,15 +43,13 @@ StructureDialog::StructureDialog(QWidget *parent)
QLineEdit *line = new QLineEdit();
line->setValidator(new QDoubleValidator(0.125, 256.0, 3, grid));
line->setText(QString::number(scale));
entries[it.first] = line;
vui[opt].line = line;
grid->addWidget(line, i, j++);
i++;
}
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &StructureDialog::onAccept);
QPushButton *reset = ui->buttonBox->button(QDialogButtonBox::RestoreDefaults);
connect(reset, &QPushButton::clicked, this, &StructureDialog::onReset);
mconfig.load();
refresh();
}
StructureDialog::~StructureDialog()
@ -54,23 +57,49 @@ StructureDialog::~StructureDialog()
delete ui;
}
void StructureDialog::onAccept()
void StructureDialog::refresh()
{
for (auto it : entries)
for (int opt = D_DESERT; opt < D_SPAWN; opt++)
{
QLineEdit *line = it.second;
modified |= line->isModified();
bool ok;
double scale = line->text().toDouble(&ok);
if (ok)
structvis[it.first] = scale;
if (vui[opt].check)
vui[opt].check->setChecked(mconfig.enabled(opt));
if (vui[opt].line)
vui[opt].line->setText(QString::number(mconfig.scale(opt)));
}
}
void StructureDialog::onReset()
void StructureDialog::on_buttonBox_clicked(QAbstractButton *button)
{
QString scalestr = "32";
for (auto it : entries)
it.second->setText(scalestr);
modified = true;
int role = ui->buttonBox->buttonRole(button);
if (role == QDialogButtonBox::ResetRole)
{
mconfig.reset();
refresh();
}
else if (role == QDialogButtonBox::AcceptRole || role == QDialogButtonBox::ApplyRole)
{
for (int opt = D_DESERT; opt < D_SPAWN; opt++)
{
MapConfig::Opt *p_opt = &mconfig.opts[opt];
if (vui[opt].check)
{
double enabled = vui[opt].check->isChecked();
modified |= p_opt->enabled != enabled;
p_opt->enabled = enabled;
}
if (vui[opt].line)
{
bool ok;
double scale = vui[opt].line->text().toDouble(&ok);
if (ok)
{
modified |= p_opt->scale != scale;
p_opt->scale = scale;
}
}
}
mconfig.save();
emit updateMapConfig();
}
}

View File

@ -2,13 +2,15 @@
#define STRUCTUREDIALOG_H
#include <QDialog>
#include <QAbstractButton>
#include <map>
#include "config.h"
namespace Ui {
class StructureDialog;
}
class QCheckBox;
class QLineEdit;
class StructureDialog : public QDialog
@ -19,16 +21,25 @@ public:
explicit StructureDialog(QWidget *parent = nullptr);
~StructureDialog();
public slots:
void onAccept();
void onReset();
void refresh();
private slots:
void on_buttonBox_clicked(QAbstractButton *button);
signals:
void updateMapConfig();
private:
Ui::StructureDialog *ui;
std::map<int, QLineEdit*> entries;
struct VisUi
{
QCheckBox *check;
QLineEdit *line;
};
std::map<int, VisUi> vui;
public:
std::map<int, double> structvis;
MapConfig mconfig;
bool modified;
};

View File

@ -3,7 +3,7 @@
<class>StructureDialog</class>
<widget class="QDialog" name="StructureDialog">
<property name="windowTitle">
<string>Structure Zoom Limits</string>
<string>Structure Visibility</string>
</property>
<property name="windowIcon">
<iconset resource="../rc/icons.qrc">
@ -16,7 +16,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>

View File

@ -117,7 +117,7 @@ void AnalysisBiomes::runLocate(Generator *g)
enum { MAX_LOCATE = 4096 };
Pos pos[MAX_LOCATE];
int siz[MAX_LOCATE];
Range r = {4, dat.x1, dat.z1, dat.x2-dat.x1+1, dat.z2-dat.z1+1, wi.y, 1};
Range r = {4, dat.x1, dat.z1, dat.x2-dat.x1+1, dat.z2-dat.z1+1, wi.y>>2, 1};
int n = getBiomeCenters(
pos, siz, MAX_LOCATE, g, r, dat.locate, minsize, tolerance,
(volatile char*)&stop

View File

@ -425,7 +425,7 @@ void TabStructures::on_pushStart_clicked()
thread.collect = ui->checkCollect->isChecked();
for (int sopt = 0; sopt < STRUCT_NUM; sopt++)
for (int sopt = 0; sopt < D_STRUCT_NUM; sopt++)
thread.mapshow[sopt] = ui->radioAll->isChecked() || parent->getMapView()->getShow(sopt);
if (ui->tabWidget->currentWidget() == ui->tabStructures)

View File

@ -29,7 +29,7 @@ public:
std::atomic_bool stop;
std::atomic_int idx;
struct Dat { int x1, z1, x2, z2; } area;
bool mapshow[STRUCT_NUM];
bool mapshow[D_STRUCT_NUM];
bool collect;
bool quad;
};

View File

@ -2,7 +2,7 @@
#include "ui_tabtriggers.h"
#include "cutil.h"
#include "settings.h"
#include "config.h"
#include <QElapsedTimer>
#include <QFileDialog>

View File

@ -11,36 +11,13 @@
#include <algorithm>
void loadStructVis(std::map<int, double>& structvis)
{
QSettings settings("cubiomes-viewer", "cubiomes-viewer");
for (int opt = D_DESERT; opt < D_SPAWN; opt++)
{
double defval = 32;
const char *name = mapopt2str(opt);
double scale = settings.value(QString("structscale/") + name, defval).toDouble();
structvis[opt] = scale;
}
}
void saveStructVis(std::map<int, double>& structvis)
{
QSettings settings("cubiomes-viewer", "cubiomes-viewer");
for (auto it : structvis)
{
const char *name = mapopt2str(it.first);
settings.setValue(QString("structscale/") + name, it.second);
}
}
const QPixmap& getMapIcon(int opt, VarPos *vp)
{
static QPixmap icons[STRUCT_NUM];
static QPixmap icons[D_STRUCT_NUM];
static QPixmap iconzvil;
static QPixmap icongiant;
static QPixmap iconship;
static QPixmap iconbasement;
static bool init = false;
if (!init)
@ -57,8 +34,11 @@ const QPixmap& getMapIcon(int opt, VarPos *vp)
icons[D_SHIPWRECK] = QPixmap(":/icons/shipwreck.png");
icons[D_TREASURE] = QPixmap(":/icons/treasure.png");
icons[D_MINESHAFT] = QPixmap(":/icons/mineshaft.png");
icons[D_WELL] = QPixmap(":/icons/well.png");
icons[D_GEODE] = QPixmap(":/icons/geode.png");
icons[D_OUTPOST] = QPixmap(":/icons/outpost.png");
icons[D_ANCIENTCITY]= QPixmap(":/icons/ancient_city.png");
icons[D_TRAIL] = QPixmap(":/icons/trail.png");
icons[D_PORTAL] = QPixmap(":/icons/portal.png");
icons[D_PORTALN] = QPixmap(":/icons/portal.png");
icons[D_SPAWN] = QPixmap(":/icons/spawn.png");
@ -70,11 +50,14 @@ const QPixmap& getMapIcon(int opt, VarPos *vp)
iconzvil = QPixmap(":/icons/zombie.png");
icongiant = QPixmap(":/icons/portal_giant.png");
iconship = QPixmap(":/icons/end_ship.png");
iconbasement = QPixmap(":/icons/igloo_basement.png");
}
if (!vp)
return icons[opt];
if (opt == D_VILLAGE && vp->v.abandoned)
return iconzvil;
if (opt == D_IGLOO && vp->v.basement)
return iconbasement;
if ((opt == D_PORTAL || opt == D_PORTALN) && vp->v.giant)
return icongiant;
if (opt == D_ENDCITY)
@ -166,6 +149,23 @@ QStringList VarPos::detail() const
if (wart)
sinfo.append(QString::asprintf("nether_wart=%d", wart));
}
else if (type == Igloo)
{
if (v.basement)
{
sinfo.append("with_basement");
sinfo.append(QString::asprintf("ladders=%d", 4+v.size*3));
}
}
else if (type == Geode)
{
sinfo.append(QString::asprintf("x=%d", p.x+v.x));
sinfo.append(QString::asprintf("y=%d", v.y));
sinfo.append(QString::asprintf("z=%d", p.z+v.z));
sinfo.append(QString::asprintf("radius=%d", v.size));
if (v.cracked)
sinfo.append("cracked");
}
return sinfo;
}
@ -413,9 +413,8 @@ void Quad::run()
return;
}
int seam_buf = 0; //pixs / 128;
int y = (scale > 1) ? wi.y >> 2 : wi.y;
int x = ti*pixs, z = tj*pixs, w = pixs+seam_buf, h = pixs+seam_buf;
int x = ti*pixs, z = tj*pixs, w = pixs, h = pixs;
Range r = {scale, x, z, w, h, y, 1};
biomes = allocCache(g, r);
if (!biomes) return;
@ -434,7 +433,22 @@ void Quad::run()
}
rgb = new uchar[w*h * 3];
if (g->mc < MC_1_18 || dim != 0 || g->bn.nptype < 0)
int nptype = -1;
if (g->mc >= MC_1_18) nptype = g->bn.nptype;
if (g->mc <= MC_B1_7) nptype = g->bnb.nptype;
if (dim == 0 && nptype >= 0)
{ // climate parameter
const int *extremes = getBiomeParaExtremes(g->mc);
int cmin = extremes[nptype*2 + 0];
int cmax = extremes[nptype*2 + 1];
for (int i = 0; i < w*h; i++)
{
double p = (biomes[i] - cmin) / (double) (cmax - cmin);
uchar col = (p <= 0) ? 0 : (p >= 1.0) ? 0xff : (uchar)(0xff * p);
rgb[3*i+0] = rgb[3*i+1] = rgb[3*i+2] = col;
}
}
else
{
// sync biomeColors
g_mutex.lock();
@ -447,18 +461,6 @@ void Quad::run()
applyHeightShading(rgb, r, g, sn, stepbits, lopt.disp[lopt.mode], false, isdel);
}
}
else // climate parameter
{
const int *extremes = getBiomeParaExtremes(g->mc);
int cmin = extremes[g->bn.nptype*2 + 0];
int cmax = extremes[g->bn.nptype*2 + 1];
for (int i = 0; i < w*h; i++)
{
double p = (biomes[i] - cmin) / (double) (cmax - cmin);
uchar col = (p <= 0) ? 0 : (p >= 1.0) ? 0xff : (uchar)(0xff * p);
rgb[3*i+0] = rgb[3*i+1] = rgb[3*i+2] = col;
}
}
img = new QImage(rgb, w, h, 3*w, QImage::Format_RGB888);
}
else if (pixs < 0)
@ -568,7 +570,7 @@ void Level::init4map(QWorld *w, int pix, int layerscale)
initSurfaceNoise(&sn, dim, wi.seed);
this->isdel = &w->isdel;
sopt = D_NONE;
if (dim == DIM_OVERWORLD && wi.mc >= MC_1_18)
if (dim == DIM_OVERWORLD && lopt.isClimate(wi.mc))
{
switch (lopt.mode)
{
@ -578,12 +580,18 @@ void Level::init4map(QWorld *w, int pix, int layerscale)
case LOPT_NOISE_E_4: g.bn.nptype = NP_EROSION; break;
case LOPT_NOISE_D_4: g.bn.nptype = NP_DEPTH; break;
case LOPT_NOISE_W_4: g.bn.nptype = NP_WEIRDNESS; break;
case LOPT_BETA_T_1: g.bnb.nptype = NP_TEMPERATURE; break;
case LOPT_BETA_H_1: g.bnb.nptype = NP_HUMIDITY; break;
}
if (g.bn.nptype >= 0)
if (wi.mc >= MC_1_18)
{
int nmax = lopt.activeDisp();
setClimateParaSeed(&g.bn, wi.seed, wi.large, g.bn.nptype, nmax);
}
else if (wi.mc <= MC_B1_7)
{
g.flags |= NO_BETA_OCEAN;
}
}
}
@ -775,12 +783,15 @@ QWorld::QWorld(WorldInfo wi, int dim, LayerOpt lopt)
setDim(dim, lopt);
std::map<int, double> svis;
loadStructVis(svis);
QSettings settings(APP_STRING, APP_STRING);
MapConfig mconfig;
mconfig.load(settings);
lvs.resize(D_SPAWN);
for (int opt = D_DESERT; opt < D_SPAWN; opt++)
{
if (!mconfig.enabled(opt))
continue;
int sdim = 0, qsiz = 512*16;
switch (opt) {
case D_PORTALN: sdim = -1; break;
@ -790,8 +801,8 @@ QWorld::QWorld(WorldInfo wi, int dim, LayerOpt lopt)
case D_GATEWAY: sdim = +1; break;
case D_MANSION: qsiz = 1280*16; break;
}
double vis = 1.0 / svis[opt];
lvs[opt].init4struct(this, sdim, qsiz, vis, opt);
double v = 1.0 / mconfig.scale(opt);
lvs[opt].init4struct(this, sdim, qsiz, v, opt);
}
memset(sshow, 0, sizeof(sshow));
}
@ -843,6 +854,13 @@ void QWorld::setDim(int dim, LayerOpt lopt)
lvb[i].init4map(this, pixs, scale);
}
void QWorld::setSelectPos(QPoint pos)
{
selx = pos.x();
selz = pos.y();
seldo = true;
selopt = D_NONE;
}
int QWorld::getBiome(Pos p)
{
@ -867,7 +885,7 @@ int QWorld::getBiome(Pos p)
QString QWorld::getBiomeName(Pos p)
{
int id = getBiome(p);
if (wi.mc >= MC_1_18 && dim == 0 && lopt.mode >= LOPT_NOISE_T_4 && lopt.mode <= LOPT_NOISE_W_4)
if (dim == 0 && lopt.isClimate(wi.mc))
{
QString c;
switch (lopt.mode)
@ -878,6 +896,8 @@ QString QWorld::getBiomeName(Pos p)
case LOPT_NOISE_E_4: c = "E"; break;
case LOPT_NOISE_D_4: c = "D"; break;
case LOPT_NOISE_W_4: c = "W"; break;
case LOPT_BETA_T_1: c = "T"; break;
case LOPT_BETA_H_1: c = "H"; break;
}
if (lopt.activeDisp())
c += "." + QString::number(lopt.activeDisp());
@ -885,16 +905,20 @@ QString QWorld::getBiomeName(Pos p)
}
const char *s = biome2str(wi.mc, id);
QString ret = s ? s : "";
if (lopt.mode == LOPT_HEIGHT_4 && dim == 0)
{
float y;
int id;
mapApproxHeight(&y, &id, &g, &sn, p.x>>2, p.z>>2, 1, 1);
ret = QString::asprintf("Y~%d ", (int) floor(y)) + ret;
}
if (lopt.mode == LOPT_HEIGHT_4 && dim == DIM_OVERWORLD)
ret = QString::asprintf("Y~%d ", estimateSurface(p)) + ret;
return ret;
}
int QWorld::estimateSurface(Pos p)
{
if (dim != DIM_OVERWORLD)
return 64;
float y = 0;
mapApproxHeight(&y, 0, &g, &sn, p.x>>2, p.z>>2, 1, 1);
return (int) floor(y);
}
static void refreshQuadColor(Quad *q)
{
QImage *img = q->img;
@ -1166,8 +1190,6 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
qreal ps = q->blocks * blocks2pix;
qreal px = vw/2.0 + (q->ti) * ps - focusx * blocks2pix;
qreal pz = vh/2.0 + (q->tj) * ps - focusz * blocks2pix;
// account for the seam buffer pixels
//ps += ((q->pixs / 128) * q->blocks / (qreal)q->pixs) * blocks2pix;
QRect rec(floor(px),floor(pz), ceil(ps),ceil(ps));
//QImage img = (*q->img).scaledToWidth(rec.width(), Qt::SmoothTransformation);
painter.drawImage(rec, *q->img);
@ -1277,6 +1299,11 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
continue;
std::map<const QPixmap*, std::vector<QPainter::PixmapFragment>> frags;
QImage bufimg = QImage(vw, vh, QImage::Format_Indexed8);
bufimg.setColor(0, qRgba(0, 0, 0, 0));
bufimg.setColor(1, qRgba(255, 255, 255, 255));
bufimg.setColor(2, qRgba(180, 64, 192, 255));
bufimg.fill(0);
for (Quad *q : l.cells)
{
@ -1305,6 +1332,14 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
x += dx / 2;
y += dy / 2;
}
else if (vp.type == Geode)
{
qreal rad = vp.v.size * blocks2pix;
x += vp.v.x * blocks2pix;
y += vp.v.z * blocks2pix;
painter.setPen(QPen(QColor(192, 0, 0, 160), 1));
painter.drawEllipse(QPointF(x, y), rad, rad);
}
painter.setPen(QPen(QColor(192, 0, 0, 128), 0));
for (Piece& p : vp.pieces)
{
@ -1334,6 +1369,34 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
vp.p.z //+ (vp.v.z + vp.v.sz / 2)
};
if (sopt == D_GEODE)
{
int r = 2;
QRectF rec = QRectF(d.x()-r, d.y()-r, 2*r, 2*r);
if (seldo && rec.contains(selx, selz))
{
selopt = sopt;
selvp = vp;
}
if (selopt == sopt && selvp.p.x == spos.x && selvp.p.z == spos.z)
{ // don't draw selected structure
continue;
}
for (int i = -r; i <= r; i++)
{
for (int j = -r; j <= r; j++)
{
int q = i*i + j*j;
if (q > r*r) continue;
int x = floor(d.x() + i);
int z = floor(d.y() + j);
if (bufimg.rect().contains(x, z))
bufimg.setPixel(x, z, q >= 2 ? 1 : 2);
}
}
continue;
}
const QPixmap& icon = getMapIcon(sopt, &vp);
QRectF rec = icon.rect();
if (seldo)
@ -1355,6 +1418,7 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
}
}
painter.drawImage(QPoint(0, 0), bufimg);
for (auto& it : frags)
painter.drawPixmapFragments(it.second.data(), it.second.size(), *it.first);
}
@ -1448,8 +1512,8 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
qreal x = vw/2.0 + (selvp.p.x - focusx) * blocks2pix;
qreal y = vh/2.0 + (selvp.p.z - focusz) * blocks2pix;
QRect iconrec = icon.rect();
qreal w = iconrec.width() * 1.5;
qreal h = iconrec.height() * 1.5;
qreal w = iconrec.width() * 1.49;
qreal h = iconrec.height() * 1.49;
painter.drawPixmap(x-w/2, y-h/2, w, h, icon);
QFont f = QFont();

View File

@ -1,7 +1,7 @@
#ifndef WORLD_H
#define WORLD_H
#include "settings.h"
#include "config.h"
#include "search.h"
#include <QRunnable>
@ -10,131 +10,11 @@
#include <QAtomicPointer>
#include <QIcon>
#include <QMutex>
#include <QThread>
#include "cubiomes/quadbase.h"
enum {
D_NONE = -1,
// generics
D_GRID,
D_SLIME,
// structures
D_DESERT,
D_JUNGLE,
D_IGLOO,
D_HUT,
D_VILLAGE,
D_MANSION,
D_MONUMENT,
D_RUINS,
D_SHIPWRECK,
D_TREASURE,
D_MINESHAFT,
D_OUTPOST,
D_ANCIENTCITY,
D_PORTAL,
D_PORTALN,
D_FORTESS,
D_BASTION,
D_ENDCITY,
D_GATEWAY,
// non-recurring structures
D_SPAWN,
D_STRONGHOLD,
STRUCT_NUM
};
inline const char *mapopt2str(int opt)
{
switch (opt)
{
case D_GRID: return "grid";
case D_SLIME: return "slime";
case D_DESERT: return "desert";
case D_JUNGLE: return "jungle";
case D_IGLOO: return "igloo";
case D_HUT: return "hut";
case D_VILLAGE: return "village";
case D_MANSION: return "mansion";
case D_MONUMENT: return "monument";
case D_RUINS: return "ruins";
case D_SHIPWRECK: return "shipwreck";
case D_TREASURE: return "treasure";
case D_MINESHAFT: return "mineshaft";
case D_OUTPOST: return "outpost";
case D_ANCIENTCITY: return "ancient_city";
case D_PORTAL: return "portal";
case D_PORTALN: return "portaln";
case D_SPAWN: return "spawn";
case D_STRONGHOLD: return "stronghold";
case D_FORTESS: return "fortress";
case D_BASTION: return "bastion";
case D_ENDCITY: return "endcity";
case D_GATEWAY: return "gateway";
default: return "";
}
}
inline int str2mapopt(const char *s)
{
if (!strcmp(s, "grid")) return D_GRID;
if (!strcmp(s, "slime")) return D_SLIME;
if (!strcmp(s, "desert")) return D_DESERT;
if (!strcmp(s, "jungle")) return D_JUNGLE;
if (!strcmp(s, "igloo")) return D_IGLOO;
if (!strcmp(s, "hut")) return D_HUT;
if (!strcmp(s, "village")) return D_VILLAGE;
if (!strcmp(s, "mansion")) return D_MANSION;
if (!strcmp(s, "monument")) return D_MONUMENT;
if (!strcmp(s, "ruins")) return D_RUINS;
if (!strcmp(s, "shipwreck")) return D_SHIPWRECK;
if (!strcmp(s, "treasure")) return D_TREASURE;
if (!strcmp(s, "mineshaft")) return D_MINESHAFT;
if (!strcmp(s, "outpost")) return D_OUTPOST;
if (!strcmp(s, "ancient_city")) return D_ANCIENTCITY;
if (!strcmp(s, "portal")) return D_PORTAL;
if (!strcmp(s, "portaln")) return D_PORTALN;
if (!strcmp(s, "spawn")) return D_SPAWN;
if (!strcmp(s, "stronghold")) return D_STRONGHOLD;
if (!strcmp(s, "fortress")) return D_FORTESS;
if (!strcmp(s, "bastion")) return D_BASTION;
if (!strcmp(s, "endcity")) return D_ENDCITY;
if (!strcmp(s, "gateway")) return D_GATEWAY;
return D_NONE;
}
inline int mapopt2stype(int opt)
{
switch (opt)
{
case D_DESERT: return Desert_Pyramid;
case D_JUNGLE: return Jungle_Pyramid;
case D_IGLOO: return Igloo;
case D_HUT: return Swamp_Hut;
case D_VILLAGE: return Village;
case D_MANSION: return Mansion;
case D_MONUMENT: return Monument;
case D_RUINS: return Ocean_Ruin;
case D_SHIPWRECK: return Shipwreck;
case D_TREASURE: return Treasure;
case D_MINESHAFT: return Mineshaft;
case D_OUTPOST: return Outpost;
case D_ANCIENTCITY: return Ancient_City;
case D_PORTAL: return Ruined_Portal;
case D_PORTALN: return Ruined_Portal_N;
case D_FORTESS: return Fortress;
case D_BASTION: return Bastion;
case D_ENDCITY: return End_City;
case D_GATEWAY: return End_Gateway;
default:
return -1;
}
}
void loadStructVis(std::map<int, double>& structvis);
void saveStructVis(std::map<int, double>& structvis);
struct Level;
struct VarPos
@ -267,8 +147,11 @@ public:
void draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz, qreal blocks2pix);
void setSelectPos(QPoint pos);
int getBiome(Pos p);
QString getBiomeName(Pos p);
int estimateSurface(Pos p);
void refreshBiomeColors();
@ -305,7 +188,7 @@ public:
std::vector<MapWorker> workers;
int threadlimit;
bool sshow[STRUCT_NUM];
bool sshow[D_STRUCT_NUM];
bool showBB;
int gridspacing;
int gridmultiplier;