Allow editing WMO only maps

This commit is contained in:
DennisWG
2024-09-08 17:50:34 +00:00
committed by T1ti
parent 619bc0b0bb
commit 52298c338d
8 changed files with 515 additions and 136 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -26,6 +26,10 @@
namespace Noggit
{
namespace Ui
{
class Vector3fWidget;
}
namespace Ui::Tools::MapCreationWizard::Ui
{
@@ -98,7 +102,22 @@ namespace Noggit
void map_dbc_updated(int new_map = 0);
private:
std::shared_ptr<Project::NoggitProject> _project;
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;
QGroupBox* _map_settings;
@@ -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);
};
}
}

View 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]);
}
}

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

View File

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