map wizard: add functionality to write blank ADTs

ui: add icon states to font engine
This commit is contained in:
Skarn
2020-11-02 00:08:38 +03:00
parent 8d8fc54895
commit 3c4e548c6a
10 changed files with 240 additions and 50 deletions

View File

@@ -22,11 +22,86 @@
#include <QPixmap>
#include <QImage>
MapChunk::MapChunk(MapTile *maintile, MPQFile *f, bool bigAlpha, tile_mode mode)
MapChunk::MapChunk(MapTile *maintile, MPQFile *f, bool bigAlpha, tile_mode mode, bool init_empty, int chunk_idx)
: _mode(mode)
, mt(maintile)
, use_big_alphamap(bigAlpha)
{
if (init_empty)
{
header.flags = 0;
px = header.ix = chunk_idx / 16;
py = header.iy = chunk_idx % 16;
header.zpos = ZEROPOINT - (maintile->zbase + py * CHUNKSIZE);
header.xpos = ZEROPOINT - (maintile->xbase + px * CHUNKSIZE);
header.ypos = 0.0f;
areaID = header.areaid = 0;
zbase = header.zpos;
xbase = header.xpos;
ybase = header.ypos;
texture_set = nullptr;
// Generate normals
for (int i = 0; i < mapbufsize; ++i)
{
mNormals[i] = {0.0f, 1.0f, 0.0f};
}
// Clear shadows
memset(_shadow_map, 0, 64 * 64);
// Do not write MCCV
hasMCCV = false;
holes = 0;
zbase = zbase*-1.0f + ZEROPOINT;
xbase = xbase*-1.0f + ZEROPOINT;
vmin.y = 0.0f;
vmin = math::vector_3d(9999999.0f, 9999999.0f, 9999999.0f);
vmax = math::vector_3d(-9999999.0f, -9999999.0f, -9999999.0f);
math::vector_3d *ttv = mVertices;
for (int j = 0; j < 17; ++j) {
for (int i = 0; i < ((j % 2) ? 8 : 9); ++i) {
float xpos, zpos;
xpos = i * UNITSIZE;
zpos = j * 0.5f * UNITSIZE;
if (j % 2) {
xpos += UNITSIZE*0.5f;
}
math::vector_3d v = math::vector_3d(xbase + xpos, ybase + 0.0f, zbase + zpos);
*ttv++ = v;
vmin.y = std::min(vmin.y, v.y);
vmax.y = std::max(vmax.y, v.y);
}
}
vmin.x = xbase;
vmin.z = zbase;
vmax.x = xbase + 8 * UNITSIZE;
vmax.z = zbase + 8 * UNITSIZE;
update_intersect_points();
// use absolute y pos in vertices
ybase = 0.0f;
header.ypos = 0.0f;
vcenter = (vmin + vmax) * 0.5f;
return;
}
uint32_t fourcc;
uint32_t size;
@@ -1157,16 +1232,19 @@ void MapChunk::save(sExtendableArray &lADTFile, int &lCurrentPosition, int &lMCI
memset(lMCNK_header->low_quality_texture_map, 0, 0x10);
std::vector<uint8_t> lod_texture_map = texture_set->lod_texture_map();
for (int i = 0; i < lod_texture_map.size(); ++i)
if (texture_set)
{
const size_t array_index(i / 4);
// it's a uint2 array so we need to write the uint2 in the order they will be on disk,
// this means writing to the highest bits of the uint8 first
const size_t bit_index((3 - ((i) % 4)) * 2);
std::vector<uint8_t> lod_texture_map = texture_set->lod_texture_map();
lMCNK_header->low_quality_texture_map[array_index] |= ((lod_texture_map[i] & 3) << bit_index);
for (int i = 0; i < lod_texture_map.size(); ++i)
{
const size_t array_index(i / 4);
// it's a uint2 array so we need to write the uint2 in the order they will be on disk,
// this means writing to the highest bits of the uint8 first
const size_t bit_index((3 - ((i) % 4)) * 2);
lMCNK_header->low_quality_texture_map[array_index] |= ((lod_texture_map[i] & 3) << bit_index);
}
}
lCurrentPosition += 8 + 0x80;
@@ -1244,39 +1322,46 @@ void MapChunk::save(sExtendableArray &lADTFile, int &lCurrentPosition, int &lMCI
// MCLY
// {
size_t lMCLY_Size = texture_set->num() * 0x10;
size_t lMCLY_Size = texture_set ? texture_set->num() * 0x10 : 0;
lADTFile.Extend(8 + lMCLY_Size);
SetChunkHeader(lADTFile, lCurrentPosition, 'MCLY', lMCLY_Size);
lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8)->ofsLayer = lCurrentPosition - lMCNK_Position;
lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8)->nLayers = texture_set->num();
lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8)->nLayers = texture_set ? texture_set->num() : 0;
std::vector<std::vector<uint8_t>> alphamaps;
std::vector<std::vector<uint8_t>> alphamaps = texture_set->save_alpha(use_big_alphamap);
int lMCAL_Size = 0;
// MCLY data
for (size_t j = 0; j < texture_set->num(); ++j)
if (texture_set)
{
ENTRY_MCLY * lLayer = lADTFile.GetPointer<ENTRY_MCLY>(lCurrentPosition + 8 + 0x10 * j);
alphamaps = texture_set->save_alpha(use_big_alphamap);
lLayer->textureID = lTextures.find(texture_set->filename(j))->second;
lLayer->flags = texture_set->flag(j);
lLayer->ofsAlpha = lMCAL_Size;
lLayer->effectID = texture_set->effect(j);
if (j == 0)
// MCLY data
for (size_t j = 0; j < texture_set->num(); ++j)
{
lLayer->flags &= ~(FLAG_USE_ALPHA | FLAG_ALPHA_COMPRESSED);
}
else
{
lLayer->flags |= FLAG_USE_ALPHA;
//! \todo find out why compression fuck up textures ingame
lLayer->flags &= ~FLAG_ALPHA_COMPRESSED;
ENTRY_MCLY * lLayer = lADTFile.GetPointer<ENTRY_MCLY>(lCurrentPosition + 8 + 0x10 * j);
lMCAL_Size += alphamaps[j - 1].size();
lLayer->textureID = lTextures.find(texture_set->filename(j))->second;
lLayer->flags = texture_set->flag(j);
lLayer->ofsAlpha = lMCAL_Size;
lLayer->effectID = texture_set->effect(j);
if (j == 0)
{
lLayer->flags &= ~(FLAG_USE_ALPHA | FLAG_ALPHA_COMPRESSED);
}
else
{
lLayer->flags |= FLAG_USE_ALPHA;
//! \todo find out why compression fuck up textures ingame
lLayer->flags &= ~FLAG_ALPHA_COMPRESSED;
lMCAL_Size += alphamaps[j - 1].size();
}
}
}
lCurrentPosition += 8 + lMCLY_Size;

View File

@@ -89,7 +89,7 @@ private:
opengl::scoped::deferred_upload_buffers<4> lod_indices;
public:
MapChunk(MapTile* mt, MPQFile* f, bool bigAlpha, tile_mode mode);
MapChunk(MapTile* mt, MPQFile* f, bool bigAlpha, tile_mode mode, bool init_empty = false, int chunk_idx = 0);
MapTile *mt;
math::vector_3d vmin, vmax, vcenter;

View File

@@ -554,7 +554,7 @@ void MapTile::saveTile(World* world)
if (!model)
{
// todo: save elsewhere if this happens ? it shouldn't but still
LogError << "Could not fine model with uid=" << uid << " when saving " << filename << std::endl;
LogError << "Could not find model with uid=" << uid << " when saving " << filename << std::endl;
}
else
{
@@ -616,6 +616,11 @@ void MapTile::saveTile(World* world)
{
for (int j = 0; j < 16; ++j)
{
if (!mChunks[i][j]->texture_set)
{
continue;
}
for (size_t tex = 0; tex < mChunks[i][j]->texture_set->num(); tex++)
{
if (lTextures.find(mChunks[i][j]->texture_set->filename(tex)) == lTextures.end())
@@ -942,3 +947,11 @@ void MapTile::add_model(uint32_t uid)
uids.push_back(uid);
}
}
void MapTile::initEmptyChunks()
{
for (int nextChunk = 0; nextChunk < 256; ++nextChunk)
{
mChunks[nextChunk / 16][nextChunk % 16] = std::make_unique<MapChunk> (this, nullptr, mBigAlpha, _mode, true, nextChunk);
}
}

View File

@@ -125,6 +125,8 @@ public:
std::vector<uint32_t>* get_uids() { return &uids; }
void initEmptyChunks();
private:
tile_mode _mode;
bool _tile_is_being_reloaded;

View File

@@ -188,6 +188,43 @@ MapCreationWizard::MapCreationWizard(QWidget* parent) : noggit::ui::widget(paren
}
);
// Selection
QObject::connect
( _minimap_widget, &noggit::ui::minimap_widget::tile_clicked
, [this] (QPoint tile)
{
if (QApplication::keyboardModifiers().testFlag(Qt::ShiftModifier))
{
int x = tile.x() - 1;
int y = tile.y() - 1;
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
if (!_world->mapIndex.hasTile(tile_index(x + i, y + j)))
{
_world->mapIndex.addTile(tile_index(x + i, y + j));
// _world->mapIndex.saveTile(tile_index(x + i, y + j), _world.get(), true);
// _world->mapIndex.save();
}
}
}
}
else
{
if (_world->mapIndex.hasTile(tile_index(tile.x(), tile.y())))
{
//
}
}
update();
}
);
}
void MapCreationWizard::selectMap(int map_id)
@@ -195,7 +232,7 @@ void MapCreationWizard::selectMap(int map_id)
DBCFile::Record record = gMapDB.getByID(map_id);
_world = std::make_unique<World>(record.getString(MapDB::InternalName), map_id); // verify if leaks here
_world = std::make_unique<World>(record.getString(MapDB::InternalName), map_id);
_minimap_widget->world(_world.get());
_directory->setText(record.getString(1));

View File

@@ -78,8 +78,8 @@ namespace noggit
void wheelEvent(QWheelEvent *event) override;
private:
ui::minimap_widget *_minimap_widget;
QComboBox *_selected_map;
ui::minimap_widget* _minimap_widget;
QComboBox* _selected_map;
QGroupBox* _map_settings;
// Map settings

View File

@@ -406,11 +406,25 @@ bool MapIndex::isTileExternal(const tile_index& tile) const
return tile.is_valid() && mTiles[tile.z][tile.x].onDisc;
}
void MapIndex::saveTile(const tile_index& tile, World* world)
void MapIndex::saveTile(const tile_index& tile, World* world, bool save_unloaded)
{
world->wait_for_all_tile_updates();
// save given tile
if (save_unloaded)
{
QSettings settings;
auto filepath = boost::filesystem::path (settings.value ("project/path").toString().toStdString())
/ noggit::mpq::normalized_filename (mTiles[tile.z][tile.x].tile->filename);
QFile file(filepath.c_str());
file.open(QIODevice::WriteOnly);
mTiles[tile.z][tile.x].tile->initEmptyChunks();
mTiles[tile.z][tile.x].tile->saveTile(world);
return;
}
if (tileLoaded(tile))
{
saveMaxUID();
@@ -1052,3 +1066,26 @@ void MapIndex::saveMinimapMD5translate()
}
void MapIndex::addTile(const tile_index& tile)
{
int j = tile.z;
int i = tile.x;
std::stringstream filename;
filename << "World\\Maps\\" << basename << "\\" << basename << "_" << tile.x << "_" << tile.z << ".adt";
mTiles[tile.z][tile.x].tile = std::make_unique<MapTile> (tile.x, tile.z, filename.str(),
mBigAlpha, true, use_mclq_green_lava(), false, _world);
mTiles[tile.z][tile.x].onDisc = true;
mTiles[tile.z][tile.x].flags |= 0x1;
mTiles[tile.z][tile.x].tile->changed = true;
if (mTiles[tile.z][tile.x].onDisc)
{
mTiles[tile.z][tile.x].flags |= 1;
}
changed = true;
}

View File

@@ -163,7 +163,7 @@ public:
void setFlag(bool to, math::vector_3d const& pos, uint32_t flag);
bool has_unsaved_changes(const tile_index& tile) const;
void saveTile(const tile_index& tile, World*);
void saveTile(const tile_index& tile, World*, bool save_unloaded=false);
void saveChanged (World*);
void reloadTile(const tile_index& tile);
void unloadTiles(const tile_index& tile); // unloads all tiles more then x adts away from given
@@ -199,6 +199,8 @@ public:
void saveMaxUID();
void loadMaxUID();
void addTile(const tile_index& tile);
// todo: find out how wow choose to use the green lava in outland
inline bool use_mclq_green_lava() const
{

View File

@@ -35,25 +35,23 @@ namespace noggit
QWidget* temp_btn = new QWidget();
temp_btn->ensurePolished();
painter->setPen (temp_btn->palette().color(QPalette::WindowText));
QColor normal_button_color;
QColor color;
if (mode == QIcon::Normal)
{
normal_button_color = temp_btn->palette().color(QPalette::WindowText);
color = temp_btn->palette().color(QPalette::WindowText);
}
else if (state == QIcon::Off)
{
color = temp_btn->palette().color(QPalette::Shadow);
}
else if (mode == QIcon::Disabled)
{
color = temp_btn->palette().color(QPalette::BrightText);
}
QColor off_button_color;
if (state == QIcon::Off)
{
off_button_color = temp_btn->palette().color(QPalette::Shadow);
}
painter->setPen(color);
QColor disabled_button_color;
if (mode == QIcon::Disabled)
{
disabled_button_color = temp_btn->palette().color(QPalette::BrightText);
}
delete temp_btn;

View File

@@ -36,7 +36,23 @@ namespace noggit
QWidget* temp_btn = new QWidget();
temp_btn->ensurePolished();
painter->setPen(temp_btn->palette().color(QPalette::WindowText));
QColor color;
if (mode == QIcon::Normal)
{
color = temp_btn->palette().color(QPalette::WindowText);
}
else if (state == QIcon::Off)
{
color = temp_btn->palette().color(QPalette::Shadow);
}
else if (mode == QIcon::Disabled)
{
color = temp_btn->palette().color(QPalette::BrightText);
}
painter->setPen(color);
delete temp_btn;