5#include "../include/LevelManager.h"
31 if (
j.contains(
"x"))
v.x =
j[
"x"].get<
float>();
32 if (
j.contains(
"y"))
v.y =
j[
"y"].get<
float>();
33 if (
j.contains(
"z"))
v.z =
j[
"z"].get<
float>();
41 j[
"prefabPath"] =
e.prefabPath;
44 j[
"rotation"] =
e.rotation;
45 if (!
e.spritePath.empty()) {
46 j[
"spritePath"] =
e.spritePath;
51 if (!
e.overrides.is_null() && !
e.overrides.empty())
53 j[
"overrides"] =
e.overrides;
57 j[
"overrides"] = json::object();
63 if (
j.contains(
"id"))
e.id =
j[
"id"].get<std::string>();
64 if (
j.contains(
"prefabPath"))
e.prefabPath =
j[
"prefabPath"].get<std::string>();
65 if (
j.contains(
"name"))
e.name =
j[
"name"].get<std::string>();
66 if (
j.contains(
"type"))
e.type =
j[
"type"].get<std::string>();
67 if (
j.contains(
"rotation"))
e.rotation =
j[
"rotation"].get<
float>();
68 if (
j.contains(
"spritePath"))
e.spritePath =
j[
"spritePath"].get<std::string>();
69 if (
j.contains(
"position"))
from_json(
j[
"position"],
e.position);
70 if (
j.contains(
"overrides"))
e.overrides =
j[
"overrides"];
71 else e.overrides = json::object();
79 : m_hasUnsavedChanges(
false), m_nextEntityId(1)
89 auto now = std::chrono::system_clock::now();
90 auto time = std::chrono::system_clock::to_time_t(
now);
96 ss << std::put_time(&
timeinfo,
"%Y-%m-%dT%H:%M:%S");
98 ss << std::put_time(std::localtime(&
time),
"%Y-%m-%dT%H:%M:%S");
106 std::stringstream
ss;
131 std::ifstream
file(path);
134 std::cerr <<
"[LevelManager] Failed to open file: " << path << std::endl;
148 std::cerr <<
"[LevelManager] Failed to deserialize level data" << std::endl;
155 std::cout <<
"[LevelManager] Successfully loaded level: " << path << std::endl;
158 catch (
const std::exception&
e)
160 std::cerr <<
"[LevelManager] Exception loading level: " <<
e.what() << std::endl;
172 std::ofstream
file(path);
175 std::cerr <<
"[LevelManager] Failed to open file for writing: " << path << std::endl;
186 std::cout <<
"[LevelManager] Successfully saved level: " << path << std::endl;
189 catch (
const std::exception&
e)
191 std::cerr <<
"[LevelManager] Exception saving level: " <<
e.what() << std::endl;
206 j[
"metadata"] = json::object();
210 j[
"metadata"][
"tags"] = json::array();
213 j[
"metadata"][
"tags"].push_back(tag);
217 j[
"editorState"] = json::object();
224 j[
"data"] = json::object();
233 j[
"data"][
"entities"] = json::array();
242 j[
"data"][
"tileMap"] = json::array();
250 j[
"data"][
"tileMap"].push_back(
rowJson);
254 j[
"data"][
"collisionMap"] = json::array();
260 rowJson.push_back(
static_cast<int>(collision));
262 j[
"data"][
"collisionMap"].push_back(
rowJson);
272 if (
j.contains(
"schema_version"))
280 if (
j.contains(
"type"))
282 if (
j.contains(
"blueprintType"))
284 if (
j.contains(
"name"))
286 if (
j.contains(
"description"))
290 if (
j.contains(
"metadata"))
292 const auto& metadata =
j[
"metadata"];
293 if (metadata.contains(
"author"))
295 if (metadata.contains(
"created"))
297 if (metadata.contains(
"lastModified"))
299 if (metadata.contains(
"tags") && metadata[
"tags"].is_array())
301 const auto&
tagsArray = metadata[
"tags"];
310 if (
j.contains(
"editorState"))
312 const auto& editorState =
j[
"editorState"];
313 if (editorState.contains(
"zoom"))
315 if (editorState.contains(
"scrollOffset"))
320 if (
j.contains(
"data"))
322 const auto& data =
j[
"data"];
323 if (data.contains(
"levelName"))
325 if (data.contains(
"worldSize"))
327 if (data.contains(
"backgroundMusic"))
329 if (data.contains(
"ambientColor"))
333 if (data.contains(
"entities") && data[
"entities"].is_array())
338 auto entity = std::make_unique<EntityInstance>();
342 if (entity->id.find(
"entity_") == 0)
344 int idNum = std::stoi(entity->id.substr(7));
353 if (data.contains(
"tileMap") && data[
"tileMap"].is_array())
359 std::vector<int>
row;
363 for (
size_t x = 0; x <
rowJson.size(); ++x)
373 if (data.contains(
"collisionMap") && data[
"collisionMap"].is_array())
379 std::vector<uint8_t>
row;
383 for (
size_t x = 0; x <
rowJson.size(); ++x)
395 catch (
const std::exception&
e)
397 std::cerr <<
"[LevelManager] Exception during deserialization: " <<
e.what() << std::endl;
408 auto entity = std::make_unique<EntityInstance>();
410 entity->prefabPath = prefabPath;
411 entity->name =
"New Entity";
412 entity->position =
Vector();
413 entity->overrides = json::object();
425 [&
id](
const std::unique_ptr<EntityInstance>& entity) {
426 return entity->id == id;
440 if (entity->id ==
id)
450 std::vector<EntityInstance*>
result;
453 result.push_back(entity.get());
498 for (
int y = 0; y < height; ++y)
533 for (
int y = 0; y < height; ++y)
ComponentTypeID GetComponentTypeID_Static()
bool SaveLevel(const std::string &path)
void NewLevel(const std::string &name)
EntityInstance * CreateEntity(const std::string &prefabPath)
std::string GetCurrentTimestamp()
void ResizeTileMap(int width, int height)
std::vector< EntityInstance * > GetAllEntities()
void SetTile(int x, int y, int tileId)
std::string m_currentPath
std::string GenerateUniqueEntityId()
int GetTile(int x, int y) const
void SetCollision(int x, int y, uint8_t mask)
uint8_t GetCollision(int x, int y) const
void DeleteEntity(const std::string &id)
LevelDefinition m_levelDef
bool LoadLevel(const std::string &path)
bool DeserializeFromJson(const json &j)
bool UpdateEntityPosition(const std::string &id, const Vector &position)
void SerializeToJson(json &j) const
void ResizeCollisionMap(int width, int height)
EntityInstance * GetEntity(const std::string &id) const
void to_json(json &j, const Vector &v)
void from_json(const json &j, Vector &v)
std::vector< std::vector< int > > tileMap
std::string blueprintType
std::string backgroundMusic
std::vector< std::vector< uint8_t > > collisionMap
EditorStateData editorState
std::vector< std::unique_ptr< EntityInstance > > entities