Allow editing WMO only maps
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
|
||||
union mcnk_flags
|
||||
{
|
||||
@@ -114,7 +116,7 @@ struct ENTRY_MODF
|
||||
uint32_t uniqueID;
|
||||
float pos[3];
|
||||
float rot[3];
|
||||
float extents[2][3];
|
||||
std::array<glm::vec3, 2> extents;
|
||||
//uint16_t flags;
|
||||
uint16_t flags;
|
||||
uint16_t doodadSet;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include <math/coordinates.hpp>
|
||||
#include <noggit/AsyncLoader.h>
|
||||
#include <noggit/MapChunk.h>
|
||||
#include <noggit/MapTile.h>
|
||||
@@ -160,6 +161,7 @@ MapIndex::MapIndex (const std::string &pBasename, int map_id, World* world,
|
||||
assert(fourcc == 'MODF');
|
||||
|
||||
theFile.read(&wmoEntry, sizeof(ENTRY_MODF));
|
||||
math::to_client(wmoEntry.pos);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
@@ -245,6 +247,11 @@ void MapIndex::save()
|
||||
{
|
||||
// MWMO
|
||||
// {
|
||||
// the game requires the path to be zero terminated!
|
||||
if(globalWMOName[globalWMOName.size() - 1] != '\0')
|
||||
{
|
||||
globalWMOName += '\0';
|
||||
}
|
||||
wdtFile.Extend(8);
|
||||
SetChunkHeader(wdtFile, curPos, 'MWMO', static_cast<int>(globalWMOName.size()));
|
||||
curPos += 8;
|
||||
@@ -259,7 +266,9 @@ void MapIndex::save()
|
||||
SetChunkHeader(wdtFile, curPos, 'MODF', sizeof(ENTRY_MODF));
|
||||
curPos += 8;
|
||||
|
||||
wdtFile.Insert(curPos, sizeof(ENTRY_MODF), (char*)&wmoEntry);
|
||||
auto entry = wmoEntry;
|
||||
math::to_server(entry.pos);
|
||||
wdtFile.Insert(curPos, sizeof(ENTRY_MODF), (char*)&entry);
|
||||
curPos += sizeof(ENTRY_MODF);
|
||||
// }
|
||||
}
|
||||
@@ -540,7 +549,7 @@ void MapIndex::saveChanged (World* world, bool save_unloaded)
|
||||
}
|
||||
}
|
||||
|
||||
bool MapIndex::hasAGlobalWMO()
|
||||
bool MapIndex::hasAGlobalWMO() const
|
||||
{
|
||||
return mHasAGlobalWMO;
|
||||
}
|
||||
@@ -1193,6 +1202,20 @@ void MapIndex::removeTile(const TileIndex &tile)
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void MapIndex::addGlobalWmo(std::string path, ENTRY_MODF entry)
|
||||
{
|
||||
mHasAGlobalWMO = true;
|
||||
globalWMOName = std::move(path);
|
||||
wmoEntry = std::move(entry);
|
||||
}
|
||||
|
||||
void MapIndex::removeGlobalWmo()
|
||||
{
|
||||
mHasAGlobalWMO = false;
|
||||
globalWMOName.clear();
|
||||
wmoEntry = {};
|
||||
}
|
||||
|
||||
unsigned MapIndex::getNumExistingTiles()
|
||||
{
|
||||
if (_n_existing_tiles >= 0)
|
||||
|
||||
@@ -213,7 +213,7 @@ public:
|
||||
void markOnDisc(const TileIndex& tile, bool mto);
|
||||
bool isTileExternal(const TileIndex& tile) const;
|
||||
|
||||
bool hasAGlobalWMO();
|
||||
bool hasAGlobalWMO() const;
|
||||
bool hasTile(const TileIndex& index) const;
|
||||
bool tileAwaitingLoading(const TileIndex& tile) const;
|
||||
bool tileLoaded(const TileIndex& tile) const;
|
||||
@@ -241,6 +241,9 @@ public:
|
||||
void saveMaxUID();
|
||||
void loadMaxUID();
|
||||
|
||||
void addGlobalWmo(std::string path, ENTRY_MODF entry);
|
||||
void removeGlobalWmo();
|
||||
|
||||
void addTile(const TileIndex& tile);
|
||||
void removeTile(const TileIndex& tile);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <noggit/ui/FontAwesome.hpp>
|
||||
#include <noggit/ui/windows/noggitWindow/NoggitWindow.hpp>
|
||||
#include <noggit/ui/widgets/Vector3Widget.hpp>
|
||||
#include <noggit/project/CurrentProject.hpp>
|
||||
#include <blizzard-database-library/include/structures/Types.h>
|
||||
#include <noggit/MapView.h>
|
||||
@@ -121,14 +122,132 @@ MapCreationWizard::MapCreationWizard(std::shared_ptr<Project::NoggitProject> pro
|
||||
|
||||
_tabs = new QTabWidget(_map_settings);
|
||||
|
||||
auto map_settings_widget(new QWidget(this));
|
||||
auto map_difficulty_widget(new QWidget(this));
|
||||
|
||||
_tabs->addTab(map_settings_widget, "Map Settings");
|
||||
_tabs->addTab(map_difficulty_widget, "Map Difficulty Settings");
|
||||
|
||||
box_map_settings_layout->addWidget(_tabs);
|
||||
|
||||
createMapSettingsTab();
|
||||
createDifficultyTab();
|
||||
createWmoEntryTab();
|
||||
|
||||
// Bottom row
|
||||
auto bottom_row_wgt = new QWidget(layout_right_holder);
|
||||
auto btn_row_layout = new QHBoxLayout(layout_right_holder);
|
||||
bottom_row_wgt->setLayout(btn_row_layout);
|
||||
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);
|
||||
save_btn->setAccessibleName("map_wizard_save_button");
|
||||
discard_btn->setAccessibleName("map_wizard_discard_button");
|
||||
|
||||
layout_right->addWidget(bottom_row_wgt);
|
||||
|
||||
// Connections
|
||||
|
||||
connect(save_btn, &QPushButton::clicked
|
||||
,[&] ()
|
||||
{
|
||||
saveCurrentEntry();
|
||||
});
|
||||
|
||||
connect(discard_btn, &QPushButton::clicked
|
||||
,[&] ()
|
||||
{
|
||||
discardChanges();
|
||||
});
|
||||
|
||||
connect(add_btn, &QPushButton::clicked
|
||||
,[&] ()
|
||||
{
|
||||
addNewMap();
|
||||
});
|
||||
|
||||
connect(remove_btn, &QPushButton::clicked
|
||||
,[&] ()
|
||||
{
|
||||
removeMap();
|
||||
});
|
||||
|
||||
_connection = connect(reinterpret_cast<Noggit::Ui::Windows::NoggitWindow*>(parent),
|
||||
QOverload<int>::of(&Noggit::Ui::Windows::NoggitWindow::mapSelected)
|
||||
, [&] (int index)
|
||||
{
|
||||
selectMap(index);
|
||||
}
|
||||
);
|
||||
|
||||
connect(_difficulty_type, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
selectMapDifficulty();
|
||||
});
|
||||
|
||||
// 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)
|
||||
{
|
||||
int x_final = x + i;
|
||||
int y_final = y + j;
|
||||
|
||||
if (x_final < 0 || x_final > 63 || y_final < 0 || y_final > 63)
|
||||
continue;
|
||||
|
||||
if (!_world->mapIndex.hasTile(TileIndex(x_final, y_final)))
|
||||
{
|
||||
if (!QApplication::keyboardModifiers().testFlag(Qt::ControlModifier) && !_wmoEntryTab.disableTerrain->isChecked())
|
||||
{
|
||||
_world->mapIndex.addTile(TileIndex(x_final, y_final));
|
||||
}
|
||||
}
|
||||
else if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
{
|
||||
_world->mapIndex.removeTile(TileIndex(x_final, y_final));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = tile.x();
|
||||
int y = tile.y();
|
||||
|
||||
if (x < 0 || x > 63 || y < 0 || y > 63)
|
||||
return;
|
||||
|
||||
if (!_world->mapIndex.hasTile(TileIndex(x, y)))
|
||||
{
|
||||
if (!QApplication::keyboardModifiers().testFlag(Qt::ControlModifier) && !_wmoEntryTab.disableTerrain->isChecked())
|
||||
{
|
||||
_world->mapIndex.addTile(TileIndex(x, y));
|
||||
}
|
||||
}
|
||||
else if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
{
|
||||
_world->mapIndex.removeTile(TileIndex(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void MapCreationWizard::createMapSettingsTab()
|
||||
{
|
||||
auto map_settings_widget(new QWidget(this));
|
||||
_tabs->addTab(map_settings_widget, "Map Settings");
|
||||
|
||||
auto map_settings_layout = new QFormLayout(map_settings_widget);
|
||||
|
||||
_directory = new QLineEdit(_map_settings);
|
||||
@@ -222,8 +341,13 @@ MapCreationWizard::MapCreationWizard(std::shared_ptr<Project::NoggitProject> pro
|
||||
_max_players = new QSpinBox(_map_settings);
|
||||
_max_players->setMaximum(std::numeric_limits<std::int32_t>::max());
|
||||
map_settings_layout->addRow("Max players:", _max_players);
|
||||
}
|
||||
|
||||
void MapCreationWizard::createDifficultyTab()
|
||||
{
|
||||
auto map_difficulty_widget(new QWidget(this));
|
||||
_tabs->addTab(map_difficulty_widget, "Map Difficulty Settings");
|
||||
|
||||
// difficulty tab
|
||||
auto difficulty_settings_layout = new QFormLayout(map_difficulty_widget);
|
||||
_map_settings->setLayout(difficulty_settings_layout);
|
||||
|
||||
@@ -250,120 +374,182 @@ MapCreationWizard::MapCreationWizard(std::shared_ptr<Project::NoggitProject> pro
|
||||
difficulty_settings_layout->addRow("Difficulty String", _difficulty_string);
|
||||
|
||||
difficulty_settings_layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||
}
|
||||
|
||||
// Bottom row
|
||||
auto bottom_row_wgt = new QWidget(layout_right_holder);
|
||||
auto btn_row_layout = new QHBoxLayout(layout_right_holder);
|
||||
bottom_row_wgt->setLayout(btn_row_layout);
|
||||
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);
|
||||
save_btn->setAccessibleName("map_wizard_save_button");
|
||||
discard_btn->setAccessibleName("map_wizard_discard_button");
|
||||
|
||||
layout_right->addWidget(bottom_row_wgt);
|
||||
|
||||
// Connections
|
||||
|
||||
connect(save_btn, &QPushButton::clicked
|
||||
,[&] ()
|
||||
void MapCreationWizard::createWmoEntryTab()
|
||||
{
|
||||
saveCurrentEntry();
|
||||
auto wmo_widget(new QWidget(this));
|
||||
_tabs->addTab(wmo_widget, "WMO Entry");
|
||||
|
||||
auto layout = new QFormLayout(wmo_widget);
|
||||
_map_settings->setLayout(layout);
|
||||
|
||||
_wmoEntryTab.disableTerrain = new QCheckBox(_map_settings);
|
||||
_wmoEntryTab.disableTerrain->setChecked(false);
|
||||
connect(_wmoEntryTab.disableTerrain, &QCheckBox::toggled, [=](bool state) {
|
||||
_wmoEntryTab.wmoPath->setDisabled(!state);
|
||||
// Is there any value in exposing these?
|
||||
//_wmoEntryTab.nameId->setDisabled(!state);
|
||||
//_wmoEntryTab.uniqueId->setDisabled(!state);
|
||||
_wmoEntryTab.position->setDisabled(!state);
|
||||
_wmoEntryTab.rotation->setDisabled(!state);
|
||||
//_wmoEntryTab.flags->setDisabled(!state);
|
||||
_wmoEntryTab.doodadSet->setDisabled(!state);
|
||||
_wmoEntryTab.nameSet->setDisabled(!state);
|
||||
});
|
||||
layout->addRow("WMO only (disable terrain):", _wmoEntryTab.disableTerrain);
|
||||
|
||||
connect(discard_btn, &QPushButton::clicked
|
||||
,[&] ()
|
||||
_wmoEntryTab.wmoPath = new QLineEdit(_map_settings);
|
||||
_wmoEntryTab.wmoPath->setDisabled(true);
|
||||
auto defaultStylesheet = _wmoEntryTab.wmoPath->styleSheet();
|
||||
connect(_wmoEntryTab.wmoPath, &QLineEdit::textChanged, [=](QString text) {
|
||||
if (!_wmoEntryTab.disableTerrain->isChecked())
|
||||
{
|
||||
discardChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
_world->mWmoFilename = text.toStdString();
|
||||
WMOInstance wmo{ _world->mWmoFilename, _world->getRenderContext() };
|
||||
wmo.wmo->wait_until_loaded();
|
||||
if (!wmo.finishedLoading() || wmo.wmo->loading_failed())
|
||||
{
|
||||
_wmoEntryTab.wmoPath->setStyleSheet("QLineEdit { background-color : red; }");
|
||||
return;
|
||||
}
|
||||
|
||||
_wmoEntryTab.wmoEntry.extents = wmo.getExtents();
|
||||
_wmoEntryTab.wmoPath->setStyleSheet(defaultStylesheet);
|
||||
populateDoodadSet(wmo);
|
||||
populateNameSet(wmo);
|
||||
});
|
||||
layout->addRow("Path:", _wmoEntryTab.wmoPath);
|
||||
|
||||
connect(add_btn, &QPushButton::clicked
|
||||
,[&] ()
|
||||
{
|
||||
addNewMap();
|
||||
_wmoEntryTab.nameId = new QSpinBox(_map_settings);
|
||||
_wmoEntryTab.nameId->setDisabled(true);
|
||||
_wmoEntryTab.nameId->setMinimum(std::numeric_limits<std::int32_t>::min());
|
||||
_wmoEntryTab.nameId->setMaximum(std::numeric_limits<std::int32_t>::max());
|
||||
connect(_wmoEntryTab.nameId, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [=](int value) {
|
||||
_wmoEntryTab.wmoEntry.nameID = value;
|
||||
});
|
||||
layout->addRow("Name Id:", _wmoEntryTab.nameId);
|
||||
|
||||
connect(remove_btn, &QPushButton::clicked
|
||||
,[&] ()
|
||||
{
|
||||
removeMap();
|
||||
_wmoEntryTab.uniqueId = new QSpinBox(_map_settings);
|
||||
_wmoEntryTab.uniqueId->setDisabled(true);
|
||||
_wmoEntryTab.uniqueId->setMinimum(std::numeric_limits<std::int32_t>::min());
|
||||
_wmoEntryTab.uniqueId->setMaximum(std::numeric_limits<std::int32_t>::max());
|
||||
connect(_wmoEntryTab.uniqueId, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [=](int value) {
|
||||
_wmoEntryTab.wmoEntry.uniqueID = value;
|
||||
});
|
||||
layout->addRow("Unique Id:", _wmoEntryTab.uniqueId);
|
||||
|
||||
_connection = connect(reinterpret_cast<Noggit::Ui::Windows::NoggitWindow*>(parent),
|
||||
QOverload<int>::of(&Noggit::Ui::Windows::NoggitWindow::mapSelected)
|
||||
, [&] (int index)
|
||||
{
|
||||
selectMap(index);
|
||||
}
|
||||
);
|
||||
|
||||
connect(_difficulty_type, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
selectMapDifficulty();
|
||||
_wmoEntryTab.position = new Vector3fWidget(_map_settings);
|
||||
_wmoEntryTab.position->setDisabled(true);
|
||||
connect(_wmoEntryTab.position, &Vector3fWidget::valueChanged , [=](glm::vec3 const& value) {
|
||||
_wmoEntryTab.wmoEntry.pos[0] = value.x;
|
||||
_wmoEntryTab.wmoEntry.pos[1] = value.y;
|
||||
_wmoEntryTab.wmoEntry.pos[2] = value.z;
|
||||
});
|
||||
layout->addRow("Position:", _wmoEntryTab.position);
|
||||
|
||||
// Selection
|
||||
_wmoEntryTab.rotation = new Vector3fWidget(_map_settings);
|
||||
_wmoEntryTab.rotation->setDisabled(true);
|
||||
connect(_wmoEntryTab.rotation, &Vector3fWidget::valueChanged, [=](glm::vec3 const& value) {
|
||||
_wmoEntryTab.wmoEntry.rot[0] = value.x;
|
||||
_wmoEntryTab.wmoEntry.rot[1] = value.y;
|
||||
_wmoEntryTab.wmoEntry.rot[2] = value.z;
|
||||
});
|
||||
layout->addRow("Rotation:", _wmoEntryTab.rotation);
|
||||
|
||||
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;
|
||||
_wmoEntryTab.flags = new QSpinBox(_map_settings);
|
||||
_wmoEntryTab.flags->setDisabled(true);
|
||||
_wmoEntryTab.flags->setMinimum(std::numeric_limits<std::uint16_t>::min());
|
||||
_wmoEntryTab.flags->setMaximum(std::numeric_limits<std::uint16_t>::max());
|
||||
connect(_wmoEntryTab.flags, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [=](int value) {
|
||||
_wmoEntryTab.wmoEntry.flags = static_cast<uint16_t>(value);
|
||||
});
|
||||
layout->addRow("Flags:", _wmoEntryTab.flags);
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
_wmoEntryTab.doodadSet = new QComboBox(_map_settings);
|
||||
_wmoEntryTab.doodadSet->setDisabled(true);
|
||||
connect(_wmoEntryTab.doodadSet, &QComboBox::currentTextChanged, [=](QString)
|
||||
{
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
int x_final = x + i;
|
||||
int y_final = y + j;
|
||||
_wmoEntryTab.wmoEntry.doodadSet = _wmoEntryTab.doodadSet->currentIndex();
|
||||
});
|
||||
layout->addRow("Doodad Set:", _wmoEntryTab.doodadSet);
|
||||
|
||||
if (x_final < 0 || x_final > 63 || y_final < 0 || y_final > 63)
|
||||
continue;
|
||||
_wmoEntryTab.nameSet = new QComboBox(_map_settings);
|
||||
_wmoEntryTab.nameSet->setDisabled(true);
|
||||
connect(_wmoEntryTab.nameSet, &QComboBox::currentTextChanged, [=](QString)
|
||||
{
|
||||
_wmoEntryTab.wmoEntry.nameSet = _wmoEntryTab.nameSet->currentIndex();
|
||||
});
|
||||
layout->addRow("Name set:", _wmoEntryTab.nameSet);
|
||||
}
|
||||
|
||||
if (!_world->mapIndex.hasTile(TileIndex(x_final, y_final)))
|
||||
void MapCreationWizard::populateWmoEntryTab()
|
||||
{
|
||||
if (!QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
_wmoEntryTab.disableTerrain->setChecked(_world->mapIndex.hasAGlobalWMO());
|
||||
if (!_world->mapIndex.hasAGlobalWMO())
|
||||
{
|
||||
_world->mapIndex.addTile(TileIndex(x_final, y_final));
|
||||
}
|
||||
}
|
||||
else if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
{
|
||||
_world->mapIndex.removeTile(TileIndex(x_final, y_final));
|
||||
}
|
||||
}
|
||||
}
|
||||
_wmoEntryTab.wmoPath->clear();
|
||||
_wmoEntryTab.nameId->clear();
|
||||
_wmoEntryTab.uniqueId->clear();
|
||||
_wmoEntryTab.position->clear();
|
||||
_wmoEntryTab.rotation->clear();
|
||||
_wmoEntryTab.flags->clear();
|
||||
_wmoEntryTab.doodadSet->clear();
|
||||
_wmoEntryTab.nameSet->clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = tile.x();
|
||||
int y = tile.y();
|
||||
_wmoEntryTab.wmoPath->setText(QString::fromStdString(_world->mWmoFilename));
|
||||
_wmoEntryTab.wmoEntry = _world->mWmoEntry;
|
||||
_wmoEntryTab.nameId->setValue(_wmoEntryTab.wmoEntry.nameID);
|
||||
_wmoEntryTab.uniqueId->setValue(_wmoEntryTab.wmoEntry.uniqueID);
|
||||
_wmoEntryTab.position->setValue(_wmoEntryTab.wmoEntry.pos);
|
||||
_wmoEntryTab.rotation->setValue(_wmoEntryTab.wmoEntry.rot);
|
||||
_wmoEntryTab.flags->setValue(_wmoEntryTab.wmoEntry.flags);
|
||||
_wmoEntryTab.doodadSet->setCurrentIndex(_wmoEntryTab.wmoEntry.doodadSet);
|
||||
_wmoEntryTab.nameSet->setCurrentIndex(_wmoEntryTab.wmoEntry.nameSet);
|
||||
}
|
||||
}
|
||||
|
||||
if (x < 0 || x > 63 || y < 0 || y > 63)
|
||||
return;
|
||||
|
||||
if (!_world->mapIndex.hasTile(TileIndex(x, y)))
|
||||
void MapCreationWizard::populateDoodadSet(WMOInstance& instance)
|
||||
{
|
||||
if (!QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
QSignalBlocker const doodadsetblocker(_wmoEntryTab.doodadSet);
|
||||
_wmoEntryTab.doodadSet->clear();
|
||||
|
||||
QStringList doodadsetnames;
|
||||
for (auto& doodad_set : instance.wmo->doodadsets)
|
||||
{
|
||||
_world->mapIndex.addTile(TileIndex(x, y));
|
||||
}
|
||||
}
|
||||
else if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
{
|
||||
_world->mapIndex.removeTile(TileIndex(x, y));
|
||||
doodadsetnames.append(doodad_set.name);
|
||||
}
|
||||
_wmoEntryTab.doodadSet->insertItems(0, doodadsetnames);
|
||||
_wmoEntryTab.doodadSet->setCurrentIndex(instance.doodadset());
|
||||
}
|
||||
|
||||
update();
|
||||
void MapCreationWizard::populateNameSet(WMOInstance& instance)
|
||||
{
|
||||
// get names from WMOAreatable, if no name, get from areatable
|
||||
// if no areatable, we have to get the terrain's area
|
||||
QSignalBlocker const namesetblocker(_wmoEntryTab.nameSet);
|
||||
_wmoEntryTab.nameSet->clear();
|
||||
auto wmoid = instance.wmo->WmoId;
|
||||
auto setnames = gWMOAreaTableDB.getWMOAreaNames(wmoid);
|
||||
QStringList namesetnames;
|
||||
for (auto& area_name : setnames)
|
||||
{
|
||||
if (area_name.empty())
|
||||
{
|
||||
auto chunk = _world->getChunkAt(instance.pos);
|
||||
namesetnames.append(gAreaDB.getAreaFullName(chunk->getAreaID()).c_str());
|
||||
}
|
||||
else
|
||||
namesetnames.append(area_name.c_str());
|
||||
}
|
||||
);
|
||||
|
||||
_wmoEntryTab.nameSet->insertItems(0, namesetnames);
|
||||
_wmoEntryTab.nameSet->setCurrentIndex(instance.mNameset);
|
||||
}
|
||||
|
||||
std::string MapCreationWizard::getDifficultyString()
|
||||
@@ -518,6 +704,8 @@ void MapCreationWizard::selectMap(int map_id)
|
||||
_project->ClientDatabase->UnloadTable("MapDifficulty");
|
||||
_difficulty_type->setCurrentIndex(0);
|
||||
selectMapDifficulty();
|
||||
|
||||
populateWmoEntryTab();
|
||||
}
|
||||
|
||||
void MapCreationWizard::selectMapDifficulty()
|
||||
@@ -633,6 +821,14 @@ void MapCreationWizard::saveCurrentEntry()
|
||||
_world->mapIndex.setBigAlpha(_is_big_alpha->isChecked());
|
||||
_world->setBasename(_directory->text().toStdString());
|
||||
_world->mapIndex.set_sort_models_by_size_class(_sort_by_size_cat->isChecked());
|
||||
if (_wmoEntryTab.disableTerrain->isChecked())
|
||||
{
|
||||
_world->mapIndex.addGlobalWmo(_wmoEntryTab.wmoPath->text().toStdString(), _wmoEntryTab.wmoEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
_world->mapIndex.removeGlobalWmo();
|
||||
}
|
||||
_world->mapIndex.saveChanged(_world, true);
|
||||
_world->mapIndex.save(); // save wdt file
|
||||
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class Vector3fWidget;
|
||||
}
|
||||
|
||||
namespace Ui::Tools::MapCreationWizard::Ui
|
||||
{
|
||||
@@ -98,6 +102,21 @@ namespace Noggit
|
||||
void map_dbc_updated(int new_map = 0);
|
||||
|
||||
private:
|
||||
struct WmoEntryTab
|
||||
{
|
||||
QCheckBox* disableTerrain = nullptr;
|
||||
QLineEdit* wmoPath = nullptr;
|
||||
QSpinBox* nameId = nullptr;
|
||||
QSpinBox* uniqueId = nullptr;
|
||||
Vector3fWidget* position = nullptr;
|
||||
Vector3fWidget* rotation = nullptr;
|
||||
QSpinBox* flags = nullptr;
|
||||
QComboBox* doodadSet = nullptr;
|
||||
QComboBox* nameSet = nullptr;
|
||||
|
||||
ENTRY_MODF wmoEntry;
|
||||
};
|
||||
|
||||
std::shared_ptr<Project::NoggitProject> _project;
|
||||
Noggit::Ui::minimap_widget* _minimap_widget;
|
||||
int _selected_map;
|
||||
@@ -139,6 +158,8 @@ namespace Noggit
|
||||
QSpinBox* _difficulty_max_players;
|
||||
QLineEdit* _difficulty_string;
|
||||
|
||||
WmoEntryTab _wmoEntryTab;
|
||||
|
||||
World* _world = nullptr;
|
||||
|
||||
bool _is_new_record = false;
|
||||
@@ -156,6 +177,13 @@ namespace Noggit
|
||||
|
||||
void removeMap();
|
||||
|
||||
void createMapSettingsTab();
|
||||
void createDifficultyTab();
|
||||
void createWmoEntryTab();
|
||||
|
||||
void populateWmoEntryTab();
|
||||
void populateDoodadSet(WMOInstance& instance);
|
||||
void populateNameSet(WMOInstance& instance);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
87
src/noggit/ui/widgets/Vector3Widget.cpp
Normal file
87
src/noggit/ui/widgets/Vector3Widget.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
#include "Vector3Widget.hpp"
|
||||
#include <noggit/MapHeaders.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
namespace Noggit::Ui
|
||||
{
|
||||
Vector3fWidget::Vector3fWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
constexpr int spacing = 8;
|
||||
|
||||
_layout = new QHBoxLayout(this);
|
||||
_layout->setContentsMargins(0, 0, 0, 0);
|
||||
_layout->setSpacing(0);
|
||||
|
||||
_xLabel = new QLabel("X", this);
|
||||
_xLabel->setStyleSheet("QLabel { background-color : red; color : white; }");
|
||||
_xLabel->setMaximumWidth(14);
|
||||
_xLabel->setAlignment(Qt::AlignCenter);
|
||||
_layout->addWidget(_xLabel);
|
||||
|
||||
_xSpinbox = new QDoubleSpinBox(this);
|
||||
_xSpinbox->setMinimum(0);
|
||||
_xSpinbox->setMaximum(ZEROPOINT * 2);
|
||||
connect(_xSpinbox, &QDoubleSpinBox::textChanged, [=](auto) {
|
||||
emit valueChanged({
|
||||
static_cast<float>(_xSpinbox->value()),
|
||||
static_cast<float>(_ySpinbox->value()),
|
||||
static_cast<float>(_zSpinbox->value()) });
|
||||
});
|
||||
_layout->addWidget(_xSpinbox);
|
||||
_layout->addSpacing(spacing);
|
||||
|
||||
_yLabel = new QLabel("Y", this);
|
||||
_yLabel->setStyleSheet("QLabel { background-color : green; color : white; }");
|
||||
_yLabel->setMaximumWidth(14);
|
||||
_yLabel->setAlignment(Qt::AlignCenter);
|
||||
_layout->addWidget(_yLabel);
|
||||
|
||||
_ySpinbox = new QDoubleSpinBox(this);
|
||||
_ySpinbox->setMinimum(0);
|
||||
_ySpinbox->setMaximum(ZEROPOINT * 2);
|
||||
connect(_ySpinbox, &QDoubleSpinBox::textChanged, [=](auto) {
|
||||
emit valueChanged({
|
||||
static_cast<float>(_xSpinbox->value()),
|
||||
static_cast<float>(_ySpinbox->value()),
|
||||
static_cast<float>(_zSpinbox->value()) });
|
||||
});
|
||||
_layout->addWidget(_ySpinbox);
|
||||
_layout->addSpacing(spacing);
|
||||
|
||||
_zLabel = new QLabel("Z", this);
|
||||
_zLabel->setStyleSheet("QLabel { background-color : blue; color : white; }");
|
||||
_zLabel->setMaximumWidth(14);
|
||||
_zLabel->setAlignment(Qt::AlignCenter);
|
||||
_layout->addWidget(_zLabel);
|
||||
|
||||
_zSpinbox = new QDoubleSpinBox(this);
|
||||
_zSpinbox->setMinimum(0);
|
||||
_zSpinbox->setMaximum(ZEROPOINT * 2);
|
||||
connect(_zSpinbox, &QDoubleSpinBox::textChanged, [=](auto) {
|
||||
emit valueChanged({
|
||||
static_cast<float>(_xSpinbox->value()),
|
||||
static_cast<float>(_ySpinbox->value()),
|
||||
static_cast<float>(_zSpinbox->value()) });
|
||||
});
|
||||
_layout->addWidget(_zSpinbox);
|
||||
}
|
||||
|
||||
void Vector3fWidget::clear()
|
||||
{
|
||||
_xSpinbox->clear();
|
||||
_ySpinbox->clear();
|
||||
_zSpinbox->clear();
|
||||
}
|
||||
|
||||
void Vector3fWidget::setValue(float value[3])
|
||||
{
|
||||
_xSpinbox->setValue(value[0]);
|
||||
_ySpinbox->setValue(value[1]);
|
||||
_zSpinbox->setValue(value[2]);
|
||||
}
|
||||
}
|
||||
39
src/noggit/ui/widgets/Vector3Widget.hpp
Normal file
39
src/noggit/ui/widgets/Vector3Widget.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
#pragma once
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
class QHBoxLayout;
|
||||
class QDoubleSpinBox;
|
||||
|
||||
namespace Noggit::Ui
|
||||
{
|
||||
class Vector3fWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Vector3fWidget(QWidget* parent = nullptr);
|
||||
|
||||
void clear();
|
||||
|
||||
void setValue(float value[3]);
|
||||
|
||||
signals:
|
||||
void valueChanged(glm::vec3 const& value);
|
||||
|
||||
private:
|
||||
glm::vec3 _vector = {};
|
||||
|
||||
QHBoxLayout* _layout = nullptr;
|
||||
QLabel* _xLabel = nullptr;
|
||||
QLabel* _yLabel = nullptr;
|
||||
QLabel* _zLabel = nullptr;
|
||||
|
||||
QDoubleSpinBox* _xSpinbox = nullptr;
|
||||
QDoubleSpinBox* _ySpinbox = nullptr;
|
||||
QDoubleSpinBox* _zSpinbox = nullptr;
|
||||
};
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <noggit/ui/windows/noggitWindow/components/BuildMapListComponent.hpp>
|
||||
#include <noggit/application/Utils.hpp>
|
||||
#include <noggit/application/NoggitApplication.hpp>
|
||||
#include <math/coordinates.hpp>
|
||||
#include <BlizzardDatabase.h>
|
||||
#include <QtGui/QCloseEvent>
|
||||
#include <QtWidgets/QHBoxLayout>
|
||||
@@ -211,12 +212,12 @@ namespace Noggit::Ui::Windows
|
||||
float dy = min_extent.z - max_extent.z; // flipping z and y works better for some reason
|
||||
float dz = min_extent.y - max_extent.y;
|
||||
|
||||
pos = max_extent;
|
||||
pos = { _world->mWmoEntry.pos[0], _world->mWmoEntry.pos[1], _world->mWmoEntry.pos[2] };
|
||||
|
||||
camera_yaw = math::degrees(math::radians(std::atan2(dx, dy)));
|
||||
|
||||
float distance = std::sqrt(dx * dx + dy * dy + dz * dz);
|
||||
camera_pitch = math::degrees(math::radians(std::asin(dz / distance)));
|
||||
camera_pitch = -math::degrees(math::radians(std::asin(dz / distance)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user