Merge branch 'wmo-stuff' into 'noggit-shadowlands'
Wmo stuff See merge request prophecy-rp/noggit-red!23
This commit is contained in:
@@ -22,6 +22,7 @@ SoundAmbienceDB gSoundAmbienceDB;
|
||||
ZoneMusicDB gZoneMusicDB;
|
||||
ZoneIntroMusicTableDB gZoneIntroMusicTableDB;
|
||||
SoundEntriesDB gSoundEntriesDB;
|
||||
WMOAreaTableDB gWMOAreaTableDB;
|
||||
|
||||
void OpenDBs(std::shared_ptr<BlizzardArchive::ClientData> clientData)
|
||||
{
|
||||
@@ -41,6 +42,7 @@ void OpenDBs(std::shared_ptr<BlizzardArchive::ClientData> 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<std::string> WMOAreaTableDB::getWMOAreaNames(int WMOId)
|
||||
{
|
||||
std::vector<std::string> 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;
|
||||
}
|
||||
|
||||
@@ -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<std::string> getWMOAreaNames(int WMOId);
|
||||
};
|
||||
|
||||
void OpenDBs(std::shared_ptr<BlizzardArchive::ClientData> clientData);
|
||||
@@ -298,3 +322,4 @@ extern SoundAmbienceDB gSoundAmbienceDB;
|
||||
extern ZoneMusicDB gZoneMusicDB;
|
||||
extern ZoneIntroMusicTableDB gZoneIntroMusicTableDB;
|
||||
extern SoundEntriesDB gSoundEntriesDB;
|
||||
extern WMOAreaTableDB gWMOAreaTableDB;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -4132,6 +4132,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);
|
||||
}
|
||||
@@ -4154,6 +4155,8 @@ void MapView::doSelection (bool selectTerrainOnly, bool mouseMove)
|
||||
}
|
||||
|
||||
_rotation_editor_need_update = true;
|
||||
objectEditor->update_selection(_world.get());
|
||||
|
||||
}
|
||||
|
||||
void MapView::update_cursor_pos()
|
||||
|
||||
@@ -229,7 +229,7 @@ void ModelInstance::updateDetails(Noggit::Ui::detail_infos* detail_widget)
|
||||
std::stringstream select_info;
|
||||
|
||||
select_info << "<b>filename:</b> " << model->file_key().filepath()
|
||||
<< "<br><b>FileDataID:</b> " << model->file_key().fileDataID()
|
||||
// << "<br><b>FileDataID:</b> " << model->file_key().fileDataID() // not in WOTLK
|
||||
<< "<br><b>unique ID:</b> " << uid
|
||||
<< "<br><b>position X/Y/Z:</b> {" << pos.x << " , " << pos.y << " , " << pos.z << "}"
|
||||
<< "<br><b>rotation X/Y/Z:</b> {" << dir.x << " , " << dir.y << " , " << dir.z << "}"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -271,6 +271,8 @@ public:
|
||||
std::vector<WMOLight> lights;
|
||||
glm::vec4 ambient_light_color;
|
||||
|
||||
uint32_t WmoId;
|
||||
|
||||
mohd_flags flags;
|
||||
|
||||
std::vector<WMOFog> fogs;
|
||||
|
||||
@@ -164,11 +164,13 @@ void WMOInstance::updateDetails(Noggit::Ui::detail_infos* detail_widget)
|
||||
std::stringstream select_info;
|
||||
|
||||
select_info << "<b>filename: </b>" << wmo->file_key().filepath()
|
||||
<< "<br><b>FileDataID: </b>" << wmo->file_key().fileDataID()
|
||||
// << "<br><b>FileDataID: </b>" << wmo->file_key().fileDataID() not in wrath
|
||||
<< "<br><b>unique ID: </b>" << uid
|
||||
<< "<br><b>position X/Y/Z: </b>{" << pos.x << ", " << pos.y << ", " << pos.z << "}"
|
||||
<< "<br><b>rotation X/Y/Z: </b>{" << dir.x << ", " << dir.y << ", " << dir.z << "}"
|
||||
<< "<br><b>WMO Id: </b>" << wmo->WmoId
|
||||
<< "<br><b>doodad set: </b>" << doodadset()
|
||||
<< "<br><b>name set: </b>" << mNameset
|
||||
<< "<br><b>textures used: </b>" << wmo->textures.size()
|
||||
<< "<span>";
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <noggit/ui/Checkbox.hpp>
|
||||
#include <noggit/ui/tools/UiCommon/expanderwidget.h>
|
||||
#include <util/qt/overload.hpp>
|
||||
#include <noggit/DBC.h>
|
||||
#include "noggit/ActionManager.hpp"
|
||||
#include "noggit/Action.hpp"
|
||||
|
||||
#include <QFormLayout>
|
||||
#include <QGridLayout>
|
||||
@@ -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<int>(&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<selected_object_type>(last_entry.value());
|
||||
if (obj->which() == eWMO)
|
||||
{
|
||||
// use actions or directly call updateDetailInfos() ?
|
||||
WMOInstance* wi = static_cast<WMOInstance*>(obj);
|
||||
NOGGIT_ACTION_MGR->beginAction(_map_view, Noggit::ActionFlags::eOBJECTS_TRANSFORMED);
|
||||
wi->change_doodadset(index);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(_nameSetSelector
|
||||
, qOverload<int>(&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<selected_object_type>(last_entry.value());
|
||||
if (obj->which() == eWMO)
|
||||
{
|
||||
WMOInstance* wi = static_cast<WMOInstance*>(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<selected_object_type>(last_entry.value());
|
||||
|
||||
if (obj->which() == eMODEL)
|
||||
{
|
||||
// ModelInstance* mi = static_cast<ModelInstance*>(obj);
|
||||
}
|
||||
else if (obj->which() == eWMO)
|
||||
{
|
||||
_wmo_group->setDisabled(false);
|
||||
_wmo_group->setHidden(false);
|
||||
WMOInstance* wi = static_cast<WMOInstance*>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <QSettings>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QSlider>
|
||||
#include <QtWidgets/qcombobox.h>
|
||||
#include <QtWidgets/qgroupbox.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user