Working on save-load system and UI

This commit is contained in:
Vladislav Khorev committed 2026-06-20 21:41:07 +03:00
1 parent 901142385d
commit d7db0faea3
29 files changed
+708 -180

No files matched your search

+36 -5
View File
@@ -67,7 +67,6 @@ namespace ZL {
obj.state.jsonPositionY,
obj.state.jsonPositionZ);
}
return obj;
}
@@ -239,8 +238,25 @@ namespace ZL {
out["scale"] = scale;
out["alpha"] = alpha;
out["isActive"] = isActive;
// isAnimating and animTask are not saved: animations snap to their end
// state on load (the final position/scale/alpha is already in the fields above).
out["isAnimating"] = isAnimating;
if (isAnimating && animTask.has_value()) {
nlohmann::json at;
at["type"] = static_cast<int>(animTask->type);
at["startPosX"] = animTask->startPos.x();
at["startPosY"] = animTask->startPos.y();
at["startPosZ"] = animTask->startPos.z();
at["startRotY"] = animTask->startRotY;
at["startScale"] = animTask->startScale;
at["targetPosX"] = animTask->targetPos.x();
at["targetPosY"] = animTask->targetPos.y();
at["targetPosZ"] = animTask->targetPos.z();
at["targetRotY"] = animTask->targetRotY;
at["targetScale"] = animTask->targetScale;
at["durationMs"] = animTask->durationMs;
at["elapsedMs"] = animTask->elapsedMs;
out["animTask"] = std::move(at);
}
}
void InteractiveObjectState::load(const nlohmann::json& in)
@@ -252,9 +268,24 @@ namespace ZL {
scale = in.value("scale", scale);
alpha = in.value("alpha", alpha);
isActive = in.value("isActive", isActive);
// Cancel any in-flight animation; state was restored to final values above.
isAnimating = false;
isAnimating = in.value("isAnimating", false);
animTask.reset();
if (isAnimating && in.contains("animTask") && in["animTask"].is_object()) {
const auto& at = in["animTask"];
AnimTask task;
task.type = static_cast<AnimTask::Type>(at.value("type", 0));
task.startPos = { at.value("startPosX", 0.f), at.value("startPosY", 0.f), at.value("startPosZ", 0.f) };
task.startRotY = at.value("startRotY", 0.f);
task.startScale = at.value("startScale", 1.f);
task.targetPos = { at.value("targetPosX", 0.f), at.value("targetPosY", 0.f), at.value("targetPosZ", 0.f) };
task.targetRotY = at.value("targetRotY", 0.f);
task.targetScale = at.value("targetScale", 1.f);
task.durationMs = at.value("durationMs", 1000.f);
task.elapsedMs = at.value("elapsedMs", 0.f);
// onComplete is non-serializable; re-wired at runtime by Lua script callbacks.
animTask = std::move(task);
}
}
} // namespace ZL
+5 -4
View File
@@ -5,6 +5,7 @@
#include <Eigen/Core>
#include <Eigen/Geometry>
#include "external/nlohmann/json.hpp"
#include "ISaveable.h"
namespace ZL {
@@ -20,7 +21,7 @@ struct AnimTask {
float targetScale = 1.f;
float durationMs = 1000.f;
float elapsedMs = 0.f;
std::function<void()> onComplete; // non-serializable
std::function<void()> onComplete; // non-serializable; re-wired at runtime by Lua callbacks
};
// Paths and baked mesh transforms needed to recreate a LoadedGameObject from disk.
@@ -37,7 +38,7 @@ struct LoadedGameObjectState {
// All serializable state for an InteractiveObject: creation info + runtime mutable state.
// Mirrors CharacterState / CharacterCreationInfo but kept as a single flat class
// since interactive objects don't need the two-level separation.
class InteractiveObjectState {
class InteractiveObjectState : public ISaveable {
public:
// --- Creation info (fixed at load time) ---
LoadedGameObjectState objectInfo;
@@ -66,8 +67,8 @@ public:
std::optional<AnimTask> animTask;
// --- Serialisation (runtime mutable fields only) ---
void save(nlohmann::json& out) const;
void load(const nlohmann::json& in);
void save(nlohmann::json& out) const override;
void load(const nlohmann::json& in) override;
};
} // namespace ZL
+28
View File
@@ -1,4 +1,5 @@
#include "Item.h"
#include "external/nlohmann/json.hpp"
#include <algorithm>
#include <iostream>
@@ -25,5 +26,32 @@ namespace ZL {
[&itemId](const Item& item) { return item.id == itemId; }) != items.end();
}
void Inventory::save(nlohmann::json& out) const {
nlohmann::json arr = nlohmann::json::array();
for (const auto& item : items) {
arr.push_back({
{"id", item.id},
{"name", item.name},
{"description", item.description},
{"icon", item.icon},
{"selectedIcon", item.selectedIcon}
});
}
out["items"] = std::move(arr);
}
void Inventory::load(const nlohmann::json& in) {
items.clear();
if (!in.contains("items") || !in["items"].is_array()) return;
for (const auto& j : in["items"]) {
Item item;
item.id = j.value("id", "");
item.name = j.value("name", "");
item.description = j.value("description", "");
item.icon = j.value("icon", "");
item.selectedIcon = j.value("selectedIcon", "");
items.push_back(std::move(item));
}
}
} // namespace ZL
+6 -4
View File
@@ -3,6 +3,7 @@
#include <memory>
#include <vector>
#include <functional>
#include "ISaveable.h"
namespace ZL {
@@ -19,11 +20,9 @@ namespace ZL {
}
};
class Inventory {
private:
std::vector<Item> items;
class Inventory : public ISaveable {
public:
std::vector<Item> items;
void addItem(const Item& item);
void removeItem(const std::string& itemId);
const std::vector<Item>& getItems() const { return items; }
@@ -31,6 +30,9 @@ namespace ZL {
void clear() { items.clear(); }
size_t getCount() const { return items.size(); }
void save(nlohmann::json& out) const override;
void load(const nlohmann::json& in) override;
// Called whenever an item is added/removed; receives the item id.
std::function<void(const std::string&)> onItemAdded;
std::function<void(const std::string&)> onItemRemoved;