#pragma once #include #include #include #include #include #include "external/nlohmann/json.hpp" #include "ISaveable.h" namespace ZL { // Animation task for timed position/rotation/scale/alpha transitions. // Moved here from InteractiveObject so InteractiveObjectState can own it. struct AnimTask { enum class Type { Move, Rotate, Scale, Fade } type; Eigen::Vector3f startPos; float startRotY = 0.f; float startScale = 1.f; Eigen::Vector3f targetPos; float targetRotY = 0.f; float targetScale = 1.f; float durationMs = 1000.f; float elapsedMs = 0.f; std::function onComplete; // non-serializable; re-wired at runtime by Lua callbacks }; // Paths and baked mesh transforms needed to recreate a LoadedGameObject from disk. struct LoadedGameObjectState { std::string texturePath; std::string textureDarkandsPath; std::string meshPath; float meshRotationX = 0.f; float meshRotationY = 0.f; float meshRotationZ = 0.f; float meshScale = 1.f; }; // 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 : public ISaveable { public: // --- Creation info (fixed at load time) --- LoadedGameObjectState objectInfo; float interactionRadius = 2.f; float approachRadius = 2.f; Eigen::Vector3f pivot = Eigen::Vector3f::Zero(); Eigen::Vector3f boundsMin = Eigen::Vector3f::Zero(); Eigen::Vector3f boundsMax = Eigen::Vector3f::Zero(); bool hasInteractionPosition = false; Eigen::Vector3f interactionPosition = Eigen::Vector3f::Zero(); bool castShadow = true; bool castShadowNight = true; std::string activateFunctionName; // Original JSON position before mesh-centering offset — needed for re-serialization. float jsonPositionX = 0.f; float jsonPositionY = 0.f; float jsonPositionZ = 0.f; // --- Runtime mutable state --- Eigen::Vector3f position = Eigen::Vector3f::Zero(); float rotationY = 0.f; float scale = 1.f; float alpha = 1.f; bool isActive = true; bool isAnimating = false; std::optional animTask; // --- Serialisation (runtime mutable fields only) --- void save(nlohmann::json& out) const override; void load(const nlohmann::json& in) override; }; } // namespace ZL