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,135 +122,11 @@ 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);
|
||||
|
||||
auto map_settings_layout = new QFormLayout(map_settings_widget);
|
||||
|
||||
_directory = new QLineEdit(_map_settings);
|
||||
map_settings_layout->addRow("Map directory:", _directory);
|
||||
|
||||
_is_big_alpha = new QCheckBox(this);
|
||||
map_settings_layout->addRow("Big alpha:", _is_big_alpha);
|
||||
_is_big_alpha->setChecked(true);
|
||||
|
||||
_sort_by_size_cat = new QCheckBox(this);
|
||||
map_settings_layout->addRow("Sort models", _sort_by_size_cat);
|
||||
_sort_by_size_cat->setChecked(true);
|
||||
_sort_by_size_cat->setToolTip("Sorts models based on their size on save. May help increase loading speed of the map.");
|
||||
|
||||
|
||||
_instance_type = new QComboBox(_map_settings);
|
||||
_instance_type->addItem("None");
|
||||
_instance_type->setItemData(0, QVariant(0));
|
||||
|
||||
_instance_type->addItem("Instance");
|
||||
_instance_type->setItemData(1, QVariant(1));
|
||||
|
||||
_instance_type->addItem("Raid");
|
||||
_instance_type->setItemData(2, QVariant(2));
|
||||
|
||||
_instance_type->addItem("Battleground");
|
||||
_instance_type->setItemData(3, QVariant(3));
|
||||
|
||||
_instance_type->addItem("Arena");
|
||||
_instance_type->setItemData(4, QVariant(4));
|
||||
|
||||
map_settings_layout->addRow("Map type:",_instance_type);
|
||||
|
||||
_map_name = new LocaleDBCEntry(_map_settings);
|
||||
map_settings_layout->addRow("Map name:",_map_name);
|
||||
|
||||
_area_table_id = new QSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Area ID:",_area_table_id);
|
||||
_area_table_id->setMaximum(std::numeric_limits<std::int32_t>::max());
|
||||
|
||||
_map_desc_alliance = new LocaleDBCEntry(_map_settings);
|
||||
map_settings_layout->addRow("Description (Alliance):",_map_desc_alliance);
|
||||
|
||||
_map_desc_horde = new LocaleDBCEntry(_map_settings);
|
||||
map_settings_layout->addRow("Description (Horde):",_map_desc_horde);
|
||||
|
||||
_loading_screen = new QSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Loading screen:",_loading_screen);
|
||||
_loading_screen->setMaximum(std::numeric_limits<std::int32_t>::max());
|
||||
|
||||
_minimap_icon_scale = new QDoubleSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Minimap icon scale:",_minimap_icon_scale);
|
||||
|
||||
_corpse_map_id->setCurrentText("None");
|
||||
map_settings_layout->addRow("Corpse map:",_corpse_map_id);
|
||||
|
||||
_corpse_x = new QDoubleSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Corpse X:",_corpse_x);
|
||||
_corpse_x->setMinimum(-17066.66656); // map size
|
||||
_corpse_x->setMaximum(17066.66656);
|
||||
|
||||
_corpse_y = new QDoubleSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Corpse Y:",_corpse_y);
|
||||
_corpse_y->setMinimum(-17066.66656); // map size
|
||||
_corpse_y->setMaximum(17066.66656);
|
||||
|
||||
_time_of_day_override = new QSpinBox(_map_settings);
|
||||
_time_of_day_override->setMinimum(-1);
|
||||
_time_of_day_override->setMaximum(2880); // Time Values from 0 to 2880 where each number represents a half minute from midnight to midnight
|
||||
_time_of_day_override->setValue(-1);
|
||||
|
||||
map_settings_layout->addRow("Daytime override:",_time_of_day_override);
|
||||
|
||||
_expansion_id = new QComboBox(_map_settings);
|
||||
|
||||
_expansion_id->addItem("Classic");
|
||||
_expansion_id->setItemData(0, QVariant(0));
|
||||
|
||||
_expansion_id->addItem("Burning Crusade");
|
||||
_expansion_id->setItemData(1, QVariant(1));
|
||||
|
||||
_expansion_id->addItem("Wrath of the Lich King");
|
||||
_expansion_id->setItemData(2, QVariant(2));
|
||||
|
||||
map_settings_layout->addRow("Expansion:",_expansion_id);
|
||||
|
||||
_raid_offset = new QSpinBox(_map_settings);
|
||||
_raid_offset->setMaximum(std::numeric_limits<std::int32_t>::max());
|
||||
map_settings_layout->addRow("Raid offset:",_raid_offset);
|
||||
|
||||
_max_players = new QSpinBox(_map_settings);
|
||||
_max_players->setMaximum(std::numeric_limits<std::int32_t>::max());
|
||||
map_settings_layout->addRow("Max players:",_max_players);
|
||||
|
||||
// difficulty tab
|
||||
auto difficulty_settings_layout = new QFormLayout(map_difficulty_widget);
|
||||
_map_settings->setLayout(difficulty_settings_layout);
|
||||
|
||||
_difficulty_type = new QComboBox(_map_settings);
|
||||
_difficulty_type->setDisabled(true);
|
||||
|
||||
difficulty_settings_layout->addRow("Difficulty Index", _difficulty_type);
|
||||
|
||||
_difficulty_req_message = new LocaleDBCEntry(_map_settings);
|
||||
_difficulty_req_message->setDisabled(true); // disable them until they're actually saveable, only "display" it for now
|
||||
difficulty_settings_layout->addRow("Requirement Message", _difficulty_req_message);
|
||||
|
||||
_difficulty_raid_duration = new QSpinBox(_map_settings);
|
||||
_difficulty_raid_duration->setDisabled(true);
|
||||
_difficulty_raid_duration->setRange(0, 7);
|
||||
difficulty_settings_layout->addRow("Instance Duration(days)", _difficulty_raid_duration);
|
||||
|
||||
_difficulty_max_players = new QSpinBox(_map_settings);
|
||||
_difficulty_max_players->setDisabled(true);
|
||||
difficulty_settings_layout->addRow("Max Players", _difficulty_max_players);
|
||||
|
||||
_difficulty_string = new QLineEdit(_map_settings);
|
||||
_difficulty_string->setDisabled(true);
|
||||
difficulty_settings_layout->addRow("Difficulty String", _difficulty_string);
|
||||
|
||||
difficulty_settings_layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||
createMapSettingsTab();
|
||||
createDifficultyTab();
|
||||
createWmoEntryTab();
|
||||
|
||||
// Bottom row
|
||||
auto bottom_row_wgt = new QWidget(layout_right_holder);
|
||||
@@ -327,7 +204,7 @@ MapCreationWizard::MapCreationWizard(std::shared_ptr<Project::NoggitProject> pro
|
||||
|
||||
if (!_world->mapIndex.hasTile(TileIndex(x_final, y_final)))
|
||||
{
|
||||
if (!QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
if (!QApplication::keyboardModifiers().testFlag(Qt::ControlModifier) && !_wmoEntryTab.disableTerrain->isChecked())
|
||||
{
|
||||
_world->mapIndex.addTile(TileIndex(x_final, y_final));
|
||||
}
|
||||
@@ -349,7 +226,7 @@ MapCreationWizard::MapCreationWizard(std::shared_ptr<Project::NoggitProject> pro
|
||||
|
||||
if (!_world->mapIndex.hasTile(TileIndex(x, y)))
|
||||
{
|
||||
if (!QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
if (!QApplication::keyboardModifiers().testFlag(Qt::ControlModifier) && !_wmoEntryTab.disableTerrain->isChecked())
|
||||
{
|
||||
_world->mapIndex.addTile(TileIndex(x, y));
|
||||
}
|
||||
@@ -366,6 +243,315 @@ MapCreationWizard::MapCreationWizard(std::shared_ptr<Project::NoggitProject> pro
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
map_settings_layout->addRow("Map directory:", _directory);
|
||||
|
||||
_is_big_alpha = new QCheckBox(this);
|
||||
map_settings_layout->addRow("Big alpha:", _is_big_alpha);
|
||||
_is_big_alpha->setChecked(true);
|
||||
|
||||
_sort_by_size_cat = new QCheckBox(this);
|
||||
map_settings_layout->addRow("Sort models", _sort_by_size_cat);
|
||||
_sort_by_size_cat->setChecked(true);
|
||||
_sort_by_size_cat->setToolTip("Sorts models based on their size on save. May help increase loading speed of the map.");
|
||||
|
||||
|
||||
_instance_type = new QComboBox(_map_settings);
|
||||
_instance_type->addItem("None");
|
||||
_instance_type->setItemData(0, QVariant(0));
|
||||
|
||||
_instance_type->addItem("Instance");
|
||||
_instance_type->setItemData(1, QVariant(1));
|
||||
|
||||
_instance_type->addItem("Raid");
|
||||
_instance_type->setItemData(2, QVariant(2));
|
||||
|
||||
_instance_type->addItem("Battleground");
|
||||
_instance_type->setItemData(3, QVariant(3));
|
||||
|
||||
_instance_type->addItem("Arena");
|
||||
_instance_type->setItemData(4, QVariant(4));
|
||||
|
||||
map_settings_layout->addRow("Map type:", _instance_type);
|
||||
|
||||
_map_name = new LocaleDBCEntry(_map_settings);
|
||||
map_settings_layout->addRow("Map name:", _map_name);
|
||||
|
||||
_area_table_id = new QSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Area ID:", _area_table_id);
|
||||
_area_table_id->setMaximum(std::numeric_limits<std::int32_t>::max());
|
||||
|
||||
_map_desc_alliance = new LocaleDBCEntry(_map_settings);
|
||||
map_settings_layout->addRow("Description (Alliance):", _map_desc_alliance);
|
||||
|
||||
_map_desc_horde = new LocaleDBCEntry(_map_settings);
|
||||
map_settings_layout->addRow("Description (Horde):", _map_desc_horde);
|
||||
|
||||
_loading_screen = new QSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Loading screen:", _loading_screen);
|
||||
_loading_screen->setMaximum(std::numeric_limits<std::int32_t>::max());
|
||||
|
||||
_minimap_icon_scale = new QDoubleSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Minimap icon scale:", _minimap_icon_scale);
|
||||
|
||||
_corpse_map_id->setCurrentText("None");
|
||||
map_settings_layout->addRow("Corpse map:", _corpse_map_id);
|
||||
|
||||
_corpse_x = new QDoubleSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Corpse X:", _corpse_x);
|
||||
_corpse_x->setMinimum(-17066.66656); // map size
|
||||
_corpse_x->setMaximum(17066.66656);
|
||||
|
||||
_corpse_y = new QDoubleSpinBox(_map_settings);
|
||||
map_settings_layout->addRow("Corpse Y:", _corpse_y);
|
||||
_corpse_y->setMinimum(-17066.66656); // map size
|
||||
_corpse_y->setMaximum(17066.66656);
|
||||
|
||||
_time_of_day_override = new QSpinBox(_map_settings);
|
||||
_time_of_day_override->setMinimum(-1);
|
||||
_time_of_day_override->setMaximum(2880); // Time Values from 0 to 2880 where each number represents a half minute from midnight to midnight
|
||||
_time_of_day_override->setValue(-1);
|
||||
|
||||
map_settings_layout->addRow("Daytime override:", _time_of_day_override);
|
||||
|
||||
_expansion_id = new QComboBox(_map_settings);
|
||||
|
||||
_expansion_id->addItem("Classic");
|
||||
_expansion_id->setItemData(0, QVariant(0));
|
||||
|
||||
_expansion_id->addItem("Burning Crusade");
|
||||
_expansion_id->setItemData(1, QVariant(1));
|
||||
|
||||
_expansion_id->addItem("Wrath of the Lich King");
|
||||
_expansion_id->setItemData(2, QVariant(2));
|
||||
|
||||
map_settings_layout->addRow("Expansion:", _expansion_id);
|
||||
|
||||
_raid_offset = new QSpinBox(_map_settings);
|
||||
_raid_offset->setMaximum(std::numeric_limits<std::int32_t>::max());
|
||||
map_settings_layout->addRow("Raid offset:", _raid_offset);
|
||||
|
||||
_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");
|
||||
|
||||
auto difficulty_settings_layout = new QFormLayout(map_difficulty_widget);
|
||||
_map_settings->setLayout(difficulty_settings_layout);
|
||||
|
||||
_difficulty_type = new QComboBox(_map_settings);
|
||||
_difficulty_type->setDisabled(true);
|
||||
|
||||
difficulty_settings_layout->addRow("Difficulty Index", _difficulty_type);
|
||||
|
||||
_difficulty_req_message = new LocaleDBCEntry(_map_settings);
|
||||
_difficulty_req_message->setDisabled(true); // disable them until they're actually saveable, only "display" it for now
|
||||
difficulty_settings_layout->addRow("Requirement Message", _difficulty_req_message);
|
||||
|
||||
_difficulty_raid_duration = new QSpinBox(_map_settings);
|
||||
_difficulty_raid_duration->setDisabled(true);
|
||||
_difficulty_raid_duration->setRange(0, 7);
|
||||
difficulty_settings_layout->addRow("Instance Duration(days)", _difficulty_raid_duration);
|
||||
|
||||
_difficulty_max_players = new QSpinBox(_map_settings);
|
||||
_difficulty_max_players->setDisabled(true);
|
||||
difficulty_settings_layout->addRow("Max Players", _difficulty_max_players);
|
||||
|
||||
_difficulty_string = new QLineEdit(_map_settings);
|
||||
_difficulty_string->setDisabled(true);
|
||||
difficulty_settings_layout->addRow("Difficulty String", _difficulty_string);
|
||||
|
||||
difficulty_settings_layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||
}
|
||||
|
||||
void MapCreationWizard::createWmoEntryTab()
|
||||
{
|
||||
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);
|
||||
|
||||
_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())
|
||||
{
|
||||
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);
|
||||
|
||||
_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);
|
||||
|
||||
_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);
|
||||
|
||||
_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);
|
||||
|
||||
_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);
|
||||
|
||||
_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);
|
||||
|
||||
_wmoEntryTab.doodadSet = new QComboBox(_map_settings);
|
||||
_wmoEntryTab.doodadSet->setDisabled(true);
|
||||
connect(_wmoEntryTab.doodadSet, &QComboBox::currentTextChanged, [=](QString)
|
||||
{
|
||||
_wmoEntryTab.wmoEntry.doodadSet = _wmoEntryTab.doodadSet->currentIndex();
|
||||
});
|
||||
layout->addRow("Doodad Set:", _wmoEntryTab.doodadSet);
|
||||
|
||||
_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);
|
||||
}
|
||||
|
||||
void MapCreationWizard::populateWmoEntryTab()
|
||||
{
|
||||
_wmoEntryTab.disableTerrain->setChecked(_world->mapIndex.hasAGlobalWMO());
|
||||
if (!_world->mapIndex.hasAGlobalWMO())
|
||||
{
|
||||
_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
|
||||
{
|
||||
_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);
|
||||
}
|
||||
}
|
||||
|
||||
void MapCreationWizard::populateDoodadSet(WMOInstance& instance)
|
||||
{
|
||||
QSignalBlocker const doodadsetblocker(_wmoEntryTab.doodadSet);
|
||||
_wmoEntryTab.doodadSet->clear();
|
||||
|
||||
QStringList doodadsetnames;
|
||||
for (auto& doodad_set : instance.wmo->doodadsets)
|
||||
{
|
||||
doodadsetnames.append(doodad_set.name);
|
||||
}
|
||||
_wmoEntryTab.doodadSet->insertItems(0, doodadsetnames);
|
||||
_wmoEntryTab.doodadSet->setCurrentIndex(instance.doodadset());
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if (_instance_type->itemData(_instance_type->currentIndex()).toInt() == 1 && _difficulty_max_players->value() == 5) // dungeon
|
||||
@@ -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