summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorilotterytea <iltsu@alright.party>2025-02-02 22:41:32 +0500
committerilotterytea <iltsu@alright.party>2025-02-02 22:41:32 +0500
commitf27bf2dfa4975c7366013bb2f729a9823105361c (patch)
tree47938d971e1bebb36765fdd44ed37680147e87b9
parent4466b394cbdd584d70f83024852a710a6460212e (diff)
feat: export package
-rw-r--r--src/editor.cpp91
-rw-r--r--src/editor.hpp7
-rw-r--r--src/level.cpp40
-rw-r--r--src/level.hpp4
-rw-r--r--src/package.cpp50
-rw-r--r--src/package.hpp5
-rw-r--r--src/sets/tileset.hpp15
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