From 70a9c8170a74f3d8bb9f6d0bfcb34c2b31936cdb Mon Sep 17 00:00:00 2001 From: T1ti Date: Tue, 22 Nov 2022 23:01:20 +0100 Subject: [PATCH 1/4] fix dbc locale loading for empty strings --- src/noggit/DBCFile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/noggit/DBCFile.h b/src/noggit/DBCFile.h index 61350003..b1962d36 100755 --- a/src/noggit/DBCFile.h +++ b/src/noggit/DBCFile.h @@ -66,7 +66,7 @@ public: if (locale == -1) { assert(field < file.fieldCount - 8); - for (loc = 0; loc < 16; loc++) + for (loc = 0; loc < 15; loc++) { size_t stringOffset = getUInt(field + loc); if (stringOffset != 0) From 8fcb5f9f3e1e3c85dbe283714066c2dadf7e15d5 Mon Sep 17 00:00:00 2001 From: T1ti Date: Tue, 22 Nov 2022 23:02:04 +0100 Subject: [PATCH 2/4] asset browser fix --- src/noggit/ui/tools/AssetBrowser/Ui/AssetBrowser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/noggit/ui/tools/AssetBrowser/Ui/AssetBrowser.cpp b/src/noggit/ui/tools/AssetBrowser/Ui/AssetBrowser.cpp index 44aaccf5..ebbf9d0d 100755 --- a/src/noggit/ui/tools/AssetBrowser/Ui/AssetBrowser.cpp +++ b/src/noggit/ui/tools/AssetBrowser/Ui/AssetBrowser.cpp @@ -108,8 +108,9 @@ AssetBrowserWidget::AssetBrowserWidget(MapView* map_view, QWidget *parent) ); connect(ui->viewport, &ModelViewer::model_set - ,[=] (const std::string& filename) + , [=](const std::string& filename) { + viewport_overlay_ui->doodadSetSelector->clear(); viewport_overlay_ui->doodadSetSelector->insertItems(0, ui->viewport->getDoodadSetNames(filename)); bool is_wmo = QString::fromStdString(filename).endsWith(".wmo"); From c74ffd1eaa0fdb8dbb8bdaeeb88a96b151f2ac96 Mon Sep 17 00:00:00 2001 From: T1ti Date: Tue, 22 Nov 2022 23:03:18 +0100 Subject: [PATCH 3/4] improve detail info window --- src/noggit/ModelInstance.cpp | 2 +- src/noggit/WMO.cpp | 4 ++-- src/noggit/WMO.h | 2 ++ src/noggit/WMOInstance.cpp | 4 +++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/noggit/ModelInstance.cpp b/src/noggit/ModelInstance.cpp index 4fa8c079..f58c6b41 100755 --- a/src/noggit/ModelInstance.cpp +++ b/src/noggit/ModelInstance.cpp @@ -229,7 +229,7 @@ void ModelInstance::updateDetails(Noggit::Ui::detail_infos* detail_widget) std::stringstream select_info; select_info << "filename: " << model->file_key().filepath() - << "
FileDataID: " << model->file_key().fileDataID() + // << "
FileDataID: " << model->file_key().fileDataID() // not in WOTLK << "
unique ID: " << uid << "
position X/Y/Z: {" << pos.x << " , " << pos.y << " , " << pos.z << "}" << "
rotation X/Y/Z: {" << dir.x << " , " << dir.y << " , " << dir.z << "}" diff --git a/src/noggit/WMO.cpp b/src/noggit/WMO.cpp index e1950549..8128b962 100755 --- a/src/noggit/WMO.cpp +++ b/src/noggit/WMO.cpp @@ -61,7 +61,7 @@ void WMO::finishLoading () assert (fourcc == 'MOHD'); CArgb ambient_color; - unsigned int nTextures, nGroups, nP, nLights, nModels, nDoodads, nDoodadSets, nX; + unsigned int nTextures, nGroups, nP, nLights, nModels, nDoodads, nDoodadSets; // header f.read (&nTextures, 4); f.read (&nGroups, 4); @@ -71,7 +71,7 @@ void WMO::finishLoading () f.read (&nDoodads, 4); f.read (&nDoodadSets, 4); f.read (&ambient_color, 4); - f.read (&nX, 4); + f.read (&WmoId, 4); f.read (ff, 12); extents[0] = ::glm::vec3 (ff[0], ff[1], ff[2]); f.read (ff, 12); diff --git a/src/noggit/WMO.h b/src/noggit/WMO.h index bb242aac..9123a2f6 100755 --- a/src/noggit/WMO.h +++ b/src/noggit/WMO.h @@ -271,6 +271,8 @@ public: std::vector lights; glm::vec4 ambient_light_color; + uint32_t WmoId; + mohd_flags flags; std::vector fogs; diff --git a/src/noggit/WMOInstance.cpp b/src/noggit/WMOInstance.cpp index b7e2bd16..7f1c9641 100755 --- a/src/noggit/WMOInstance.cpp +++ b/src/noggit/WMOInstance.cpp @@ -164,11 +164,13 @@ void WMOInstance::updateDetails(Noggit::Ui::detail_infos* detail_widget) std::stringstream select_info; select_info << "filename: " << wmo->file_key().filepath() - << "
FileDataID: " << wmo->file_key().fileDataID() + // << "
FileDataID: " << wmo->file_key().fileDataID() not in wrath << "
unique ID: " << uid << "
position X/Y/Z: {" << pos.x << ", " << pos.y << ", " << pos.z << "}" << "
rotation X/Y/Z: {" << dir.x << ", " << dir.y << ", " << dir.z << "}" + << "
WMO Id: " << wmo->WmoId << "
doodad set: " << doodadset() + << "
name set: " << mNameset << "
textures used: " << wmo->textures.size() << ""; From 6bd406cc762ee9a9409f320db66d9d51903e955e Mon Sep 17 00:00:00 2001 From: T1ti Date: Tue, 22 Nov 2022 23:04:39 +0100 Subject: [PATCH 4/4] Object editor : doodadset&nameset selectors --- src/noggit/DBC.cpp | 69 ++++++++++++++++++ src/noggit/DBC.h | 25 +++++++ src/noggit/MapView.cpp | 3 + src/noggit/ui/ObjectEditor.cpp | 125 +++++++++++++++++++++++++++++++-- src/noggit/ui/ObjectEditor.h | 8 +++ 5 files changed, 226 insertions(+), 4 deletions(-) diff --git a/src/noggit/DBC.cpp b/src/noggit/DBC.cpp index 4a032398..c1d37a66 100755 --- a/src/noggit/DBC.cpp +++ b/src/noggit/DBC.cpp @@ -22,6 +22,7 @@ SoundAmbienceDB gSoundAmbienceDB; ZoneMusicDB gZoneMusicDB; ZoneIntroMusicTableDB gZoneIntroMusicTableDB; SoundEntriesDB gSoundEntriesDB; +WMOAreaTableDB gWMOAreaTableDB; void OpenDBs(std::shared_ptr clientData) { @@ -41,6 +42,7 @@ void OpenDBs(std::shared_ptr clientData) gZoneMusicDB.open(clientData); gZoneIntroMusicTableDB.open(clientData); gSoundEntriesDB.open(clientData); + gWMOAreaTableDB.open(clientData); } @@ -185,3 +187,70 @@ std::string LiquidTypeDB::getLiquidName(int pID) return type; } + +std::string WMOAreaTableDB::getWMOAreaName(int WMOId, int namesetId) +{ + if (WMOId == -1) + { + return "Unknown location"; + } + + for (Iterator i = gWMOAreaTableDB.begin(); i != gWMOAreaTableDB.end(); ++i) + { + if (i->getUInt(WMOAreaTableDB::WmoId) == WMOId && i->getUInt(WMOAreaTableDB::NameSetId) == namesetId && i->getUInt(WMOAreaTableDB::WMOGroupID) == -1) + { + // wmoareatableid = i->getUInt(WMOAreaTableDB::ID); + std::string areaName = i->getLocalizedString(WMOAreaTableDB::Name); + + if (!areaName.empty()) + return areaName; + else + { // get name from area instead + int areatableid = i->getUInt(WMOAreaTableDB::AreaTableRefId); + if (areatableid) + { + auto rec = gAreaDB.getByID(areatableid); + return rec.getLocalizedString(AreaDB::Name); + } + else + return "Unknown location"; // nullptr? need to get it from terrain + } + } + } + throw NotFound(); +} + +std::vector WMOAreaTableDB::getWMOAreaNames(int WMOId) +{ + std::vector areanamesvect; + + if (WMOId == -1) + { + return areanamesvect; + } + + for (Iterator i = gWMOAreaTableDB.begin(); i != gWMOAreaTableDB.end(); ++i) + { + if (i->getUInt(WMOAreaTableDB::WmoId) == WMOId && i->getUInt(WMOAreaTableDB::WMOGroupID) == -1) + { + // wmoareatableid = i->getUInt(WMOAreaTableDB::ID); + std::string areaName = i->getLocalizedString(WMOAreaTableDB::Name); + + if (!areaName.empty()) + areanamesvect.push_back(areaName); + else + { // get name from area instead + int areatableid = i->getUInt(WMOAreaTableDB::AreaTableRefId); + if (areatableid) + { + auto rec = gAreaDB.getByID(areatableid); + areanamesvect.push_back(rec.getLocalizedString(AreaDB::Name)); + } + else + areanamesvect.push_back(""); // nullptr? need to get it from terrain + } + } + // could optimise and break when iterator WmoId is higher than the Wmodid, but this wouldn't support unordered DBCs. + } + return areanamesvect; +} diff --git a/src/noggit/DBC.h b/src/noggit/DBC.h index c0ae2e1e..4146eae0 100755 --- a/src/noggit/DBC.h +++ b/src/noggit/DBC.h @@ -275,7 +275,31 @@ public: static const size_t distanceCutoff = 27; // float static const size_t EAXDef = 28; // int static const size_t soundEntriesAdvancedID = 29; // int +}; +class WMOAreaTableDB : public DBCFile +{ +public: + WMOAreaTableDB() : + DBCFile("DBFilesClient\\WMOAreaTable.dbc") + { } + + /// Fields + static const size_t ID = 0; // uint + static const size_t WmoId = 1; // uint + static const size_t NameSetId = 2; // uint [AreaID] + static const size_t WMOGroupID= 3; // uint + static const size_t SoundProviderPreferences = 4; // uint + static const size_t UnderwaterSoundProviderPreferences = 5; // uint + static const size_t SoundAmbience = 6; // uint + static const size_t ZoneMusic = 7; // uint + static const size_t ZoneIntroMusicTable = 8; // uint + static const size_t Flags = 9; // int CWorldMap::QueryOutdoors: rec.flags & 4 || rec.flags & 2. &0x18: Minimap::s_singleExterior = true unless groupRec::flags & 0x20 + static const size_t AreaTableRefId = 10; // uint + static const size_t Name = 11; // localisation string + + static std::string getWMOAreaName(int WMOId, int namesetId); + static std::vector getWMOAreaNames(int WMOId); }; void OpenDBs(std::shared_ptr clientData); @@ -298,3 +322,4 @@ extern SoundAmbienceDB gSoundAmbienceDB; extern ZoneMusicDB gZoneMusicDB; extern ZoneIntroMusicTableDB gZoneIntroMusicTableDB; extern SoundEntriesDB gSoundEntriesDB; +extern WMOAreaTableDB gWMOAreaTableDB; diff --git a/src/noggit/MapView.cpp b/src/noggit/MapView.cpp index f4cb0a8a..c6d93d21 100755 --- a/src/noggit/MapView.cpp +++ b/src/noggit/MapView.cpp @@ -4117,6 +4117,7 @@ void MapView::doSelection (bool selectTerrainOnly, bool mouseMove) } else if (!_mod_space_down && !_mod_alt_down && !_mod_ctrl_down) { + // objectEditor->update_selection(_world.get()); _world->reset_selection(); _world->add_to_selection(hit); } @@ -4139,6 +4140,8 @@ void MapView::doSelection (bool selectTerrainOnly, bool mouseMove) } _rotation_editor_need_update = true; + objectEditor->update_selection(_world.get()); + } void MapView::update_cursor_pos() diff --git a/src/noggit/ui/ObjectEditor.cpp b/src/noggit/ui/ObjectEditor.cpp index 05316d57..5c2c6818 100755 --- a/src/noggit/ui/ObjectEditor.cpp +++ b/src/noggit/ui/ObjectEditor.cpp @@ -13,6 +13,9 @@ #include #include #include +#include +#include "noggit/ActionManager.hpp" +#include "noggit/Action.hpp" #include #include @@ -93,6 +96,21 @@ namespace Noggit drag_selection_depth_layout->addRow(_drag_selection_depth_spin); layout->addWidget(drag_selection_depth_group); + QPushButton* asset_browser_btn = new QPushButton("Asset browser", this); + layout->addWidget(asset_browser_btn); + QPushButton* object_palette_btn = new QPushButton("Object palette", this); + layout->addWidget(object_palette_btn); + + _wmo_group = new QGroupBox("WMO Options"); + auto wmo_layout = new QFormLayout(_wmo_group); + + _doodadSetSelector = new QComboBox(this); + _nameSetSelector = new QComboBox(this); + layout->addWidget(_wmo_group); + + wmo_layout->addRow("Doodad Set:", _doodadSetSelector); + wmo_layout->addRow("Name Set:", _nameSetSelector); + auto *copyBox = new ExpanderWidget( this); copyBox->setExpanderTitle("Copy options"); copyBox->setExpanded(_settings->value ("object_editor/copy_options", false).toBool()); @@ -269,16 +287,12 @@ namespace Noggit QPushButton *last_m2_from_wmv = new QPushButton("Last M2 from WMV", this); QPushButton *last_wmo_from_wmv = new QPushButton("Last WMO from WMV", this); QPushButton *helper_models_btn = new QPushButton("Helper Models", this); - QPushButton *asset_browser_btn = new QPushButton("Asset browser", this); - QPushButton *object_palette_btn = new QPushButton("Object palette", this); importBox_content_layout->addWidget(toTxt); importBox_content_layout->addWidget(fromTxt); importBox_content_layout->addWidget(last_m2_from_wmv); importBox_content_layout->addWidget(last_wmo_from_wmv); importBox_content_layout->addWidget(helper_models_btn); - importBox_content_layout->addWidget(asset_browser_btn); - importBox_content_layout->addWidget(object_palette_btn); importBox->addPage(importBox_content); @@ -489,6 +503,50 @@ namespace Noggit , [=]() { mapView->getObjectPalette()->setVisible(mapView->getObjectPalette()->isHidden()); } ); + connect(_doodadSetSelector + , qOverload(&QComboBox::currentIndexChanged) + , [this](int index) { + auto last_entry = _map_view->_world->get_last_selected_model(); + if (last_entry) + { + if (last_entry.value().index() != eEntry_Object) + { + return; + } + auto obj = std::get(last_entry.value()); + if (obj->which() == eWMO) + { + // use actions or directly call updateDetailInfos() ? + WMOInstance* wi = static_cast(obj); + NOGGIT_ACTION_MGR->beginAction(_map_view, Noggit::ActionFlags::eOBJECTS_TRANSFORMED); + wi->change_doodadset(index); + NOGGIT_ACTION_MGR->endAction(); + } + } + }); + + connect(_nameSetSelector + , qOverload(&QComboBox::currentIndexChanged) + , [this](int index) { + auto last_entry = _map_view->_world->get_last_selected_model(); + if (last_entry) + { + if (last_entry.value().index() != eEntry_Object) + { + return; + } + auto obj = std::get(last_entry.value()); + if (obj->which() == eWMO) + { + WMOInstance* wi = static_cast(obj); + NOGGIT_ACTION_MGR->beginAction(_map_view, Noggit::ActionFlags::eOBJECTS_TRANSFORMED); + wi->mNameset = index; + NOGGIT_ACTION_MGR->endAction(); + + } + } + }); + auto mv_pos = mapView->pos(); auto mv_size = mapView->size(); @@ -816,5 +874,64 @@ namespace Noggit { return QSize(215, height()); } + + void object_editor::update_selection(World* world) + { + _wmo_group->setDisabled(true); + _wmo_group->hide(); + + auto last_entry = world->get_last_selected_model(); + // for (auto& selection : selected) + if (last_entry) + { + if (last_entry.value().index() != eEntry_Object) + { + return; + } + auto obj = std::get(last_entry.value()); + + if (obj->which() == eMODEL) + { + // ModelInstance* mi = static_cast(obj); + } + else if (obj->which() == eWMO) + { + _wmo_group->setDisabled(false); + _wmo_group->setHidden(false); + WMOInstance* wi = static_cast(obj); + + QSignalBlocker const doodadsetblocker(_doodadSetSelector); + _doodadSetSelector->clear(); + + QStringList doodadsetnames; + for (auto& doodad_set : wi->wmo->doodadsets) + { + doodadsetnames.append(doodad_set.name); + } + _doodadSetSelector->insertItems(0, doodadsetnames); + _doodadSetSelector->setCurrentIndex(wi->doodadset()); + + // get names from WMOAreatable, if no name, get from areatable + // if no areatable, we have to get the terrain's area + QSignalBlocker const namesetblocker(_nameSetSelector); + _nameSetSelector->clear(); + auto wmoid = wi->wmo->WmoId; + auto setnames = gWMOAreaTableDB.getWMOAreaNames(wmoid); + QStringList namesetnames; + for (auto& area_name : setnames) + { + if (area_name.empty()) + { + auto chunk = world->getChunkAt(wi->pos); + namesetnames.append(gAreaDB.getAreaName(chunk->getAreaID()).c_str()); + } + else + namesetnames.append(area_name.c_str()); + } + _nameSetSelector->insertItems(0, namesetnames); + _nameSetSelector->setCurrentIndex(wi->mNameset); + } + } + } } } diff --git a/src/noggit/ui/ObjectEditor.h b/src/noggit/ui/ObjectEditor.h index e97668de..ba1a41e3 100755 --- a/src/noggit/ui/ObjectEditor.h +++ b/src/noggit/ui/ObjectEditor.h @@ -9,6 +9,8 @@ #include #include #include +#include +#include class MapView; class QButtonGroup; @@ -84,6 +86,8 @@ namespace Noggit helper_models* helper_models_widget; QSize sizeHint() const override; + void update_selection(World* world); + private: float _radius = 0.01f; float _drag_selection_depth = 100.0f; @@ -95,6 +99,10 @@ namespace Noggit QSlider* _drag_selection_depth_slider; QDoubleSpinBox* _drag_selection_depth_spin; + QGroupBox* _wmo_group; + QComboBox* _doodadSetSelector; + QComboBox* _nameSetSelector; + QSettings* _settings; QButtonGroup* pasteModeGroup;