diff options
| author | ilotterytea <iltsu@alright.party> | 2025-02-02 22:41:32 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-02-02 22:41:32 +0500 |
| commit | f27bf2dfa4975c7366013bb2f729a9823105361c (patch) | |
| tree | 47938d971e1bebb36765fdd44ed37680147e87b9 | |
| parent | 4466b394cbdd584d70f83024852a710a6460212e (diff) | |
feat: export package
| -rw-r--r-- | src/editor.cpp | 91 | ||||
| -rw-r--r-- | src/editor.hpp | 7 | ||||
| -rw-r--r-- | src/level.cpp | 40 | ||||
| -rw-r--r-- | src/level.hpp | 4 | ||||
| -rw-r--r-- | src/package.cpp | 50 | ||||
| -rw-r--r-- | src/package.hpp | 5 | ||||
| -rw-r--r-- | src/sets/tileset.hpp | 15 |
7 files changed, 211 insertions, 1 deletions
diff --git a/src/editor.cpp b/src/editor.cpp index c97f375..985167a 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -119,6 +119,80 @@ namespace silly::editor { } } + void Editor::createSavePackageWindow(const sf::RenderWindow &window) { + sf::Vector2u windowSize = window.getSize(); + + SavePackageState &state = this->savePackageState.value(); + + ImGui::SetNextWindowPos( + ImVec2(windowSize.x / 2.0f - 160, windowSize.y / 2.0f - 70)); + ImGui::SetNextWindowSize(ImVec2(320, 140)); + ImGui::Begin("Export package...", NULL, + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize); + + std::string text_format, text_description; + + if (state.format == PACKAGE_TXT) { + text_format = "TXT"; + text_description = + "Represent level package as a .txt file\n" + "- File can be read by a human\n" + "- File can be imported to other editor\n" + "- Tileset is NOT embedded\n"; + } else { + text_format = "WTF"; + text_description = "uhhhh please make an issue about this on github"; + } + + if (ImGui::BeginCombo("Format", text_format.c_str())) { + for (int i = 0; i < 1; i++) { + bool is_selected = state.format == (LevelPackageFormat)i; + + std::string text_format; + + if (state.format == PACKAGE_TXT) { + text_format = "TXT"; + } else { + text_format = "WTF"; + } + + if (ImGui::Selectable(text_format.c_str(), is_selected)) { + state.format = (LevelPackageFormat)i; + } + + if (is_selected) ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + + ImGui::Text(text_description.c_str()); + + if (ImGui::Button("Export")) { + NFD::UniquePath outPath; + + nfdresult_t result; + + if (state.format == PACKAGE_TXT) { + result = NFD::PickFolder(outPath); + } else { + result = NFD::SaveDialog(outPath); + } + + if (result == NFD_OKAY) { + state.path = outPath.get(); + this->package.save(state.format, state.path); + ImGui::SetWindowCollapsed(true); + } + } + + if (ImGui::IsWindowCollapsed()) { + ImGui::SetWindowCollapsed(false); + this->savePackageState = std::nullopt; + } + + ImGui::End(); + } + void Editor::createNewFloor(const sf::RenderWindow &window) { if (!this->newFloorState.has_value()) { this->newFloorState = std::make_optional((NewFloorState){}); @@ -193,6 +267,15 @@ namespace silly::editor { if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMenu("File")) { + if (!pkg.get_levels().empty() && + !pkg.get_current_level().get_floors().empty()) { + if (ImGui::MenuItem("Export")) { + this->savePackageState = std::make_optional((SavePackageState){}); + } + + ImGui::Separator(); + } + if (ImGui::MenuItem("Quit")) { window.close(); } @@ -320,7 +403,8 @@ namespace silly::editor { ImGui::EndChild(); ImGui::BeginDisabled(this->newLevelState.has_value() || - this->newFloorState.has_value()); + this->newFloorState.has_value() || + this->savePackageState.has_value()); // --- TILE SELECTION --- ImGui::BeginChild("TileSelectionRegion", ImVec2(0, 400), ImGuiChildFlags_Border, @@ -438,6 +522,11 @@ namespace silly::editor { this->createNewFloor(window); return; } + + if (this->savePackageState.has_value()) { + this->createSavePackageWindow(window); + return; + } } const float Editor::get_zoom() const { return this->zoom; } diff --git a/src/editor.hpp b/src/editor.hpp index a92a6ca..0bc55d1 100644 --- a/src/editor.hpp +++ b/src/editor.hpp @@ -26,6 +26,11 @@ namespace silly::editor { int width = 10, height = 10; }; + struct SavePackageState { + std::string path; + LevelPackageFormat format; + }; + class Editor { public: Editor(LevelPackage &package) : package(package) {} @@ -38,6 +43,7 @@ namespace silly::editor { private: void createNewLevel(const sf::RenderWindow &window); void createNewFloor(const sf::RenderWindow &window); + void createSavePackageWindow(const sf::RenderWindow &window); void drawHeaderBar(sf::RenderWindow &window); LevelPackage &package; @@ -52,5 +58,6 @@ namespace silly::editor { std::optional<NewTileState> newTileState; std::optional<NewLevelState> newLevelState; std::optional<NewFloorState> newFloorState; + std::optional<SavePackageState> savePackageState; }; }
\ No newline at end of file diff --git a/src/level.cpp b/src/level.cpp index 39ac4e9..fb11881 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -93,6 +93,32 @@ namespace silly::editor { return count; } + const std::vector<TileLayer> &TileFloor::get_layers() const { + return this->layers; + } + + std::string TileFloor::export_to_string() const { + std::ostringstream oss; + + oss << "[[floor]]\n" + << "# width;height\n" + << this->width << ";" << this->height << "\n"; + + for (auto it = this->layers.begin(); it != this->layers.end(); ++it) { + oss << "[[[layer]]]\n" + << "# type\n" + << it->type << "\n" + << "# tileset_tile_id;x;y;rotation\n"; + + for (auto tt = it->tiles.begin(); tt != it->tiles.end(); ++tt) { + oss << tt->tile->id << ";" << tt->position.x << ";" << tt->position.y + << ";" << tt->rotation << "\n"; + } + } + + return oss.str(); + } + void TileLevel::add_floor(TileFloor floor) { this->floors.push_back(floor); } void TileLevel::move_to_floor(int floor_id) { @@ -112,4 +138,18 @@ namespace silly::editor { } const std::string &TileLevel::get_name() const { return this->name; } + + std::string TileLevel::export_to_string() const { + std::ostringstream oss; + + oss << "[level]\n" + << "# name\n" + << this->name << "\n"; + + for (auto it = this->floors.begin(); it != this->floors.end(); ++it) { + oss << it->export_to_string() << "\n"; + } + + return oss.str(); + } }
\ No newline at end of file diff --git a/src/level.hpp b/src/level.hpp index 711a884..a0bcb23 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -39,6 +39,8 @@ namespace silly::editor { const int get_width() const; const int get_height() const; const int get_tile_count() const; + const std::vector<TileLayer> &get_layers() const; + std::string export_to_string() const; private: int width, height; @@ -60,6 +62,8 @@ namespace silly::editor { const std::string &get_name() const; + std::string export_to_string() const; + private: const std::string name; diff --git a/src/package.cpp b/src/package.cpp index 379aaeb..e958a19 100644 --- a/src/package.cpp +++ b/src/package.cpp @@ -1,6 +1,9 @@ #include "package.hpp" #include <algorithm> +#include <filesystem> +#include <fstream> +#include <iostream> namespace silly::editor { TileSet &LevelPackage::get_tileset() { return this->tileset; } @@ -26,4 +29,51 @@ namespace silly::editor { } const std::string &LevelPackage::get_name() const { return this->name; } + + std::string LevelPackage::export_to_string() const { + std::ostringstream oss; + + // package data + oss << "[package]\n" + << "# name,version\n" + << name << "," + << "0\n"; + + // tileset data + oss << this->tileset.export_to_string() << "\n"; + + // level data + for (auto it = this->levels.begin(); it != this->levels.end(); ++it) { + oss << it->export_to_string() << "\n"; + } + + return oss.str(); + } + + void LevelPackage::save(LevelPackageFormat format, + std::string &file_path) const { + if (format != PACKAGE_TXT) { + return; + } + + // writing package file + std::stringstream pkg_file_path; + + pkg_file_path << file_path << "/" << this->name << ".txt"; + + std::string package = this->export_to_string(); + + std::ofstream ifs(pkg_file_path.str()); + ifs << package; + ifs.close(); + + // copying resource files + for (auto it = this->tileset.get_entries().begin(); + it != this->tileset.get_entries().end(); ++it) { + TilesetTile *t = it->get(); + std::string old_path = t->path; + std::string new_path = file_path + "/" + t->name + "." + t->extension; + std::filesystem::copy_file(old_path, new_path); + } + } }
\ No newline at end of file diff --git a/src/package.hpp b/src/package.hpp index 5fa957c..4e8d9d3 100644 --- a/src/package.hpp +++ b/src/package.hpp @@ -7,6 +7,8 @@ #include "sets/tileset.hpp" namespace silly::editor { + enum LevelPackageFormat { PACKAGE_TXT = 0 }; + class LevelPackage { public: LevelPackage(const std::string &name) : name(name) {} @@ -24,6 +26,9 @@ namespace silly::editor { const std::string &get_name() const; + std::string export_to_string() const; + void save(LevelPackageFormat format, std::string &file_path) const; + private: const std::string name; diff --git a/src/sets/tileset.hpp b/src/sets/tileset.hpp index 0206f1c..8562e0f 100644 --- a/src/sets/tileset.hpp +++ b/src/sets/tileset.hpp @@ -56,5 +56,20 @@ namespace silly::editor { return t.get()->id == entry.id; }))); } + + std::string export_to_string() const { + std::ostringstream oss; + + oss << "[tileset]\n" + << "# id;type;name.extension\n"; + + for (auto it = this->entries.begin(); it != this->entries.end(); ++it) { + TilesetTile *t = it->get(); + oss << std::to_string(t->id) << ";" << std::to_string(t->type) << ";" + << t->name << "." << t->extension << "\n"; + } + + return oss.str(); + } }; }
\ No newline at end of file |
