Merge branch 'wmo-stuff' into 'noggit-shadowlands'

Wmo stuff

See merge request prophecy-rp/noggit-red!23
This commit is contained in:
Intemporel
2022-12-02 18:30:21 +00:00
11 changed files with 237 additions and 10 deletions

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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()

View File

@@ -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 << "}"

View File

@@ -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);

View File

@@ -271,6 +271,8 @@ public:
std::vector<WMOLight> lights;
glm::vec4 ambient_light_color;
uint32_t WmoId;
mohd_flags flags;
std::vector<WMOFog> fogs;

View File

@@ -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>";

View File

@@ -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);
}
}
}
}
}

View File

@@ -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;

View File

@@ -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");