minimap editor: add missing functionality that was present in UI only
map wizard: add ability to edit existing maps. WIP.
This commit is contained in:
@@ -86,24 +86,38 @@ public:
|
||||
*reinterpret_cast<T*>(offset + field * 4) = val;
|
||||
}
|
||||
|
||||
void writeString(size_t field, std::string& val)
|
||||
void writeString(size_t field, const std::string& val)
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
|
||||
if (!val.size())
|
||||
{
|
||||
*reinterpret_cast<unsigned int*>(offset + field * 4) = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t old_size = file.stringTable.size();
|
||||
*reinterpret_cast<unsigned int*>(offset + field * 4) = file.stringTable.size();
|
||||
file.stringTable.resize(old_size + val.size() + 1);
|
||||
std::copy(val.c_str(), val.c_str() + val.size() + 1, file.stringTable.data() + old_size);
|
||||
file.stringSize += val.size() + 1;
|
||||
}
|
||||
|
||||
void writeLocalizedString(size_t field, std::string& val, int locale)
|
||||
void writeLocalizedString(size_t field, const std::string& val, int locale)
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
|
||||
if (!val.size())
|
||||
{
|
||||
*reinterpret_cast<unsigned int*>(offset + ((field + locale) * 4)) = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t old_size = file.stringTable.size();
|
||||
*reinterpret_cast<unsigned int*>(offset + field + locale * 4) = file.stringTable.size();
|
||||
*reinterpret_cast<unsigned int*>(offset + ((field + locale) * 4)) = file.stringTable.size();
|
||||
file.stringTable.resize(old_size + val.size() + 1);
|
||||
std::copy(val.c_str(), val.c_str() + val.size() + 1, file.stringTable.data() + old_size);
|
||||
file.stringSize += val.size() + 1;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -111,7 +111,7 @@ MapCreationWizard::MapCreationWizard(QWidget* parent) : noggit::ui::widget(paren
|
||||
_instance_type->addItem("None");
|
||||
_instance_type->setItemData(0, QVariant(0));
|
||||
|
||||
_instance_type->addItem("Instance Crusade");
|
||||
_instance_type->addItem("Instance");
|
||||
_instance_type->setItemData(1, QVariant(1));
|
||||
|
||||
_instance_type->addItem("Raid");
|
||||
@@ -177,10 +177,34 @@ MapCreationWizard::MapCreationWizard(QWidget* parent) : noggit::ui::widget(paren
|
||||
_max_players = new QSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Max players:",_max_players);
|
||||
|
||||
// Bottom row
|
||||
auto btn_row_layout = new QHBoxLayout(this);
|
||||
btn_row_layout->setAlignment(Qt::AlignRight);
|
||||
|
||||
auto save_btn = new QPushButton("Save", this);
|
||||
auto discard_btn = new QPushButton("Discard", this);
|
||||
btn_row_layout->addWidget(save_btn);
|
||||
btn_row_layout->addWidget(discard_btn);
|
||||
|
||||
layout_right->addItem(btn_row_layout);
|
||||
|
||||
|
||||
selectMap(_selected_map->itemData(_selected_map->currentIndex()).toInt());
|
||||
|
||||
// Connections
|
||||
|
||||
connect(save_btn, &QPushButton::clicked
|
||||
,[&] ()
|
||||
{
|
||||
saveCurrentEntry();
|
||||
});
|
||||
|
||||
connect(discard_btn, &QPushButton::clicked
|
||||
,[&] ()
|
||||
{
|
||||
|
||||
});
|
||||
|
||||
connect(_selected_map, QOverload<int>::of(&QComboBox::currentIndexChanged)
|
||||
, [&] (int index)
|
||||
{
|
||||
@@ -205,19 +229,33 @@ MapCreationWizard::MapCreationWizard(QWidget* parent) : noggit::ui::widget(paren
|
||||
{
|
||||
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();
|
||||
if (!QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
{
|
||||
_world->mapIndex.addTile(tile_index(x + i, y + j));
|
||||
}
|
||||
}
|
||||
else if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
{
|
||||
_world->mapIndex.removeTile(tile_index(x + i, y + j));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_world->mapIndex.hasTile(tile_index(tile.x(), tile.y())))
|
||||
int x = tile.x();
|
||||
int y = tile.y();
|
||||
|
||||
if (!_world->mapIndex.hasTile(tile_index(x, y)))
|
||||
{
|
||||
//
|
||||
if (!QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
{
|
||||
_world->mapIndex.addTile(tile_index(x, y));
|
||||
}
|
||||
}
|
||||
else if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
{
|
||||
_world->mapIndex.removeTile(tile_index(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,6 +269,7 @@ void MapCreationWizard::selectMap(int map_id)
|
||||
{
|
||||
|
||||
DBCFile::Record record = gMapDB.getByID(map_id);
|
||||
_cur_map_id = map_id;
|
||||
|
||||
_world = std::make_unique<World>(record.getString(MapDB::InternalName), map_id);
|
||||
_minimap_widget->world(_world.get());
|
||||
@@ -290,6 +329,42 @@ void MapCreationWizard::wheelEvent(QWheelEvent* event)
|
||||
|
||||
}
|
||||
|
||||
void MapCreationWizard::saveCurrentEntry()
|
||||
{
|
||||
// Save ADTs to disk
|
||||
_world->mapIndex.saveChanged(_world.get(), true);
|
||||
_world->mapIndex.save();
|
||||
|
||||
// Save Map.dbc record
|
||||
DBCFile::Record record = _is_new_record ? gMapDB.addRecord(_cur_map_id) : gMapDB.getByID(_cur_map_id);
|
||||
|
||||
record.writeString(1, _directory->text().toStdString());
|
||||
record.write(2, _instance_type->itemData(_instance_type->currentIndex()).toInt());
|
||||
_map_name->toRecord(record, 5);
|
||||
|
||||
record.write(22, _area_table_id->value());
|
||||
_map_desc_alliance->toRecord(record, 23);
|
||||
_map_desc_horde->toRecord(record, 40);
|
||||
record.write(57, _loading_screen->value());
|
||||
record.write(58, static_cast<float>(_minimap_icon_scale->value()));
|
||||
record.write(59, _corpse_map_id->itemData(_corpse_map_id->currentIndex()).toInt());
|
||||
record.write(60, static_cast<float>(_corpse_x->value()));
|
||||
record.write(61, static_cast<float>(_corpse_y->value()));
|
||||
record.write(62, _time_of_day_override->value());
|
||||
record.write(63, _expansion_id->itemData(_expansion_id->currentIndex()).toInt());
|
||||
record.write(64, _raid_offset->value());
|
||||
record.write(65, _max_players->value());
|
||||
|
||||
gMapDB.save();
|
||||
|
||||
}
|
||||
|
||||
void MapCreationWizard::discardChanges()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
LocaleDBCEntry::LocaleDBCEntry(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
auto layout = new QHBoxLayout(this);
|
||||
@@ -379,7 +454,7 @@ void LocaleDBCEntry::setCurrentLocale(const std::string& locale)
|
||||
_show_entry->setCurrentWidget(_widget_map.at(locale));
|
||||
}
|
||||
|
||||
void LocaleDBCEntry::fill(DBCFile::Record& record, size_t field, size_t id_field)
|
||||
void LocaleDBCEntry::fill(DBCFile::Record& record, size_t field)
|
||||
{
|
||||
for (int loc = 0; loc < 16; ++loc)
|
||||
{
|
||||
@@ -389,5 +464,15 @@ void LocaleDBCEntry::fill(DBCFile::Record& record, size_t field, size_t id_field
|
||||
_flags->setValue(record.getInt(field + 16));
|
||||
}
|
||||
|
||||
void LocaleDBCEntry::toRecord(DBCFile::Record &record, size_t field)
|
||||
{
|
||||
for (int loc = 0; loc < 16; ++loc)
|
||||
{
|
||||
record.writeLocalizedString(field,getValue(loc), loc);
|
||||
}
|
||||
|
||||
record.write(field + 16, _flags->value());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -41,7 +41,10 @@ namespace noggit
|
||||
_widget_map.at(_locale_names[locale])->setText(QString::fromStdString(val));
|
||||
}
|
||||
|
||||
void fill(DBCFile::Record& record, size_t field, size_t id_field = 0);
|
||||
std::string getValue(int locale) { return _widget_map.at(_locale_names[locale])->text().toStdString(); };
|
||||
|
||||
void fill(DBCFile::Record& record, size_t field);
|
||||
void toRecord(DBCFile::Record& record, size_t field);
|
||||
|
||||
private:
|
||||
QComboBox* _current_locale;
|
||||
@@ -107,8 +110,14 @@ namespace noggit
|
||||
|
||||
std::unique_ptr<World> _world;
|
||||
|
||||
bool _is_new_record = false;
|
||||
int _cur_map_id = 0;
|
||||
|
||||
void selectMap(int map_id);
|
||||
|
||||
void saveCurrentEntry();
|
||||
void discardChanges();
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1868,7 +1868,7 @@ void World::drawMinimap ( MapTile *tile
|
||||
mcnk_shader.uniform("tex2", 3);
|
||||
mcnk_shader.uniform("tex3", 4);
|
||||
|
||||
mcnk_shader.uniform("draw_shadows", 0);
|
||||
mcnk_shader.uniform("draw_shadows", static_cast<int>(settings->draw_shadows));
|
||||
mcnk_shader.uniform("shadow_map", 5);
|
||||
|
||||
mcnk_shader.uniform("tex_anim_0", math::vector_2d());
|
||||
@@ -2168,28 +2168,34 @@ bool World::saveMinimap(tile_index const& tile_idx, MinimapRenderSettings* setti
|
||||
if (!dir.exists())
|
||||
dir.mkpath(".");
|
||||
|
||||
QByteArray bytes;
|
||||
QBuffer buffer( &bytes );
|
||||
buffer.open( QIODevice::WriteOnly );
|
||||
|
||||
image.save( &buffer, "PNG" );
|
||||
image.save(std::string(basename + "_" + std::to_string(tile_idx.x) + "_" + std::to_string(tile_idx.z) + ".png").c_str());
|
||||
|
||||
auto blp = Png2Blp();
|
||||
blp.load(reinterpret_cast<const void*>(bytes.constData()), bytes.size());
|
||||
|
||||
uint32_t file_size;
|
||||
void* blp_image = blp.createBlpUncompressedInMemory(true, file_size);
|
||||
|
||||
std::string tex_name = std::string(basename + "_" + std::to_string(tile_idx.x) + "_" + std::to_string(tile_idx.z) + ".blp");
|
||||
|
||||
QFile file(dir.filePath(tex_name.c_str()));
|
||||
file.open(QIODevice::WriteOnly);
|
||||
if (settings->file_format == ".png")
|
||||
{
|
||||
image.save(std::string(basename + "_" + std::to_string(tile_idx.x) + "_" + std::to_string(tile_idx.z) + ".png").c_str());
|
||||
}
|
||||
else if (settings->file_format == ".blp")
|
||||
{
|
||||
QByteArray bytes;
|
||||
QBuffer buffer( &bytes );
|
||||
buffer.open( QIODevice::WriteOnly );
|
||||
|
||||
QDataStream out(&file);
|
||||
out.writeRawData(reinterpret_cast<char*>(blp_image), file_size);
|
||||
image.save( &buffer, "PNG" );
|
||||
|
||||
file.close();
|
||||
auto blp = Png2Blp();
|
||||
blp.load(reinterpret_cast<const void*>(bytes.constData()), bytes.size());
|
||||
|
||||
uint32_t file_size;
|
||||
void* blp_image = blp.createBlpUncompressedInMemory(true, file_size);
|
||||
|
||||
QFile file(dir.filePath(tex_name.c_str()));
|
||||
file.open(QIODevice::WriteOnly);
|
||||
|
||||
QDataStream out(&file);
|
||||
out.writeRawData(reinterpret_cast<char*>(blp_image), file_size);
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
// Write combined file
|
||||
if (settings->combined_minimap)
|
||||
@@ -2230,8 +2236,6 @@ bool World::saveMinimap(tile_index const& tile_idx, MinimapRenderSettings* setti
|
||||
std::string tilename_left = (boost::format("%s\\map_%d_%02d.blp") % map_name % tile_idx.x % tile_idx.z).str();
|
||||
mapIndex._minimap_md5translate[map_name][tilename_left] = tex_name;
|
||||
|
||||
// image.save(dir.filePath(std::string(basename + "_" + std::to_string(tile_idx.x) + "_" + std::to_string(tile_idx.z) + ".png").c_str()));
|
||||
|
||||
if (unload)
|
||||
{
|
||||
mapIndex.unloadTile(tile_idx);
|
||||
|
||||
@@ -432,7 +432,7 @@ void MapIndex::saveTile(const tile_index& tile, World* world, bool save_unloaded
|
||||
}
|
||||
}
|
||||
|
||||
void MapIndex::saveChanged (World* world)
|
||||
void MapIndex::saveChanged (World* world, bool save_unloaded)
|
||||
{
|
||||
world->wait_for_all_tile_updates();
|
||||
|
||||
@@ -441,7 +441,43 @@ void MapIndex::saveChanged (World* world)
|
||||
save();
|
||||
}
|
||||
|
||||
saveMaxUID();
|
||||
if (!save_unloaded)
|
||||
{
|
||||
saveMaxUID();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
for (int j = 0; j < 64; ++j)
|
||||
{
|
||||
if (!(mTiles[i][j].tile && mTiles[i][j].tile->changed.load()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QSettings settings;
|
||||
auto filepath = boost::filesystem::path (settings.value ("project/path").toString().toStdString())
|
||||
/ noggit::mpq::normalized_filename (mTiles[i][j].tile->filename);
|
||||
|
||||
if (mTiles[i][j].flags & 0x1)
|
||||
{
|
||||
QFile file(filepath.string().c_str());
|
||||
file.open(QIODevice::WriteOnly);
|
||||
|
||||
mTiles[i][j].tile->initEmptyChunks();
|
||||
mTiles[i][j].tile->saveTile(world);
|
||||
mTiles[i][j].tile->changed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
QFile file(filepath.string().c_str());
|
||||
file.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (MapTile* tile : loaded_tiles())
|
||||
{
|
||||
@@ -1069,23 +1105,29 @@ 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;
|
||||
}
|
||||
|
||||
void MapIndex::removeTile(const tile_index &tile)
|
||||
{
|
||||
mTiles[tile.z][tile.x].flags &= ~0x1;
|
||||
|
||||
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].tile->changed = true;
|
||||
mTiles[tile.z][tile.x].onDisc = false;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@@ -163,8 +163,8 @@ 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*, bool save_unloaded=false);
|
||||
void saveChanged (World*);
|
||||
void saveTile(const tile_index& tile, World*, bool save_unloaded = false);
|
||||
void saveChanged (World*, bool save_unloaded = false);
|
||||
void reloadTile(const tile_index& tile);
|
||||
void unloadTiles(const tile_index& tile); // unloads all tiles more then x adts away from given
|
||||
void unloadTile(const tile_index& tile); // unload given tile
|
||||
@@ -200,6 +200,7 @@ public:
|
||||
void loadMaxUID();
|
||||
|
||||
void addTile(const tile_index& tile);
|
||||
void removeTile(const tile_index& tile);
|
||||
|
||||
// todo: find out how wow choose to use the green lava in outland
|
||||
inline bool use_mclq_green_lava() const
|
||||
|
||||
Reference in New Issue
Block a user