mirror of
https://github.com/Cubitect/cubiomes-viewer.git
synced 2025-01-08 11:57:50 +08:00
Changes for MC 1.21
* added 1.21.2 to versions, as well as an experimental 1.21.3 for the pale_garden biome * added trial chamber finder * added inner linked gateways * fixed inaccurate End generation at large distances from 0,0 * fixed copying seeds from matching seed list (#302) * fixed non-persistent search progress and results list in headless mode (#310)
This commit is contained in:
parent
abcbfbd0bf
commit
a5376bfd72
2
cubiomes
2
cubiomes
@ -1 +1 @@
|
||||
Subproject commit 0af31b4e7eeb14a58c2bd9a4c4c68b97b4a7d6e8
|
||||
Subproject commit e49c8c561bcd238b376b7817182695ea2f993061
|
@ -141,6 +141,7 @@ HEADERS += \
|
||||
$$CUPATH/finders.h \
|
||||
$$CUPATH/generator.h \
|
||||
$$CUPATH/layers.h \
|
||||
$$CUPATH/biomes.h \
|
||||
$$CUPATH/quadbase.h \
|
||||
$$CUPATH/util.h \
|
||||
$$LUAPATH/lapi.h \
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 135 B After Width: | Height: | Size: 387 B |
Binary file not shown.
Before Width: | Height: | Size: 135 B After Width: | Height: | Size: 350 B |
@ -60,7 +60,7 @@ bool WorldInfo::equals(const WorldInfo& wi) const
|
||||
|
||||
void WorldInfo::reset()
|
||||
{
|
||||
mc = MC_NEWEST;
|
||||
mc = MC_DEFAULT;
|
||||
large = false;
|
||||
seed = 0;
|
||||
y = 255;
|
||||
@ -92,7 +92,7 @@ bool WorldInfo::read(const QString& line)
|
||||
{
|
||||
mc = str2mc(buf);
|
||||
if (mc < 0)
|
||||
mc = MC_NEWEST;
|
||||
mc = MC_DEFAULT;
|
||||
return true;
|
||||
}
|
||||
if (sscanf(p, "#Large: %d", &tmp) == 1)
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#define PRECOMPUTE48_BUFSIZ ((int64_t)1 << 30)
|
||||
|
||||
enum { MC_DEFAULT = MC_1_21_2 };
|
||||
|
||||
struct ExtGenConfig
|
||||
{
|
||||
@ -77,7 +78,7 @@ enum {
|
||||
LOPT_NOOCEAN_1,
|
||||
LOPT_BETA_T_1,
|
||||
LOPT_BETA_H_1,
|
||||
LOPT_HEIGHT_4,
|
||||
LOPT_HEIGHT,
|
||||
LOPT_STRUCTS,
|
||||
LOPT_MAX,
|
||||
};
|
||||
|
@ -336,6 +336,17 @@ void FormSearchControl::setSearchRange(uint64_t smin, uint64_t smax)
|
||||
searchProgressReset();
|
||||
}
|
||||
|
||||
bool FormSearchControl::getSeed(int row, uint64_t *seed)
|
||||
{
|
||||
QAbstractItemModel *model = ui->results->model();
|
||||
if (row < 0 || row >= model->rowCount())
|
||||
return false;
|
||||
QModelIndex idx = model->index(row, SeedTableModel::COL_SEED);
|
||||
*seed = model->data(idx, Qt::UserRole).toULongLong();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void FormSearchControl::on_buttonClear_clicked()
|
||||
{
|
||||
model->reset();
|
||||
@ -444,13 +455,9 @@ void FormSearchControl::on_buttonMore_clicked()
|
||||
|
||||
void FormSearchControl::onSeedSelectionChanged()
|
||||
{
|
||||
int row = ui->results->currentIndex().row();
|
||||
if (row >= 0 && row < ui->results->model()->rowCount())
|
||||
{
|
||||
QModelIndex idx = ui->results->model()->index(row, SeedTableModel::COL_SEED);
|
||||
uint64_t s = ui->results->model()->data(idx, Qt::UserRole).toULongLong();
|
||||
uint64_t s;
|
||||
if (getSeed(ui->results->currentIndex().row(), &s))
|
||||
emit selectedSeedChanged(s);
|
||||
}
|
||||
}
|
||||
|
||||
void FormSearchControl::on_results_clicked(const QModelIndex &)
|
||||
@ -809,10 +816,9 @@ void FormSearchControl::removeCurrent()
|
||||
|
||||
void FormSearchControl::copySeed()
|
||||
{
|
||||
QModelIndex index = ui->results->currentIndex();
|
||||
if (index.isValid())
|
||||
uint64_t seed;
|
||||
if (getSeed(ui->results->currentIndex().row(), &seed))
|
||||
{
|
||||
uint64_t seed = ui->results->model()->data(index, Qt::UserRole).toULongLong();
|
||||
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setText(QString::asprintf("%" PRId64, seed));
|
||||
}
|
||||
@ -824,11 +830,10 @@ void FormSearchControl::copyResults()
|
||||
int n = ui->results->model()->rowCount();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
QModelIndex idx = ui->results->model()->index(i, SeedTableModel::COL_SEED);
|
||||
uint64_t seed = ui->results->model()->data(idx, Qt::UserRole).toULongLong();
|
||||
text += QString::asprintf("%" PRId64 "\n", seed);
|
||||
uint64_t seed;
|
||||
if (getSeed(i, &seed))
|
||||
text += QString::asprintf("%" PRId64 "\n", seed);
|
||||
}
|
||||
|
||||
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setText(text);
|
||||
}
|
||||
|
@ -114,6 +114,8 @@ public:
|
||||
|
||||
void setSearchMode(int mode);
|
||||
|
||||
bool getSeed(int row, uint64_t *seed);
|
||||
|
||||
signals:
|
||||
void selectedSeedChanged(uint64_t seed);
|
||||
void searchStatusChanged(bool running);
|
||||
|
@ -5,8 +5,11 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QFileInfo>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
short get_term_width()
|
||||
@ -34,19 +37,20 @@ static QTextStream& qOut()
|
||||
return out;
|
||||
}
|
||||
|
||||
Headless::Headless(QString sessionpath, QString resultspath, QObject *parent)
|
||||
Headless::Headless(QString sessionpath, QString resultspath, bool reset, QObject *parent)
|
||||
: QThread(parent)
|
||||
, sthread(nullptr)
|
||||
, sessionpath(sessionpath)
|
||||
, resultfile(resultspath)
|
||||
, resultstream(stdout)
|
||||
, progressfp()
|
||||
{
|
||||
sthread.isdone = true;
|
||||
|
||||
QSettings settings(APP_STRING, APP_STRING);
|
||||
g_extgen.load(settings);
|
||||
|
||||
if (!loadSession(sessionpath))
|
||||
if (!loadSession(sessionpath, reset))
|
||||
return;
|
||||
|
||||
if (!sthread.set(nullptr, session))
|
||||
@ -82,7 +86,7 @@ static bool load_seeds(std::vector<uint64_t>& seeds, QString path)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Headless::loadSession(QString sessionpath)
|
||||
bool Headless::loadSession(QString sessionpath, bool reset)
|
||||
{
|
||||
qOut() << "Loading session: \"" << sessionpath << "\"\n";
|
||||
qOut().flush();
|
||||
@ -100,6 +104,11 @@ bool Headless::loadSession(QString sessionpath)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reset)
|
||||
session.sc.startseed = 0;
|
||||
else
|
||||
results = session.slist;
|
||||
|
||||
if (session.cv.empty())
|
||||
{
|
||||
warn(nullptr, "Session defines no search constraints.");
|
||||
@ -149,15 +158,32 @@ void Headless::run()
|
||||
session.writeHeader(resultstream);
|
||||
resultstream.flush();
|
||||
|
||||
sthread.startSearch();
|
||||
elapsed.start();
|
||||
|
||||
if (resultfile.isOpen())
|
||||
{
|
||||
// open a separate write channel to the same result file and
|
||||
// reserve space for a progress field after the header
|
||||
QByteArray path = QFileInfo(resultfile).absoluteFilePath().toLocal8Bit();
|
||||
progressfp = fopen(path.data(), "rb+");
|
||||
if (progressfp)
|
||||
{
|
||||
fseek(progressfp, resultfile.size(), SEEK_SET);
|
||||
resultstream << QString::asprintf("#Progress: %20" PRId64 "\n", session.sc.startseed);
|
||||
resultstream.flush();
|
||||
}
|
||||
|
||||
for (uint64_t s : results)
|
||||
{
|
||||
resultstream << (int64_t) s << "\n";
|
||||
resultstream.flush();
|
||||
}
|
||||
|
||||
qOut() << "\n\n\n\n\n\n\n";
|
||||
qOut().flush();
|
||||
timer.start(250);
|
||||
}
|
||||
|
||||
sthread.startSearch();
|
||||
elapsed.start();
|
||||
}
|
||||
|
||||
void Headless::searchResult(uint64_t seed)
|
||||
@ -174,6 +200,11 @@ void Headless::searchFinish(bool done)
|
||||
timer.stop();
|
||||
progressTimeout();
|
||||
}
|
||||
if (progressfp)
|
||||
{
|
||||
fclose(progressfp);
|
||||
progressfp = NULL;
|
||||
}
|
||||
if (done)
|
||||
qOut() << "Search done!\n";
|
||||
qOut() << "Stopping event loop.\n";
|
||||
@ -188,6 +219,13 @@ void Headless::progressTimeout()
|
||||
qreal min, avg, max;
|
||||
sthread.getProgress(&status, &prog, &end, &seed, &min, &avg, &max);
|
||||
|
||||
if (progressfp)
|
||||
{
|
||||
long pos = ftell(progressfp);
|
||||
fprintf(progressfp, "#Progress: %20" PRId64 "\n", seed);
|
||||
fseek(progressfp, pos, SEEK_SET);
|
||||
}
|
||||
|
||||
short width = get_term_width();
|
||||
if (width <= 24)
|
||||
return;
|
||||
|
@ -12,10 +12,10 @@ class Headless : public QThread
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Headless(QString sessionpath, QString resultspath, QObject *parent = 0);
|
||||
Headless(QString sessionpath, QString resultspath, bool reset, QObject *parent = 0);
|
||||
virtual ~Headless();
|
||||
|
||||
bool loadSession(QString sessionpath);
|
||||
bool loadSession(QString sessionpath, bool reset);
|
||||
|
||||
public slots:
|
||||
void run();
|
||||
@ -33,6 +33,7 @@ public:
|
||||
std::vector<uint64_t> results;
|
||||
QFile resultfile;
|
||||
QTextStream resultstream;
|
||||
FILE *progressfp;
|
||||
QTimer timer;
|
||||
QElapsedTimer elapsed;
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ bool getLayerOptionInfo(LayerOptInfo *info, int mode, int disp, WorldInfo wi)
|
||||
if (disp == 3) txt = "1:64";
|
||||
if (disp == 4) txt = "1:256";
|
||||
break;
|
||||
case LOPT_HEIGHT_4:
|
||||
case LOPT_HEIGHT:
|
||||
if (disp == 0) txt = QApplication::translate("LayerDialog", "Grayscale");
|
||||
if (disp == 1) txt = QApplication::translate("LayerDialog", "Shaded biome map");
|
||||
if (disp == 2) txt = QApplication::translate("LayerDialog", "Contours on biomes");
|
||||
@ -113,7 +113,7 @@ LayerDialog::LayerDialog(QWidget *parent, WorldInfo wi)
|
||||
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_HEIGHT] = ui->radioHeight;
|
||||
radio[LOPT_STRUCTS] = ui->radioStruct;
|
||||
|
||||
combo[LOPT_BIOMES] = ui->comboBiomes;
|
||||
@ -122,7 +122,7 @@ LayerDialog::LayerDialog(QWidget *parent, WorldInfo wi)
|
||||
combo[LOPT_NOISE_C_4] = ui->comboNoiseC;
|
||||
combo[LOPT_NOISE_E_4] = ui->comboNoiseE;
|
||||
combo[LOPT_NOISE_W_4] = ui->comboNoiseW;
|
||||
combo[LOPT_HEIGHT_4] = ui->comboHeight;
|
||||
combo[LOPT_HEIGHT] = ui->comboHeight;
|
||||
|
||||
for (int i = 0; i < LOPT_MAX; i++)
|
||||
{
|
||||
|
@ -34,6 +34,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
bool version = false;
|
||||
bool nogui = false;
|
||||
bool clear = false;
|
||||
bool reset = false;
|
||||
bool usage = false;
|
||||
QString sessionpath;
|
||||
@ -45,6 +46,8 @@ int main(int argc, char *argv[])
|
||||
version = true;
|
||||
else if (strcmp(argv[i], "--nogui") == 0)
|
||||
nogui = true;
|
||||
else if (strcmp(argv[i], "--reset") == 0)
|
||||
clear = true;
|
||||
else if (strcmp(argv[i], "--reset-all") == 0)
|
||||
reset = true;
|
||||
else if (strncmp(argv[i], "--session=", 10) == 0)
|
||||
@ -67,6 +70,7 @@ int main(int argc, char *argv[])
|
||||
" --help Display this help and exit.\n"
|
||||
" --version Output version information and exit.\n"
|
||||
" --nogui Run in headless search mode.\n"
|
||||
" --reset Discard results and reset starting seed.\n"
|
||||
" --reset-all Clear settings and remove all session data.\n"
|
||||
" --session=file Open this session file.\n"
|
||||
" --out=file Write matching seeds to this file while searching.\n"
|
||||
@ -105,7 +109,7 @@ int main(int argc, char *argv[])
|
||||
if (nogui)
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
Headless headless(sessionpath, resultspath, &app);
|
||||
Headless headless(sessionpath, resultspath, clear, &app);
|
||||
|
||||
QObject::connect(&headless, SIGNAL(finished()), &app, SLOT(quit()));
|
||||
QTimer::singleShot(0, &headless, SLOT(run()));
|
||||
|
@ -111,7 +111,7 @@ MainWindow::MainWindow(QString sessionpath, QString resultspath, QWidget *parent
|
||||
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_HEIGHT] = ui->actionHeight;
|
||||
laction[LOPT_STRUCTS] = ui->actionStructures;
|
||||
|
||||
QActionGroup *grp = new QActionGroup(this);
|
||||
@ -365,7 +365,7 @@ bool MainWindow::getSeed(WorldInfo *wi, bool applyrand)
|
||||
{
|
||||
if (applyrand)
|
||||
qDebug() << "Unknown MC version: " << mcs.c_str();
|
||||
wi->mc = MC_NEWEST;
|
||||
wi->mc = MC_DEFAULT;
|
||||
ok = false;
|
||||
}
|
||||
|
||||
@ -697,13 +697,13 @@ void MainWindow::setMCList(bool experimental)
|
||||
if (ui->comboBoxMC->count())
|
||||
getSeed(&wi, false);
|
||||
else
|
||||
wi.mc = MC_NEWEST;
|
||||
wi.mc = MC_DEFAULT;
|
||||
QStringList mclist;
|
||||
for (int mc = MC_NEWEST; mc > MC_UNDEF; mc--)
|
||||
{
|
||||
if (!experimental && mc != wi.mc)
|
||||
{
|
||||
if (mc <= MC_1_0 || mc == MC_1_16_1 || mc == MC_1_19_2)
|
||||
if (mc <= MC_1_0 || mc == MC_1_16_1 || mc == MC_1_19_2 || mc == MC_1_21_3)
|
||||
continue;
|
||||
}
|
||||
const char *mcs = mc2str(mc);
|
||||
|
@ -502,7 +502,7 @@ void MapView::paintEvent(QPaintEvent *)
|
||||
QPoint cur = mapFromGlobal(QCursor::pos());
|
||||
qreal bx = (cur.x() - width()/2.0) / blocks2pix + fx;
|
||||
qreal bz = (cur.y() - height()/2.0) / blocks2pix + fz;
|
||||
Pos p = {(int)clampimax(bx), (int)clampimax(bz)};
|
||||
Pos p = {(int)clampimax(floor(bx)), (int)clampimax(floor(bz))};
|
||||
overlay->pos = p;
|
||||
overlay->bname = world->getBiomeName(p);
|
||||
|
||||
|
@ -1275,6 +1275,7 @@ L_qm_any:
|
||||
case F_PORTALN:
|
||||
case F_ANCIENT_CITY:
|
||||
case F_TRAILS:
|
||||
case F_CHAMBERS:
|
||||
|
||||
case F_FORTRESS:
|
||||
case F_BASTION:
|
||||
|
@ -91,6 +91,7 @@ enum
|
||||
F_TRAILS,
|
||||
F_BIOME_SAMPLE,
|
||||
F_NOISE_SAMPLE,
|
||||
F_CHAMBERS,
|
||||
// new filters should be added here at the end to keep some downwards compatibility
|
||||
FILTER_MAX,
|
||||
};
|
||||
@ -504,6 +505,13 @@ static const struct FilterList : private FilterInfo
|
||||
""
|
||||
};
|
||||
|
||||
list[F_CHAMBERS] = FilterInfo{
|
||||
CAT_STRUCT, 1, LOC_RAD, Trial_Chambers, 1, BR_CLUST, MC_1_21, MC_NEWEST, 0, 0, disp++,
|
||||
"chambers",
|
||||
QT_TRANSLATE_NOOP("Filter", "Trial chambers"),
|
||||
""
|
||||
};
|
||||
|
||||
list[F_PORTAL] = FilterInfo{
|
||||
CAT_STRUCT, 0, LOC_RAD, Ruined_Portal, 1, BR_CLUST, MC_1_16_1, MC_NEWEST, 0, 0, disp++,
|
||||
"portal",
|
||||
|
@ -156,6 +156,8 @@ QString getBiomeDisplay(int mc, int id)
|
||||
case mangrove_swamp: return QApplication::translate("Biome", "Mangrove Swamp");
|
||||
// 1.20
|
||||
case cherry_grove: return QApplication::translate("Biome", "Cherry Grove");
|
||||
// 1.21.3 (Winter Drop Version TBA)
|
||||
case pale_garden: return QApplication::translate("Biome", "Pale Garden");
|
||||
}
|
||||
const char *name = biome2str(mc, id);
|
||||
return name ? name : "";
|
||||
|
@ -136,7 +136,7 @@ QStringList VarPos::detail() const
|
||||
|
||||
|
||||
Quad::Quad(const Level* l, int64_t i, int64_t j)
|
||||
: wi(l->wi),dim(l->dim),lopt(l->lopt),g(&l->g),sn(&l->sn),hd(l->hd),scale(l->scale)
|
||||
: wi(l->wi),dim(l->dim),lopt(l->lopt),g(&l->g),sn(&l->sn),highres(l->highres),scale(l->scale)
|
||||
, ti(i),tj(j),blocks(l->blocks),pixs(l->pixs),sopt(l->sopt)
|
||||
, biomes(),rgb(),img(),spos()
|
||||
{
|
||||
@ -267,7 +267,12 @@ void applyHeightShading(unsigned char *rgb, Range r,
|
||||
pw += 2*bd; ph += 2*bd;
|
||||
}
|
||||
std::vector<float> buf(pw * ph);
|
||||
if (ps == 0)
|
||||
if (ps == 0 && r.scale <= 8 && g->dim == DIM_END)
|
||||
{
|
||||
mapEndSurfaceHeight(&buf[0], &g->en, sn, px, pz, pw, ph, r.scale, 0);
|
||||
mapEndIslandHeight(&buf[0], &g->en, g->seed, px, pz, pw, ph, r.scale);
|
||||
}
|
||||
else if (ps == 0 && r.scale == 4)
|
||||
{
|
||||
mapApproxHeight(&buf[0], 0, g, sn, px, pz, pw, ph);
|
||||
}
|
||||
@ -286,6 +291,7 @@ void applyHeightShading(unsigned char *rgb, Range r,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// interpolate height
|
||||
std::vector<float> height((w+2) * (h+2));
|
||||
for (int j = 0; j < h+2; j++)
|
||||
@ -382,7 +388,8 @@ void Quad::run()
|
||||
|
||||
if (pixs > 0)
|
||||
{
|
||||
if (lopt.mode == LOPT_STRUCTS && dim == DIM_OVERWORLD)
|
||||
if ((lopt.mode == LOPT_STRUCTS && dim == DIM_OVERWORLD) ||
|
||||
(g->mc <= MC_1_17 && scale > 256 && dim == DIM_OVERWORLD))
|
||||
{
|
||||
img = new QImage();
|
||||
done = true;
|
||||
@ -431,9 +438,13 @@ void Quad::run()
|
||||
g_mutex.unlock();
|
||||
biomesToImage(rgb, g_biomeColors, biomes, w, h, 1, 1);
|
||||
|
||||
if (lopt.mode == LOPT_HEIGHT_4)
|
||||
if (lopt.mode == LOPT_HEIGHT)
|
||||
{
|
||||
int stepbits = (hd ? 0 : 2);
|
||||
int stepbits = 0; // interpolated_step = (1 << stepbits)
|
||||
if (scale > 16)
|
||||
{
|
||||
stepbits = 1;
|
||||
}
|
||||
applyHeightShading(rgb, r, g, sn, stepbits, lopt.disp[lopt.mode], false, isdel);
|
||||
}
|
||||
}
|
||||
@ -459,7 +470,7 @@ void Quad::run()
|
||||
Level::Level()
|
||||
: cells(),g(),sn(),entry(),lopt(),wi(),dim()
|
||||
, tx(),tz(),tw(),th()
|
||||
, hd(),scale(),blocks(),pixs()
|
||||
, highres(),scale(),blocks(),pixs()
|
||||
, sopt()
|
||||
{
|
||||
}
|
||||
@ -480,7 +491,7 @@ void Level::init4map(QWorld *w, int pix, int layerscale)
|
||||
|
||||
tx = tz = tw = th = 0;
|
||||
|
||||
hd = (layerscale == 1);
|
||||
highres = (layerscale == 1);
|
||||
scale = layerscale;
|
||||
pixs = pix;
|
||||
blocks = pix * layerscale;
|
||||
@ -504,7 +515,7 @@ void Level::init4map(QWorld *w, int pix, int layerscale)
|
||||
case LOPT_NOISE_E_4:
|
||||
case LOPT_NOISE_D_4:
|
||||
case LOPT_NOISE_W_4:
|
||||
case LOPT_HEIGHT_4:
|
||||
//case LOPT_HEIGHT_4:
|
||||
case LOPT_RIVER_4:
|
||||
case LOPT_STRUCTS:
|
||||
optlscale = 4;
|
||||
@ -796,7 +807,13 @@ void QWorld::setDim(int dim, LayerOpt lopt)
|
||||
initSurfaceNoise(&sn, dim, g.seed);
|
||||
|
||||
int pixs, lcnt;
|
||||
if (g.mc >= MC_1_18 || dim != DIM_OVERWORLD)
|
||||
if (lopt.mode == LOPT_HEIGHT)
|
||||
{
|
||||
pixs = 32;
|
||||
lcnt = 6;
|
||||
qual = 4.0;
|
||||
}
|
||||
else if (g.mc > MC_1_17 || dim != DIM_OVERWORLD)
|
||||
{
|
||||
pixs = 128;
|
||||
lcnt = 6;
|
||||
@ -873,7 +890,7 @@ QString QWorld::getBiomeName(Pos p)
|
||||
return c + "=" + QString::number(id);
|
||||
}
|
||||
QString ret = getBiomeDisplay(wi.mc, id);
|
||||
if (lopt.mode == LOPT_HEIGHT_4)
|
||||
if (lopt.mode == LOPT_HEIGHT)
|
||||
{
|
||||
int y = estimateSurface(p);
|
||||
if (y > 0)
|
||||
@ -885,7 +902,15 @@ QString QWorld::getBiomeName(Pos p)
|
||||
int QWorld::estimateSurface(Pos p)
|
||||
{
|
||||
float y = 0;
|
||||
mapApproxHeight(&y, 0, &g, &sn, p.x>>2, p.z>>2, 1, 1);
|
||||
if (g.dim == DIM_END)
|
||||
{ // use end surface generator for 1:1 scale
|
||||
mapEndSurfaceHeight(&y, &g.en, &sn, p.x, p.z, 1, 1, 1, 0);
|
||||
mapEndIslandHeight(&y, &g.en, g.seed, p.x, p.z, 1, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapApproxHeight(&y, 0, &g, &sn, p.x>>2, p.z>>2, 1, 1);
|
||||
}
|
||||
return (int) floor(y);
|
||||
}
|
||||
|
||||
@ -1094,9 +1119,9 @@ struct SpawnStronghold : public Scheduled
|
||||
}
|
||||
};
|
||||
|
||||
static bool draw_grid_rec(QPainter& painter, QRect &rec, qreal pix, int64_t x, int64_t z)
|
||||
static bool draw_grid_rec(QPainter& painter, QColor col, QRect &rec, qreal pix, int64_t x, int64_t z)
|
||||
{
|
||||
painter.setPen(QPen(QColor(0, 0, 0, 96), 1));
|
||||
painter.setPen(QPen(col, 1));
|
||||
painter.drawRect(rec);
|
||||
if (pix < 50)
|
||||
return false;
|
||||
@ -1142,6 +1167,7 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
|
||||
smallfont.setPointSize(oldfont.pointSize() - 2);
|
||||
painter.setFont(smallfont);
|
||||
|
||||
QColor gridcol = lopt.mode == LOPT_HEIGHT ? QColor(192, 0, 0, 96) : QColor(0, 0, 0, 96);
|
||||
int gridpix = 128;
|
||||
// 128px is approximately the size of:
|
||||
//gridpix = painter.fontMetrics().boundingRect("-30000000,-30000000").width();
|
||||
@ -1166,7 +1192,7 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
|
||||
|
||||
if (sshow[D_GRID] && !gridspacing)
|
||||
{
|
||||
draw_grid_rec(painter, rec, ps, q->ti*q->blocks, q->tj*q->blocks);
|
||||
draw_grid_rec(painter, gridcol, rec, ps, q->ti*q->blocks, q->tj*q->blocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1190,7 +1216,7 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
|
||||
qreal px = vw/2.0 + (x+i) * ps - focusx * blocks2pix;
|
||||
qreal pz = vh/2.0 + (z+j) * ps - focusz * blocks2pix;
|
||||
QRect rec(px, pz, ps, ps);
|
||||
draw_grid_rec(painter, rec, ps, (x+i)*gs, (z+j)*gs);
|
||||
draw_grid_rec(painter, gridcol, rec, ps, (x+i)*gs, (z+j)*gs);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1264,6 +1290,41 @@ void QWorld::draw(QPainter& painter, int vw, int vh, qreal focusx, qreal focusz,
|
||||
}
|
||||
}
|
||||
|
||||
if (showBB && sshow[D_GATEWAY] && dim == DIM_END && g.mc > MC_1_12)
|
||||
{
|
||||
if (endgates.empty())
|
||||
{
|
||||
endgates.resize(40);
|
||||
getFixedEndGateways(g.mc, g.seed, &endgates[0]);
|
||||
for (int i = 0; i < 20; i++)
|
||||
endgates[20 + i] = getLinkedGatewayPos(&g.en, &sn, g.seed, endgates[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
qreal xsrc = vw/2.0 + (0.5 + endgates[i].x - focusx) * blocks2pix;
|
||||
qreal ysrc = vh/2.0 + (0.5 + endgates[i].z - focusz) * blocks2pix;
|
||||
qreal xdst = vw/2.0 + (0.5 + endgates[i+20].x - focusx) * blocks2pix;
|
||||
qreal ydst = vh/2.0 + (0.5 + endgates[i+20].z - focusz) * blocks2pix;
|
||||
|
||||
QPen pen = painter.pen();
|
||||
painter.setPen(QPen(QColor(192, 0, 0, 160), i == 0 ? 1.5 : 0.5));
|
||||
painter.drawLine(QPointF(xsrc,ysrc), QPointF(xdst,ydst));
|
||||
painter.setPen(pen);
|
||||
|
||||
if (blocks2pix >= 1.0 && abs(xsrc) < vw && abs(ysrc) < vh)
|
||||
{
|
||||
QString s = QString::number(i+1);
|
||||
QRect rec = painter.fontMetrics().boundingRect(s);
|
||||
qreal dx = xsrc - xdst;
|
||||
qreal dy = ysrc - ydst;
|
||||
qreal df = rec.height() / sqrt(dx*dx + dy*dy);
|
||||
rec.moveCenter(QPoint(xsrc + dx * df, ysrc + dy * df));
|
||||
painter.drawText(rec, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Shape& s : shapes)
|
||||
{
|
||||
if (s.dim != DIM_UNDEF && s.dim != dim)
|
||||
|
@ -64,7 +64,7 @@ struct Quad : public Scheduled
|
||||
LayerOpt lopt;
|
||||
const Generator *g;
|
||||
const SurfaceNoise *sn;
|
||||
int hd;
|
||||
int highres;
|
||||
int scale;
|
||||
int ti, tj;
|
||||
int blocks;
|
||||
@ -101,7 +101,7 @@ struct Level
|
||||
WorldInfo wi;
|
||||
int dim;
|
||||
int tx, tz, tw, th;
|
||||
int hd;
|
||||
int highres;
|
||||
int scale;
|
||||
int blocks;
|
||||
int pixs;
|
||||
@ -204,6 +204,7 @@ public:
|
||||
QAtomicPointer<Pos> spawn;
|
||||
QAtomicPointer<PosElement> strongholds;
|
||||
QAtomicPointer<QVector<QuadInfo>> qsinfo;
|
||||
QVector<Pos> endgates;
|
||||
// isdel is a flag for the worker thread to stop
|
||||
std::atomic_bool isdel;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user