From 987c307cc96b7f3f12cb54a3aa7b804581985f61 Mon Sep 17 00:00:00 2001 From: Luis Michaelis Date: Mon, 4 Dec 2023 20:16:06 +0100 Subject: [PATCH] refactor(VObject): finalize migration to compliant archives --- docs/library/misc/v1.2-to-v1.3.md | 2 + examples/run_interpreter.cc | 6 +- include/phoenix/vobs/camera.hh | 5 +- include/phoenix/vobs/light.hh | 4 +- include/phoenix/vobs/misc.hh | 21 +- include/phoenix/vobs/mob.hh | 10 +- include/phoenix/vobs/sound.hh | 4 +- include/phoenix/vobs/trigger.hh | 15 +- include/phoenix/vobs/vob.hh | 2 +- include/phoenix/vobs/zone.hh | 6 +- include/zenkit/Archive.hh | 2 +- include/zenkit/Boxes.hh | 4 + include/zenkit/Object.hh | 13 +- include/zenkit/World.hh | 12 +- include/zenkit/vobs/Camera.hh | 138 ++++--- include/zenkit/vobs/Light.hh | 95 ++--- include/zenkit/vobs/Misc.hh | 562 ++++++++++++++------------- include/zenkit/vobs/MovableObject.hh | 205 +++++----- include/zenkit/vobs/Sound.hh | 86 ++-- include/zenkit/vobs/Trigger.hh | 349 +++++++++-------- include/zenkit/vobs/VirtualObject.hh | 416 +++++++++++++------- include/zenkit/vobs/Zone.hh | 135 ++++--- src/Archive.cc | 160 +++----- src/Object.cc | 4 + src/World.cc | 8 +- src/vobs/Camera.cc | 24 +- src/vobs/Light.cc | 10 +- src/vobs/Misc.cc | 62 +-- src/vobs/MovableObject.cc | 34 +- src/vobs/Sound.cc | 14 +- src/vobs/Trigger.cc | 40 +- src/vobs/VirtualObject.cc | 24 +- src/vobs/Zone.cc | 16 +- src/world/VobTree.cc | 11 - src/world/WayNet.cc | 12 +- tests/TestFont.cc | 12 +- tests/TestModelAnimation.cc | 16 +- tests/TestSaveGame.cc | 1 + tests/TestVobsG1.cc | 76 ++-- tests/TestVobsG2.cc | 94 ++--- tests/TestWorld.cc | 6 +- 41 files changed, 1420 insertions(+), 1296 deletions(-) diff --git a/docs/library/misc/v1.2-to-v1.3.md b/docs/library/misc/v1.2-to-v1.3.md index 602ac3a3..33544529 100644 --- a/docs/library/misc/v1.2-to-v1.3.md +++ b/docs/library/misc/v1.2-to-v1.3.md @@ -163,6 +163,8 @@ been polished up a bit. This is what you should do: * `atomic_message` is now `CutsceneMessage` * `script` is now `DaedalusScript` (other related classes and structs have been prefixed with `Daedalus` too) * `vm` is now `DaedalusVm` (other related classes and structs have been prefixed with `Daedalus` too) + * All classes in `phoenix::vobs` have been moved into the `zenkit` namespace and prefixed with a `V` (e.g. + `phoenix::vobs::Light` becomes `zenkit::VLight`) 4. Change all enum member accesses from their `snake_case` names to the new `SCREAMING_SNAKE_CASE` names. The deprecation warnings from your compiler should tell you these changes too. Alternatively, you can look into the old diff --git a/examples/run_interpreter.cc b/examples/run_interpreter.cc index 0d0de550..32b62baf 100644 --- a/examples/run_interpreter.cc +++ b/examples/run_interpreter.cc @@ -28,9 +28,9 @@ int main(int argc, char** argv) { return true; }); - auto xardas = vm.init_instance("NONE_100_XARDAS"); - auto hero = vm.init_instance("PC_HERO"); - auto gold = vm.init_instance("ITMI_GOLD"); + auto xardas = vm.init_instance("NONE_100_XARDAS"); + auto hero = vm.init_instance("PC_HERO"); + auto gold = vm.init_instance("ITMI_GOLD"); vm.register_external("NPC_ISPLAYER", [&hero](std::shared_ptr npc) { return npc->id == hero->id; }); diff --git a/include/phoenix/vobs/camera.hh b/include/phoenix/vobs/camera.hh index 5f3eff72..35fb51a4 100644 --- a/include/phoenix/vobs/camera.hh +++ b/include/phoenix/vobs/camera.hh @@ -5,9 +5,8 @@ namespace phoenix { namespace vobs { - using camera_trj_frame - ZKREM("renamed to zenkit::vobs::CameraTrajectoryFrame") = zenkit::vobs::CameraTrajectoryFrame; - using cs_camera ZKREM("renamed to zenkit::vobs::CutsceneCamera") = zenkit::vobs::CutsceneCamera; + using camera_trj_frame ZKREM("renamed to zenkit::VCameraTrajectoryFrame") = zenkit::VCameraTrajectoryFrame; + using cs_camera ZKREM("renamed to zenkit::VCutsceneCamera") = zenkit::VCutsceneCamera; } // namespace vobs using camera_motion ZKREM("renamed to zenkit::CameraMotion") = zenkit::CameraMotion; diff --git a/include/phoenix/vobs/light.hh b/include/phoenix/vobs/light.hh index 4b70716a..fd2ddc85 100644 --- a/include/phoenix/vobs/light.hh +++ b/include/phoenix/vobs/light.hh @@ -5,8 +5,8 @@ namespace phoenix { namespace vobs { - using light_preset ZKREM("renamed to zenkit::vobs::LightPreset") = zenkit::vobs::LightPreset; - using light ZKREM("renamed to zenkit::vobs::Light") = zenkit::vobs::Light; + using light_preset ZKREM("renamed to zenkit::VLightPreset") = zenkit::VLightPreset; + using light ZKREM("renamed to zenkit::VLight") = zenkit::VLight; } // namespace vobs using light_mode ZKREM("renamed to zenkit::LightType") = zenkit::LightType; diff --git a/include/phoenix/vobs/misc.hh b/include/phoenix/vobs/misc.hh index 8a8eb531..0b3924b6 100644 --- a/include/phoenix/vobs/misc.hh +++ b/include/phoenix/vobs/misc.hh @@ -5,17 +5,16 @@ namespace phoenix { namespace vobs { - using animate ZKREM("renamed to zenkit::vobs::Animate") = zenkit::vobs::Animate; - using item ZKREM("renamed to zenkit::vobs::Item") = zenkit::vobs::Item; - using lens_flare ZKREM("renamed to zenkit::vobs::LensFlare") = zenkit::vobs::LensFlare; - using pfx_controller - ZKREM("renamed to zenkit::vobs::ParticleEffectController") = zenkit::vobs::ParticleEffectController; - using code_master ZKREM("renamed to zenkit::vobs::CodeMaster") = zenkit::vobs::CodeMaster; - using message_filter ZKREM("renamed to zenkit::vobs::MessageFilter") = zenkit::vobs::MessageFilter; - using mover_controller ZKREM("renamed to zenkit::vobs::MoverController") = zenkit::vobs::MoverController; - using touch_damage ZKREM("renamed to zenkit::vobs::TouchDamage") = zenkit::vobs::TouchDamage; - using earthquake ZKREM("renamed to zenkit::vobs::Earthquake") = zenkit::vobs::Earthquake; - using npc ZKREM("renamed to zenkit::vobs::Npc") = zenkit::vobs::Npc; + using animate ZKREM("renamed to zenkit::VAnimate") = zenkit::VAnimate; + using item ZKREM("renamed to zenkit::VItem") = zenkit::VItem; + using lens_flare ZKREM("renamed to zenkit::VLensFlare") = zenkit::VLensFlare; + using pfx_controller ZKREM("renamed to zenkit::VParticleEffectController") = zenkit::VParticleEffectController; + using code_master ZKREM("renamed to zenkit::VCodeMaster") = zenkit::VCodeMaster; + using message_filter ZKREM("renamed to zenkit::VMessageFilter") = zenkit::VMessageFilter; + using mover_controller ZKREM("renamed to zenkit::VMoverController") = zenkit::VMoverController; + using touch_damage ZKREM("renamed to zenkit::VTouchDamage") = zenkit::VTouchDamage; + using earthquake ZKREM("renamed to zenkit::VEarthquake") = zenkit::VEarthquake; + using npc ZKREM("renamed to zenkit::VNpc") = zenkit::VNpc; } // namespace vobs using message_filter_action ZKREM("renamed to zenkit::MessageFilterAction") = zenkit::MessageFilterAction; diff --git a/include/phoenix/vobs/mob.hh b/include/phoenix/vobs/mob.hh index 4e9e1dd5..becf16fd 100644 --- a/include/phoenix/vobs/mob.hh +++ b/include/phoenix/vobs/mob.hh @@ -5,11 +5,11 @@ namespace phoenix { namespace vobs { - using mob ZKREM("renamed to zenkit::vobs::MovableObject") = zenkit::vobs::MovableObject; - using mob_inter ZKREM("renamed to zenkit::vobs::InteractiveObject") = zenkit::vobs::InteractiveObject; - using mob_fire ZKREM("renamed to zenkit::vobs::Fire") = zenkit::vobs::Fire; - using mob_container ZKREM("renamed to zenkit::vobs::Container") = zenkit::vobs::Container; - using mob_door ZKREM("renamed to zenkit::vobs::Door") = zenkit::vobs::Door; + using mob ZKREM("renamed to zenkit::VMovableObject") = zenkit::VMovableObject; + using mob_inter ZKREM("renamed to zenkit::VInteractiveObject") = zenkit::VInteractiveObject; + using mob_fire ZKREM("renamed to zenkit::VFire") = zenkit::VFire; + using mob_container ZKREM("renamed to zenkit::VContainer") = zenkit::VContainer; + using mob_door ZKREM("renamed to zenkit::VDoor") = zenkit::VDoor; } // namespace vobs using sound_material ZKREM("renamed to zenkit::SoundMaterialType") = zenkit::SoundMaterialType; diff --git a/include/phoenix/vobs/sound.hh b/include/phoenix/vobs/sound.hh index 77d8f735..a006b432 100644 --- a/include/phoenix/vobs/sound.hh +++ b/include/phoenix/vobs/sound.hh @@ -5,8 +5,8 @@ namespace phoenix { namespace vobs { - using sound ZKREM("renamed to zenkit::vobs::Sound") = zenkit::vobs::Sound; - using sound_daytime ZKREM("renamed to zenkit::vobs::SoundDaytime") = zenkit::vobs::SoundDaytime; + using sound ZKREM("renamed to zenkit::VSound") = zenkit::VSound; + using sound_daytime ZKREM("renamed to zenkit::VSoundDaytime") = zenkit::VSoundDaytime; } // namespace vobs using sound_mode ZKREM("renamed to zenkit::SoundMode") = zenkit::SoundMode; diff --git a/include/phoenix/vobs/trigger.hh b/include/phoenix/vobs/trigger.hh index 4f495397..0f8a76cb 100644 --- a/include/phoenix/vobs/trigger.hh +++ b/include/phoenix/vobs/trigger.hh @@ -7,14 +7,13 @@ namespace phoenix { namespace vobs { - using trigger ZKREM("renamed to zenkit::vobs::Trigger") = zenkit::vobs::Trigger; - using trigger_mover ZKREM("renamed to zenkit::vobs::Mover") = zenkit::vobs::Mover; - using trigger_list ZKREM("renamed to zenkit::vobs::TriggerList") = zenkit::vobs::TriggerList; - using trigger_script ZKREM("renamed to zenkit::vobs::TriggerScript") = zenkit::vobs::TriggerScript; - using trigger_change_level - ZKREM("renamed to zenkit::vobs::TriggerChangeLevel") = zenkit::vobs::TriggerChangeLevel; - using trigger_world_start ZKREM("renamed to zenkit::vobs::TriggerWorldStart") = zenkit::vobs::TriggerWorldStart; - using trigger_untouch ZKREM("renamed to zenkit::vobs::TriggerUntouch") = zenkit::vobs::TriggerUntouch; + using trigger ZKREM("renamed to zenkit::VTrigger") = zenkit::VTrigger; + using trigger_mover ZKREM("renamed to zenkit::VMover") = zenkit::VMover; + using trigger_list ZKREM("renamed to zenkit::VTriggerList") = zenkit::VTriggerList; + using trigger_script ZKREM("renamed to zenkit::VTriggerScript") = zenkit::VTriggerScript; + using trigger_change_level ZKREM("renamed to zenkit::VTriggerChangeLevel") = zenkit::VTriggerChangeLevel; + using trigger_world_start ZKREM("renamed to zenkit::VTriggerWorldStart") = zenkit::VTriggerWorldStart; + using trigger_untouch ZKREM("renamed to zenkit::VTriggerUntouch") = zenkit::VTriggerUntouch; } // namespace vobs using mover_behavior ZKREM("renamed to zenkit::MoverBehavior") = zenkit::MoverBehavior; diff --git a/include/phoenix/vobs/vob.hh b/include/phoenix/vobs/vob.hh index 443bc569..a28a407e 100644 --- a/include/phoenix/vobs/vob.hh +++ b/include/phoenix/vobs/vob.hh @@ -4,7 +4,7 @@ #include "zenkit/vobs/VirtualObject.hh" namespace phoenix { - using vob_type ZKREM("renamed to zenkit::ObjectType") = zenkit::ObjectType; + using vob_type ZKREM("renamed to zenkit::VirtualObjectType") = zenkit::VirtualObjectType; using shadow_mode ZKREM("renamed to zenkit::ShadowType") = zenkit::ShadowType; using visual_type ZKREM("renamed to zenkit::VisualType") = zenkit::VisualType; using sprite_alignment ZKREM("renamed to zenkit::SpriteAlignment") = zenkit::SpriteAlignment; diff --git a/include/phoenix/vobs/zone.hh b/include/phoenix/vobs/zone.hh index ead08c5f..ab0c5e75 100644 --- a/include/phoenix/vobs/zone.hh +++ b/include/phoenix/vobs/zone.hh @@ -4,7 +4,7 @@ #include "zenkit/vobs/Zone.hh" namespace phoenix::vobs { - using zone_music ZKREM("renamed to zenkit::vobs::ZoneMusic") = zenkit::vobs::ZoneMusic; - using zone_far_plane ZKREM("renamed to zenkit::vobs::ZoneFarPlane") = zenkit::vobs::ZoneFarPlane; - using zone_fog ZKREM("renamed to zenkit::vobs::ZoneFog") = zenkit::vobs::ZoneFog; + using zone_music ZKREM("renamed to zenkit::VZoneMusic") = zenkit::VZoneMusic; + using zone_far_plane ZKREM("renamed to zenkit::VZoneFarPlane") = zenkit::VZoneFarPlane; + using zone_fog ZKREM("renamed to zenkit::VZoneFog") = zenkit::VZoneFog; } // namespace phoenix::vobs diff --git a/include/zenkit/Archive.hh b/include/zenkit/Archive.hh index 8f17947d..da1c06bb 100644 --- a/include/zenkit/Archive.hh +++ b/include/zenkit/Archive.hh @@ -149,7 +149,7 @@ namespace zenkit { std::enable_if_t, std::shared_ptr> // read_object(GameVersion version) { auto obj = this->read_object(version); - if (obj != nullptr && obj->get_type() != T::TYPE) { + if (obj != nullptr && obj->get_object_type() != T::TYPE) { throw ParserError {"ReadArchive", "Read unexcected object!"}; } diff --git a/include/zenkit/Boxes.hh b/include/zenkit/Boxes.hh index dd4ec420..55b9dd79 100644 --- a/include/zenkit/Boxes.hh +++ b/include/zenkit/Boxes.hh @@ -16,6 +16,10 @@ namespace zenkit { /// \brief Represents a axis-aligned bounding box (AABB) struct AxisAlignedBoundingBox { + static constexpr AxisAlignedBoundingBox zero() { + return {glm::vec3 {0}, glm::vec3 {0}}; + } + /// \brief The coordinates of the minimum corner of the bounding box. glm::vec3 min; diff --git a/include/zenkit/Object.hh b/include/zenkit/Object.hh index fe9514a8..24f9c528 100644 --- a/include/zenkit/Object.hh +++ b/include/zenkit/Object.hh @@ -69,11 +69,22 @@ namespace zenkit { zCSkyControler_Outdoor }; + constexpr bool is_vobject(ObjectType type) { + return type < ObjectType::ignored; + } + +#define ZK_OBJECT(s) \ + static constexpr ObjectType TYPE = s; \ + ObjectType get_object_type() const override { \ + return s; \ + } + class Object ZKAPI { public: Object() = default; virtual ~Object() noexcept = default; - [[nodiscard]] virtual ObjectType get_type() const = 0; + + [[nodiscard]] virtual ObjectType get_object_type() const; virtual void load(ReadArchive& r, GameVersion version); }; diff --git a/include/zenkit/World.hh b/include/zenkit/World.hh index 045fc13c..91abc22c 100644 --- a/include/zenkit/World.hh +++ b/include/zenkit/World.hh @@ -17,9 +17,7 @@ namespace phoenix { } namespace zenkit { - namespace vobs { - struct Npc; - } + struct VNpc; struct CutscenePlayer : Object { static constexpr ObjectType TYPE = ObjectType::oCCSPlayer; @@ -28,7 +26,7 @@ namespace zenkit { int32_t last_process_hour; int32_t play_list_count; - [[nodiscard]] ObjectType get_type() const override { + [[nodiscard]] ObjectType get_object_type() const override { return TYPE; } @@ -52,7 +50,7 @@ namespace zenkit { bool is_raining; int rain_ctr; - [[nodiscard]] ObjectType get_type() const override { + [[nodiscard]] ObjectType get_object_type() const override { return TYPE; } @@ -60,7 +58,7 @@ namespace zenkit { }; struct SpawnLocation { - std::shared_ptr npc; + std::shared_ptr npc; glm::vec3 position; float timer; }; @@ -136,7 +134,7 @@ namespace zenkit { WayNet world_way_net; // \note Only available in save-games, otherwise empty. - std::vector> npcs {}; + std::vector> npcs {}; std::vector npc_spawns {}; bool npc_spawn_enabled = false; int npc_spawn_flags = 0; diff --git a/include/zenkit/vobs/Camera.hh b/include/zenkit/vobs/Camera.hh index d6c5975a..29c9cdca 100644 --- a/include/zenkit/vobs/Camera.hh +++ b/include/zenkit/vobs/Camera.hh @@ -67,77 +67,69 @@ namespace zenkit { pingpong ZKREM("renamed to CameraLoop::PINGPONG") = PINGPONG, }; - namespace vobs { - /// \brief A VOb which describes the trajectory of a camera during a cutscene. - struct CameraTrajectoryFrame : VirtualObject { - static constexpr ObjectType TYPE = ObjectType::zCCamTrj_KeyFrame; - - float time; - float roll_angle; - float fov_scale; - CameraMotion motion_type; - CameraMotion motion_type_fov; - CameraMotion motion_type_roll; - CameraMotion motion_type_time_scale; - float tension; - float cam_bias; - float continuity; - float time_scale; - bool time_fixed; - glm::mat4 original_pose; - - /// \brief Parses a camera trajectory VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") - ZKAPI static std::unique_ptr parse(ReadArchive& ctx, GameVersion version); - - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } - - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - - /// \brief A VOb which defined the movement of the camera during a cutscene. - struct CutsceneCamera : VirtualObject { - CameraTrajectory trajectory_for; - CameraTrajectory target_trajectory_for; - CameraLoop loop_mode; - CameraLerpType lerp_mode; - bool ignore_for_vob_rotation; - bool ignore_for_vob_rotation_target; - bool adapt; - bool ease_first; - bool ease_last; - float total_duration; - std::string auto_focus_vob; - bool auto_player_movable; - bool auto_untrigger_last; - float auto_untrigger_last_delay; - std::int32_t position_count; - std::int32_t target_count; - - std::vector> frames; - - // Save-game only variables - bool s_paused {false}; - bool s_started {false}; - bool s_goto_time_mode {false}; - float s_cs_time {0}; - - /// \brief Parses a cutscene camera VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(CutsceneCamera& obj, ReadArchive& ctx, GameVersion version); - - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - } // namespace vobs + /// \brief A VOb which describes the trajectory of a camera during a cutscene. + struct VCameraTrajectoryFrame : VirtualObject { + ZK_OBJECT(ObjectType::zCCamTrj_KeyFrame); + + public: + float time; + float roll_angle; + float fov_scale; + CameraMotion motion_type; + CameraMotion motion_type_fov; + CameraMotion motion_type_roll; + CameraMotion motion_type_time_scale; + float tension; + float cam_bias; + float continuity; + float time_scale; + bool time_fixed; + glm::mat4 original_pose; + + /// \brief Parses a camera trajectory VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") + ZKAPI static std::unique_ptr parse(ReadArchive& ctx, GameVersion version); + + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + /// \brief A VOb which defined the movement of the camera during a cutscene. + struct VCutsceneCamera : VirtualObject { + ZK_OBJECT(ObjectType::zCCSCamera); + + public: + CameraTrajectory trajectory_for; + CameraTrajectory target_trajectory_for; + CameraLoop loop_mode; + CameraLerpType lerp_mode; + bool ignore_for_vob_rotation; + bool ignore_for_vob_rotation_target; + bool adapt; + bool ease_first; + bool ease_last; + float total_duration; + std::string auto_focus_vob; + bool auto_player_movable; + bool auto_untrigger_last; + float auto_untrigger_last_delay; + std::int32_t position_count; + std::int32_t target_count; + + std::vector> frames; + + // Save-game only variables + bool paused {false}; + bool started {false}; + bool goto_time_mode {false}; + float cs_time {0}; + + ZKREM("use ::load()") ZKAPI static void parse(VCutsceneCamera& obj, ReadArchive& ctx, GameVersion version); + + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; } // namespace zenkit diff --git a/include/zenkit/vobs/Light.hh b/include/zenkit/vobs/Light.hh index 721c5ccc..745ba02b 100644 --- a/include/zenkit/vobs/Light.hh +++ b/include/zenkit/vobs/Light.hh @@ -40,57 +40,58 @@ namespace zenkit { low ZKREM("renamed to LightQuality::LOW") = LOW, }; - namespace vobs { - /// \brief A preset for light sources. - struct LightPreset { - std::string preset {}; - LightType light_type {LightType::SPOT}; - float range {}; - glm::u8vec4 color {}; - float cone_angle {0}; - bool is_static {false}; - LightQuality quality {LightQuality::MEDIUM}; - std::string lensflare_fx {}; + /// \brief A preset for light sources. + struct LightPreset { + std::string preset {}; + LightType light_type {LightType::SPOT}; + float range {}; + glm::u8vec4 color {}; + float cone_angle {0}; + bool is_static {false}; + LightQuality quality {LightQuality::MEDIUM}; + std::string lensflare_fx {}; - bool on {false}; - std::vector range_animation_scale {}; - float range_animation_fps {0}; - bool range_animation_smooth {true}; - std::vector color_animation_list {}; - float color_animation_fps {0}; - bool color_animation_smooth {true}; - bool can_move {true}; + bool on {false}; + std::vector range_animation_scale {}; + float range_animation_fps {0}; + bool range_animation_smooth {true}; + std::vector color_animation_list {}; + float color_animation_fps {0}; + bool color_animation_smooth {true}; + bool can_move {true}; - /// \brief Parses a light preset the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - ZKREM("use ::load()") ZKAPI static void parse(LightPreset& obj, ReadArchive& ctx, GameVersion version); + /// \brief Parses a light preset the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + ZKREM("use ::load()") ZKAPI static void parse(LightPreset& obj, ReadArchive& ctx, GameVersion version); - /// \brief Parses a light preset the given *ZenGin* archive. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \return The parsed light preset. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static LightPreset parse(ReadArchive& in, GameVersion version); + /// \brief Parses a light preset the given *ZenGin* archive. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \return The parsed light preset. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static LightPreset parse(ReadArchive& in, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version); - }; + ZKAPI void load(ReadArchive& r, GameVersion version); + }; + + /// \brief A VOb which acts as a light source. + struct VLight : VirtualObject, LightPreset { + ZK_OBJECT(ObjectType::zCVobLight); - /// \brief A VOb which acts as a light source. - struct Light : VirtualObject, LightPreset { - /// \brief Parses a light VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - /// \see light_preset::parse - ZKREM("use ::load()") ZKAPI static void parse(Light& obj, ReadArchive& ctx, GameVersion version); + public: + /// \brief Parses a light VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + /// \see light_preset::parse + ZKREM("use ::load()") ZKAPI static void parse(VLight& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - } // namespace vobs + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; } // namespace zenkit diff --git a/include/zenkit/vobs/Misc.hh b/include/zenkit/vobs/Misc.hh index 2daf1bb7..cf6d4aea 100644 --- a/include/zenkit/vobs/Misc.hh +++ b/include/zenkit/vobs/Misc.hh @@ -56,298 +56,322 @@ namespace zenkit { point ZKREM("renamed to TouchCollisionType::POINT") = POINT, }; - namespace vobs { - /// \brief An animated VOb. - struct Animate : VirtualObject { - bool start_on {false}; - - // Save-game only variables - bool s_is_running {false}; - - /// \brief Parses an animated VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(Animate& obj, ReadArchive& ctx, GameVersion version); - - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + /// \brief An animated VOb. + struct VAnimate : VirtualObject { + ZK_OBJECT(ObjectType::zCVobAnimate); - /// \brief A VOb representing an in-game item. - struct Item : VirtualObject { - static constexpr ObjectType TYPE = ObjectType::oCItem; + public: + bool start_on {false}; - std::string instance; + // Save-game only variables + bool s_is_running {false}; - // Save-game only variables - int s_amount; - int s_flags; + /// \brief Parses an animated VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VAnimate& obj, ReadArchive& ctx, GameVersion version); - /// \brief Parses an item VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(Item& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + /// \brief A VOb representing an in-game item. + struct VItem : VirtualObject { + ZK_OBJECT(ObjectType::oCItem); - /// \brief A VOb representing a [lens flare](https://en.wikipedia.org/wiki/Lens_flare). - struct LensFlare : VirtualObject { - std::string fx; + public: + std::string instance; - /// \brief Parses a lens flare VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(LensFlare& obj, ReadArchive& ctx, GameVersion version); + // Save-game only variables + int s_amount; + int s_flags; - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + /// \brief Parses an item VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VItem& obj, ReadArchive& ctx, GameVersion version); - /// \brief A VOb representing a particle system controller. - struct ParticleEffectController : VirtualObject { - std::string pfx_name; - bool kill_when_done; - bool initially_running; - - /// \brief Parses a particle system controller VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") - ZKAPI static void parse(ParticleEffectController& obj, ReadArchive& ctx, GameVersion version); - - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; - struct MessageFilter : VirtualObject { - std::string target; - MessageFilterAction on_trigger; - MessageFilterAction on_untrigger; + /// \brief A VOb representing a [lens flare](https://en.wikipedia.org/wiki/Lens_flare). + struct VLensFlare : VirtualObject { + ZK_OBJECT(ObjectType::zCVobLensFlare); - /// \brief Parses a message filter VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(MessageFilter& obj, ReadArchive& ctx, GameVersion version); + public: + std::string fx; - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + /// \brief Parses a lens flare VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VLensFlare& obj, ReadArchive& ctx, GameVersion version); - struct CodeMaster : VirtualObject { - std::string target; - bool ordered; - bool first_false_is_failure; - std::string failure_target; - bool untriggered_cancels; - std::vector slaves; - - // Save-game only variables - uint8_t s_num_triggered_slaves; - - /// \brief Parses a code master VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(CodeMaster& obj, ReadArchive& ctx, GameVersion version); - - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; - struct MoverController : VirtualObject { - std::string target; - MoverMessageType message; - std::int32_t key; + /// \brief A VOb representing a particle system controller. + struct VParticleEffectController : VirtualObject { + ZK_OBJECT(ObjectType::zCPFXController); + + public: + std::string pfx_name; + bool kill_when_done; + bool initially_running; + + /// \brief Parses a particle system controller VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") + ZKAPI static void parse(VParticleEffectController& obj, ReadArchive& ctx, GameVersion version); + + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; - /// \brief Parses a mover controller VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(MoverController& obj, ReadArchive& ctx, GameVersion version); + struct VMessageFilter : VirtualObject { + ZK_OBJECT(ObjectType::zCMessageFilter); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + public: + std::string target; + MessageFilterAction on_trigger; + MessageFilterAction on_untrigger; - /// \brief A VOb which represents a damage source. - struct TouchDamage : VirtualObject { - float damage; - - bool barrier; - bool blunt; - bool edge; - bool fire; - bool fly; - bool magic; - bool point; - bool fall; - - float repeat_delay_sec; - float volume_scale; - TouchCollisionType collision; - - /// \brief Parses a touch damage VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(TouchDamage& obj, ReadArchive& ctx, GameVersion version); - - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + /// \brief Parses a message filter VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VMessageFilter& obj, ReadArchive& ctx, GameVersion version); - /// \brief A VOb which represents an earthquake-like effect. - struct Earthquake : VirtualObject { - float radius; - float duration; - glm::vec3 amplitude; - - /// \brief Parses an earthquake VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(Earthquake& obj, ReadArchive& ctx, GameVersion version); - - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + struct VCodeMaster : VirtualObject { + ZK_OBJECT(ObjectType::zCCodeMaster); + + public: + std::string target; + bool ordered; + bool first_false_is_failure; + std::string failure_target; + bool untriggered_cancels; + std::vector slaves; + + // Save-game only variables + uint8_t s_num_triggered_slaves; + + /// \brief Parses a code master VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VCodeMaster& obj, ReadArchive& ctx, GameVersion version); + + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + struct VMoverController : VirtualObject { + ZK_OBJECT(ObjectType::zCMoverController); + + public: + std::string target; + MoverMessageType message; + std::int32_t key; + + /// \brief Parses a mover controller VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VMoverController& obj, ReadArchive& ctx, GameVersion version); - struct Npc : VirtualObject { - static constexpr ObjectType TYPE = ObjectType::oCNpc; - static std::uint32_t const attribute_count = 8; - static std::uint32_t const hcs_count = 4; - static std::uint32_t const missions_count = 5; - static std::uint32_t const aivar_count = 100; - static std::uint32_t const packed_count = 9; - static std::uint32_t const protection_count = 8; - - struct Talent : Object { - static constexpr ObjectType TYPE = ObjectType::oCNpcTalent; - - int talent; - int value; - int skill; - - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } - - void load(ReadArchive& r, GameVersion version) override; - }; - - using talent ZKREM("renamed to Talent") = Talent; - - struct Slot { - bool used; - std::string name; - std::shared_ptr item {}; - bool in_inventory; - }; - - using slot ZKREM("renamed to Slot") = Slot; - - std::string npc_instance; - glm::vec3 model_scale; - float model_fatness; - - std::vector overlays; - - int flags; - int guild; - int guild_true; - int level; - int xp; - int xp_next_level; - int lp; - - std::vector> talents; - - int fight_tactic; - int fight_mode; - bool wounded; - bool mad; - int mad_time; - bool player; - - int attributes[attribute_count]; - int hcs[hcs_count]; - int missions[missions_count]; - - std::string start_ai_state; - int aivar[aivar_count]; - std::string script_waypoint; - int attitude; - int attitude_temp; - int name_nr; - bool move_lock; - - std::string packed[packed_count]; - std::vector> items; - std::vector slots; - - bool current_state_valid; - std::string current_state_name; - int current_state_index; - bool current_state_is_routine; - - bool next_state_valid; - std::string next_state_name; - int next_state_index; - bool next_state_is_routine; - - int last_ai_state; - bool has_routine; - bool routine_changed; - bool routine_overlay; - int routine_overlay_count; - int walkmode_routine; - bool weaponmode_routine; - bool start_new_routine; - int ai_state_driven; - glm::vec3 ai_state_pos; - std::string current_routine; - bool respawn; - int respawn_time; - - int protection[protection_count]; - - int bs_interruptable_override {0}; - int npc_type {0}; - int spell_mana {0}; - - /// \brief Parses an NPC VOb from the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(Npc& obj, ReadArchive& ctx, GameVersion version); - - [[nodiscard]] ObjectType get_type() const override { + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + /// \brief A VOb which represents a damage source. + struct VTouchDamage : VirtualObject { + ZK_OBJECT(ObjectType::oCTouchDamage); + + public: + float damage; + + bool barrier; + bool blunt; + bool edge; + bool fire; + bool fly; + bool magic; + bool point; + bool fall; + + float repeat_delay_sec; + float volume_scale; + TouchCollisionType collision; + + /// \brief Parses a touch damage VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VTouchDamage& obj, ReadArchive& ctx, GameVersion version); + + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + /// \brief A VOb which represents an earthquake-like effect. + struct VEarthquake : VirtualObject { + ZK_OBJECT(ObjectType::zCEarthquake); + + public: + float radius; + float duration; + glm::vec3 amplitude; + + /// \brief Parses an earthquake VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VEarthquake& obj, ReadArchive& ctx, GameVersion version); + + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + struct VNpc : VirtualObject { + ZK_OBJECT(ObjectType::oCNpc); + + public: + static std::uint32_t const attribute_count = 8; + static std::uint32_t const hcs_count = 4; + static std::uint32_t const missions_count = 5; + static std::uint32_t const aivar_count = 100; + static std::uint32_t const packed_count = 9; + static std::uint32_t const protection_count = 8; + + struct Talent : Object { + static constexpr ObjectType TYPE = ObjectType::oCNpcTalent; + + int talent; + int value; + int skill; + + [[nodiscard]] ObjectType get_object_type() const override { return TYPE; } - ZKAPI void load(ReadArchive& r, GameVersion version) override; + void load(ReadArchive& r, GameVersion version) override; }; - struct ScreenEffect : VirtualObject { - ZKAPI void load(ReadArchive& r, GameVersion version) override; + using talent ZKREM("renamed to Talent") = Talent; + + struct Slot { + bool used; + std::string name; + std::shared_ptr item {}; + bool in_inventory; }; - } // namespace vobs + + using slot ZKREM("renamed to Slot") = Slot; + + std::string npc_instance; + glm::vec3 model_scale; + float model_fatness; + + std::vector overlays; + + int flags; + int guild; + int guild_true; + int level; + int xp; + int xp_next_level; + int lp; + + std::vector> talents; + + int fight_tactic; + int fight_mode; + bool wounded; + bool mad; + int mad_time; + bool player; + + int attributes[attribute_count]; + int hcs[hcs_count]; + int missions[missions_count]; + + std::string start_ai_state; + int aivar[aivar_count]; + std::string script_waypoint; + int attitude; + int attitude_temp; + int name_nr; + bool move_lock; + + std::string packed[packed_count]; + std::vector> items; + std::vector slots; + + bool current_state_valid; + std::string current_state_name; + int current_state_index; + bool current_state_is_routine; + + bool next_state_valid; + std::string next_state_name; + int next_state_index; + bool next_state_is_routine; + + int last_ai_state; + bool has_routine; + bool routine_changed; + bool routine_overlay; + int routine_overlay_count; + int walkmode_routine; + bool weaponmode_routine; + bool start_new_routine; + int ai_state_driven; + glm::vec3 ai_state_pos; + std::string current_routine; + bool respawn; + int respawn_time; + + int protection[protection_count]; + + int bs_interruptable_override {0}; + int npc_type {0}; + int spell_mana {0}; + + /// \brief Parses an NPC VOb from the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VNpc& obj, ReadArchive& ctx, GameVersion version); + + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + struct VScreenEffect : VirtualObject { + ZK_OBJECT(ObjectType::zCVobScreenFX) + + public: + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; } // namespace zenkit diff --git a/include/zenkit/vobs/MovableObject.hh b/include/zenkit/vobs/MovableObject.hh index 58059fbc..b98ff995 100644 --- a/include/zenkit/vobs/MovableObject.hh +++ b/include/zenkit/vobs/MovableObject.hh @@ -30,105 +30,108 @@ namespace zenkit { glass ZKREM("renamed to SoundMaterialType::GLASS") = GLASS, }; - namespace vobs { - struct MovableObject : VirtualObject { - std::string name; - std::int32_t hp; - std::int32_t damage; - bool movable; - bool takable; - bool focus_override; - SoundMaterialType material; - std::string visual_destroyed; - std::string owner; - std::string owner_guild; - bool destroyed; - - /// \brief Parses an interactive VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(MovableObject& obj, ReadArchive& ctx, GameVersion version); - - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - - struct InteractiveObject : MovableObject { - std::int32_t state; - std::string target; - std::string item; - std::string condition_function; - std::string on_state_change_function; - bool rewind; - - /// \brief Parses a interactive VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") - ZKAPI static void parse(InteractiveObject& obj, ReadArchive& ctx, GameVersion version); - - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - - /// \brief A VOb representing a campfire. - struct Fire : InteractiveObject { - std::string slot; - std::string vob_tree; - - /// \brief Parses a campfire VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - /// \see mob::parse - ZKREM("use ::load()") ZKAPI static void parse(Fire& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - - /// \brief A VOb representing a container. - struct Container : InteractiveObject { - bool locked; - std::string key; - std::string pick_string; - std::string contents; - - // Save-game only variables - std::vector> s_items; - - /// \brief Parses a container VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - /// \see mob::parse - /// \see mob_container::parse - ZKREM("use ::load()") ZKAPI static void parse(Container& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - - /// \brief A VOb representing a door. - struct Door : public InteractiveObject { - bool locked; - std::string key; - std::string pick_string; - - /// \brief Parses a door VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - /// \see mob::parse - /// \see mob_container::parse - ZKREM("use ::load") ZKAPI static void parse(Door& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - } // namespace vobs + struct VMovableObject : VirtualObject { + std::string name; + std::int32_t hp; + std::int32_t damage; + bool movable; + bool takable; + bool focus_override; + SoundMaterialType material; + std::string visual_destroyed; + std::string owner; + std::string owner_guild; + bool destroyed; + + /// \brief Parses an interactive VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VMovableObject& obj, ReadArchive& ctx, GameVersion version); + + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + struct VInteractiveObject : VMovableObject { + std::int32_t state; + std::string target; + std::string item; + std::string condition_function; + std::string on_state_change_function; + bool rewind; + + /// \brief Parses a interactive VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") + ZKAPI static void parse(VInteractiveObject& obj, ReadArchive& ctx, GameVersion version); + + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + /// \brief A VOb representing a campfire. + struct VFire : VInteractiveObject { + std::string slot; + std::string vob_tree; + + /// \brief Parses a campfire VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + /// \see mob::parse + ZKREM("use ::load()") ZKAPI static void parse(VFire& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + /// \brief A VOb representing a container. + struct VContainer : VInteractiveObject { + bool locked; + std::string key; + std::string pick_string; + std::string contents; + + // Save-game only variables + std::vector> s_items; + + /// \brief Parses a container VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + /// \see mob::parse + /// \see mob_container::parse + ZKREM("use ::load()") ZKAPI static void parse(VContainer& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + /// \brief A VOb representing a door. + struct VDoor : VInteractiveObject { + bool locked; + std::string key; + std::string pick_string; + + /// \brief Parses a door VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + /// \see mob::parse + /// \see mob_container::parse + ZKREM("use ::load") ZKAPI static void parse(VDoor& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + struct VLadder : VInteractiveObject {}; + struct VSwitch : VInteractiveObject {}; + struct VWheel : VInteractiveObject {}; + struct VBed : VInteractiveObject {}; } // namespace zenkit diff --git a/include/zenkit/vobs/Sound.hh b/include/zenkit/vobs/Sound.hh index 9765b0e1..fb0f96a6 100644 --- a/include/zenkit/vobs/Sound.hh +++ b/include/zenkit/vobs/Sound.hh @@ -36,50 +36,54 @@ namespace zenkit { ellipsoidal ZKREM("renamed to SoundTriggerVolume::ELLIPSOIDAL") = ELLIPSOIDAL, }; - namespace vobs { - /// \brief A VOb which emits a sound. - struct Sound : VirtualObject { - float volume {0}; - SoundMode mode {SoundMode::ONCE}; - float random_delay {0}; - float random_delay_var {0}; - bool initially_playing {false}; - bool ambient3d {false}; - bool obstruction {true}; - float cone_angle {0}; - SoundTriggerVolumeType volume_type {SoundTriggerVolumeType::SPHERICAL}; - float radius {0}; - std::string sound_name {}; + /// \brief A VOb which emits a sound. + struct VSound : VirtualObject { + ZK_OBJECT(ObjectType::zCVobSound); - // Save-game only variables - bool s_is_running; - bool s_is_allowed_to_run; + public: + float volume {0}; + SoundMode mode {SoundMode::ONCE}; + float random_delay {0}; + float random_delay_var {0}; + bool initially_playing {false}; + bool ambient3d {false}; + bool obstruction {true}; + float cone_angle {0}; + SoundTriggerVolumeType volume_type {SoundTriggerVolumeType::SPHERICAL}; + float radius {0}; + std::string sound_name {}; - /// \brief Parses a sound VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(Sound& obj, ReadArchive& ctx, GameVersion version); + // Save-game only variables + bool s_is_running; + bool s_is_allowed_to_run; - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + /// \brief Parses a sound VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VSound& obj, ReadArchive& ctx, GameVersion version); - /// \brief A VOb which emits a sound only during certain times of the day. - struct SoundDaytime : Sound { - float start_time {0}; - float end_time {0}; - std::string sound_name2 {}; + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + /// \brief A VOb which emits a sound only during certain times of the day. + struct VSoundDaytime : VSound { + ZK_OBJECT(ObjectType::zCVobSoundDaytime); - /// \brief Parses a timed sound VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(SoundDaytime& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - } // namespace vobs + public: + float start_time {0}; + float end_time {0}; + std::string sound_name2 {}; + + /// \brief Parses a timed sound VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VSoundDaytime& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; } // namespace zenkit diff --git a/include/zenkit/vobs/Trigger.hh b/include/zenkit/vobs/Trigger.hh index 6bd0124e..bd7a77f5 100644 --- a/include/zenkit/vobs/Trigger.hh +++ b/include/zenkit/vobs/Trigger.hh @@ -67,174 +67,197 @@ namespace zenkit { random ZKREM("renamed to TriggerBatchMode::RANDOM") = RANDOM, }; - namespace vobs { - /// \brief A basic trigger VOb which does something upon the player interacting with it. - struct Trigger : VirtualObject { - std::string target; - std::uint8_t flags; - std::uint8_t filter_flags; - std::string vob_target; - std::int32_t max_activation_count; - float retrigger_delay_sec; - float damage_threshold; - float fire_delay_sec; - - // Save-game only variables - float s_next_time_triggerable {0}; - int s_count_can_be_activated {0}; - bool s_is_enabled {true}; - - /// \brief Parses a trigger VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - /// \see trigger::parse - ZKREM("use ::load()") ZKAPI static void parse(Trigger& obj, ReadArchive& ctx, GameVersion version); - - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + /// \brief A basic trigger VOb which does something upon the player interacting with it. + struct VTrigger : VirtualObject { + ZK_OBJECT(ObjectType::zCTrigger); + + public: + std::string target; + std::uint8_t flags; + std::uint8_t filter_flags; + std::string vob_target; + std::int32_t max_activation_count; + float retrigger_delay_sec; + float damage_threshold; + float fire_delay_sec; + + // Save-game only variables + float s_next_time_triggerable {0}; + int s_count_can_be_activated {0}; + bool s_is_enabled {true}; + + /// \brief Parses a trigger VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + /// \see trigger::parse + ZKREM("use ::load()") ZKAPI static void parse(VTrigger& obj, ReadArchive& ctx, GameVersion version); + + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; - /// \brief A VOb which can move upon player interaction. - struct Mover : Trigger { - MoverBehavior behavior {MoverBehavior::TOGGLE}; - float touch_blocker_damage {0}; - float stay_open_time_sec {0}; - bool locked {true}; - bool auto_link {false}; - bool auto_rotate {false}; - - float speed {0}; - MoverLerpType lerp_mode {MoverLerpType::CURVE}; - MoverSpeedType speed_mode {MoverSpeedType::CONSTANT}; - - std::vector keyframes {}; - - std::string sfx_open_start {}; - std::string sfx_open_end {}; - std::string sfx_transitioning {}; - std::string sfx_close_start {}; - std::string sfx_close_end {}; - std::string sfx_lock {}; - std::string sfx_unlock {}; - std::string sfx_use_locked {}; - - // Save-game only variables - glm::vec3 s_act_key_pos_delta; - float s_act_keyframe_f; - int s_act_keyframe; - int s_next_keyframe; - float s_move_speed_unit; - float s_advance_dir; - uint32_t s_mover_state; - int s_trigger_event_count; - float s_stay_open_time_dest; - - /// \brief Parses a mover trigger VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - /// \see trigger::parse - ZKREM("use ::load()") ZKAPI static void parse(Mover& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + struct VCutsceneTrigger : VTrigger { + ZK_OBJECT(ObjectType::oCCSTrigger); + }; - /// \brief A VOb which can call multiple script function upon being triggered. - struct TriggerList : Trigger { - struct Target { - std::string name {}; - float delay {}; - - [[nodiscard]] bool operator==(Target const& tgt) const noexcept { - return this->name == tgt.name && this->delay == tgt.delay; - } - }; - - using target ZKREM("renamed to Target") = Target; - - TriggerBatchMode mode {}; - std::vector targets {}; - - // Save-game only variables - uint8_t s_act_target {0}; - bool s_send_on_trigger {false}; - - /// \brief Parses a trigger list VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - /// \see trigger::parse - ZKREM("use ::load()") ZKAPI static void parse(TriggerList& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + /// \brief A VOb which can move upon player interaction. + struct VMover : VTrigger { + ZK_OBJECT(ObjectType::zCMover); + + public: + MoverBehavior behavior {MoverBehavior::TOGGLE}; + float touch_blocker_damage {0}; + float stay_open_time_sec {0}; + bool locked {true}; + bool auto_link {false}; + bool auto_rotate {false}; + + float speed {0}; + MoverLerpType lerp_mode {MoverLerpType::CURVE}; + MoverSpeedType speed_mode {MoverSpeedType::CONSTANT}; + + std::vector keyframes {}; + + std::string sfx_open_start {}; + std::string sfx_open_end {}; + std::string sfx_transitioning {}; + std::string sfx_close_start {}; + std::string sfx_close_end {}; + std::string sfx_lock {}; + std::string sfx_unlock {}; + std::string sfx_use_locked {}; + + // Save-game only variables + glm::vec3 s_act_key_pos_delta; + float s_act_keyframe_f; + int s_act_keyframe; + int s_next_keyframe; + float s_move_speed_unit; + float s_advance_dir; + uint32_t s_mover_state; + int s_trigger_event_count; + float s_stay_open_time_dest; + + /// \brief Parses a mover trigger VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + /// \see trigger::parse + ZKREM("use ::load()") ZKAPI static void parse(VMover& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; - /// \brief A VOb which calls a script function upon being triggered. - struct TriggerScript : Trigger { - std::string function {}; - - /// \brief Parses a script trigger VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - /// \see trigger::parse - ZKREM("use ::load()") ZKAPI static void parse(TriggerScript& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + /// \brief A VOb which can call multiple script function upon being triggered. + struct VTriggerList : VTrigger { + ZK_OBJECT(ObjectType::zCTriggerList); - /// \brief A VOb which triggers a level change if the player moves close to it. - struct TriggerChangeLevel : Trigger { - std::string level_name {}; - std::string start_vob {}; - - /// \brief Parses a change level trigger VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - /// \see trigger::parse - ZKREM("use ::load()") - ZKAPI static void parse(TriggerChangeLevel& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; + public: + struct Target { + std::string name {}; + float delay {}; - /// \brief A VOb which triggers a world start event. - struct TriggerWorldStart : VirtualObject { - std::string target; - bool fire_once; - - // Save-game only variables - bool s_has_fired {false}; - - /// \brief Parses a world load trigger VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") - ZKAPI static void parse(TriggerWorldStart& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; + [[nodiscard]] bool operator==(Target const& tgt) const noexcept { + return this->name == tgt.name && this->delay == tgt.delay; + } }; - struct TriggerUntouch : VirtualObject { - std::string target; - - /// \brief Parses an untouch trigger VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(TriggerUntouch& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - } // namespace vobs + using target ZKREM("renamed to Target") = Target; + + TriggerBatchMode mode {}; + std::vector targets {}; + + // Save-game only variables + uint8_t s_act_target {0}; + bool s_send_on_trigger {false}; + + /// \brief Parses a trigger list VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + /// \see trigger::parse + ZKREM("use ::load()") ZKAPI static void parse(VTriggerList& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + /// \brief A VOb which calls a script function upon being triggered. + struct VTriggerScript : VTrigger { + ZK_OBJECT(ObjectType::oCTriggerScript); + + public: + std::string function {}; + + /// \brief Parses a script trigger VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + /// \see trigger::parse + ZKREM("use ::load()") ZKAPI static void parse(VTriggerScript& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + /// \brief A VOb which triggers a level change if the player moves close to it. + struct VTriggerChangeLevel : VTrigger { + ZK_OBJECT(ObjectType::oCTriggerChangeLevel); + + public: + std::string level_name {}; + std::string start_vob {}; + + /// \brief Parses a change level trigger VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + /// \see trigger::parse + ZKREM("use ::load()") + ZKAPI static void parse(VTriggerChangeLevel& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + /// \brief A VOb which triggers a world start event. + struct VTriggerWorldStart : VirtualObject { + ZK_OBJECT(ObjectType::zCTriggerWorldStart); + + public: + std::string target; + bool fire_once; + + // Save-game only variables + bool s_has_fired {false}; + + /// \brief Parses a world load trigger VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") + ZKAPI static void parse(VTriggerWorldStart& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + struct VTriggerUntouch : VirtualObject { + ZK_OBJECT(ObjectType::zCTriggerUntouch); + + public: + std::string target; + + /// \brief Parses an untouch trigger VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VTriggerUntouch& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; } // namespace zenkit diff --git a/include/zenkit/vobs/VirtualObject.hh b/include/zenkit/vobs/VirtualObject.hh index d81fa9ba..0179a034 100644 --- a/include/zenkit/vobs/VirtualObject.hh +++ b/include/zenkit/vobs/VirtualObject.hh @@ -12,21 +12,20 @@ #include #include +#include #include #include #include #include -namespace zenkit::vobs { - struct Npc; -} namespace zenkit { class ReadArchive; + struct VNpc; - /// \brief Ways a VOb can cast shadows. + /// \brief Ways VObjects can cast shadows. enum class ShadowType : std::uint8_t { - NONE = 0, ///< The VOb does not cast any shadow. - BLOB = 1, ///< The VOb casts a basic dark circle at its base. + NONE = 0, ///< The VObject does not cast any shadow. + BLOB = 1, ///< The VObject casts a basic dark circle at its base. // Deprecated entries. none ZKREM("renamed to ShadowType::NONE") = NONE, @@ -55,9 +54,9 @@ namespace zenkit { unknown ZKREM("renamed to VisualType::UNKNOWN") = UNKNOWN, }; - /// \brief Ways the camera may behave with a VOb. + /// \brief Behavior of a VObject's rotation in relation to the camera. enum class SpriteAlignment : std::uint8_t { - NONE = 0, ///< The sprite is not affected by the camera's position. + NONE = 0, ///< The sprite is not affected by the camera's rotation. YAW = 1, ///< The sprite rotates with the camera's yaw axis. FULL = 2, ///< The sprite rotates with camera fully. @@ -70,7 +69,21 @@ namespace zenkit { /// \brief Types of wavy animation. enum class AnimationType : std::uint8_t { NONE = 0, ///< No wave animation. + + /// \brief String wind animation. + /// + ///

Indicates that the object should be animated as if shifting in strong wind. Used mostly for + /// animating grass and other small foliage.

+ /// + /// \see http://www.gothic-library.ru/publ/class_zcvob/1-1-0-467#visualAniMode WIND = 1, + + /// \brief Light wind animation. + /// + ///

Indicates that the object should be animated as if shifting in light wind. Used mostly for + /// animating trees.

+ /// + /// \see http://www.gothic-library.ru/publ/class_zcvob/1-1-0-467#visualAniMode WIND_ALT = 2, // Deprecated entries. @@ -79,10 +92,46 @@ namespace zenkit { wind2 ZKREM("renamed to AnimationType::WIND_ALT") = WIND_ALT, }; + struct Visual : Object { + /// \brief The type of this visual. + VisualType type = VisualType::UNKNOWN; + + /// \brief The name of this visual, a decal mesh or particle effect. + /// + ///

This field conains the name of the source file of the visual. A mesh visual, for example, will end in + /// `.3DS` since that is the original file format of the mesh.

+ std::string name; + }; + + struct VisualMesh final : Visual { + ZK_OBJECT(ObjectType::zCMesh); + }; + + struct VisualMultiResolutionMesh final : Visual { + ZK_OBJECT(ObjectType::zCProgMeshProto); + }; + + struct VisualParticleEffect final : Visual { + ZK_OBJECT(ObjectType::zCParticleFX); + }; + + struct VisualCamera final : Visual { + ZK_OBJECT(ObjectType::zCAICamera); + }; + + struct VisualModel final : Visual { + ZK_OBJECT(ObjectType::zCModel); + }; + + struct VisualMorphMesh final : Visual { + ZK_OBJECT(ObjectType::zCMorphMesh); + }; + /// \brief Decal visual configuration for VObs. - struct VisualDecal : Object { - static constexpr ObjectType TYPE = ObjectType::zCDecal; + struct VisualDecal final : Visual { + ZK_OBJECT(ObjectType::zCDecal); + public: std::string name {}; glm::vec2 dimension {}; glm::vec2 offset {}; @@ -99,55 +148,9 @@ namespace zenkit { /// \throws ParserError if parsing fails. ZKREM("use ::load()") ZKAPI static VisualDecal parse(ReadArchive& ctx, GameVersion version); - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } - ZKAPI void load(ReadArchive& r, GameVersion version); }; - struct VisualMesh : Object { - static constexpr ObjectType TYPE = ObjectType::zCMesh; - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } - }; - - struct VisualMultiResolutionMesh : Object { - static constexpr ObjectType TYPE = ObjectType::zCProgMeshProto; - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } - }; - - struct VisualParticleEffect : Object { - static constexpr ObjectType TYPE = ObjectType::zCParticleFX; - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } - }; - - struct VisualCamera : Object { - static constexpr ObjectType TYPE = ObjectType::zCAICamera; - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } - }; - - struct VisualModel : Object { - static constexpr ObjectType TYPE = ObjectType::zCModel; - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } - }; - - struct VisualMorphMesh : Object { - static constexpr ObjectType TYPE = ObjectType::zCMorphMesh; - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } - }; - struct RigidBody { glm::vec3 vel; std::uint8_t mode; @@ -158,22 +161,24 @@ namespace zenkit { ZKAPI void load(ReadArchive& r, GameVersion version); }; - struct EventManager : Object { - static constexpr ObjectType TYPE = ObjectType::ignored; + struct EventManager final : Object { + ZK_OBJECT(ObjectType::zCEventManager); - bool cleared; - bool active; - - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } + private: + bool cleared = false; + bool active = false; ZKAPI void load(ReadArchive& r, GameVersion version); }; - struct AiHuman : Object { - static constexpr ObjectType TYPE = ObjectType::zCModel; + struct VirtualObject; + + struct Ai : Object {}; + struct AiHuman final : Ai { + ZK_OBJECT(ObjectType::oCAIHuman); + + public: int water_level; float floor_y; float water_y; @@ -182,7 +187,7 @@ namespace zenkit { float head_y; float fall_dist_y; float fall_start_y; - std::shared_ptr npc; + std::shared_ptr npc; int walk_mode; int weapon_mode; int wmode_ast; @@ -190,104 +195,231 @@ namespace zenkit { bool change_weapon; int action_mode; - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } - void load(ReadArchive& r, GameVersion version) override; }; - struct VirtualObject; - - struct AiMove : Object { - static constexpr ObjectType TYPE = ObjectType::zCModel; + struct AiMove final : Ai { + ZK_OBJECT(ObjectType::oCAIVobMove); + public: std::shared_ptr vob; - std::shared_ptr owner; - - [[nodiscard]] ObjectType get_type() const override { - return TYPE; - } + std::shared_ptr owner; void load(ReadArchive& r, GameVersion version) override; }; - /// \brief The base class for all VObs. + enum class VirtualObjectType { + UNKNOWN = -1, + zCVob = 0, ///< The base type for all VObs. + zCVobLevelCompo = 1, ///< A basic VOb used for grouping other VObs. + oCItem = 2, ///< A VOb representing an item + oCNpc = 3, ///< A VOb representing an NPC + zCMoverController = 4, + zCVobScreenFX = 5, + zCVobStair = 6, + zCPFXController = 7, + zCVobAnimate = 8, + zCVobLensFlare = 9, + zCVobLight = 10, + zCVobSpot = 11, + zCVobStartpoint = 12, + zCMessageFilter = 13, + zCCodeMaster = 14, + zCTriggerWorldStart = 15, + zCCSCamera = 16, + zCCamTrj_KeyFrame = 17, + oCTouchDamage = 18, + zCTriggerUntouch = 19, + zCEarthquake = 20, + oCMOB = 21, ///< The base VOb type used for dynamic world objects. + oCMobInter = 22, ///< The base VOb type used for interactive world objects. + oCMobBed = 23, ///< A bed the player can sleep in. + oCMobFire = 24, ///< A campfire the player can cook things on. + oCMobLadder = 25, ///< A ladder the player can climb. + oCMobSwitch = 26, ///< A switch or button the player can use. + oCMobWheel = 27, ///< A grindstone the player can sharpen their weapon with. + oCMobContainer = 28, ///< A container the player can open. + oCMobDoor = 29, ///< A door the player can open. + zCTrigger = 30, ///< The base VOb type used for all kinds of triggers. + zCTriggerList = 31, ///< A collection of multiple triggers. + oCTriggerScript = 32, ///< A trigger for calling a script function. + oCTriggerChangeLevel = 33, ///< A trigger for changing the game world. + oCCSTrigger = 34, ///< A cutscene trigger. + zCMover = 35, + zCVobSound = 36, ///< A VOb which emits a certain sound. + zCVobSoundDaytime = 37, ///< A VOb which emits a sound only during a specified time. + oCZoneMusic = 38, ///< A VOb which plays music from the soundtrack. + oCZoneMusicDefault = 39, + zCZoneZFog = 40, ///< A VOb which indicates a foggy area. + zCZoneZFogDefault = 41, + zCZoneVobFarPlane = 42, + zCZoneVobFarPlaneDefault = 43, + }; + + /// \brief The base class of all ZenGin virtual objects. + /// + ///

Contains general VObject settings like its position, rotation, visual and much more. Known fields have been + /// documented with information about their purpose and additional information may be obtained from the unified + /// ZenGin documentation at https://zk.gothickit.dev.

+ /// + ///

ZenGin virtual objects inherit from the base zenkit::Object. Copy and move operations have been + /// intentionally deleted, because VObject can reference each other through shared pointers. Moving VObjects + /// while this is the case would break parsing.

/// - ///

Contains parameters all VObs have, like their position, bounding box and model.

+ /// \note Virtual objects should not be loaded manually. They are embedded into world archives and are automatically + /// loaded when the world is loaded. struct VirtualObject : Object { + ZK_OBJECT(ObjectType::zCVob); + + public: VirtualObject() = default; - VirtualObject(VirtualObject const&) = delete; - VirtualObject(VirtualObject&&) = default; - struct SaveState { - uint8_t sleep_mode; - float next_on_timer; - std::optional rigid_body {}; - }; - - using save_state ZKREM("renamed to SaveState") = SaveState; - - ObjectType type; ///< The type of this VOb. - uint32_t id; ///< The index of this VOb in the archive it was read from. - - AxisAlignedBoundingBox bbox {}; - glm::vec3 position {}; - glm::mat3x3 rotation {}; - bool show_visual {}; - SpriteAlignment sprite_camera_facing_mode {SpriteAlignment::NONE}; - bool cd_static {}; - bool cd_dynamic {}; - bool vob_static {}; - ShadowType dynamic_shadows {}; - bool physics_enabled {}; - AnimationType anim_mode {}; - std::int32_t bias {}; - bool ambient {}; - float anim_strength {}; - float far_clip_scale {}; - - std::string preset_name {}; - std::string vob_name {}; - std::string visual_name {}; - - ZKREM("use ::visual.get_type() instead") VisualType associated_visual_type {}; - ZKREM("use ::visual instead") std::optional visual_decal {}; - std::shared_ptr visual = nullptr; - - // One of: AiHuman (oCAIHuman), AiMove (oCAIVobMove) - std::shared_ptr ai = nullptr; - - /// \brief Contains extra data about the item in the context of a saved game. - std::optional saved {}; + /// \brief Implicit copy-constructor. Disabled for performance reasons. + VirtualObject(VirtualObject const&) = delete; - /// \brief The children of this VOb. - std::vector> children {}; + /// \brief Move-constructor. Disabled for memory safety with shared references. + VirtualObject(VirtualObject&&) = default; /// \brief Default virtual destructor. ~VirtualObject() override = default; - /// \return `true` if this VOb is from a save-game and `false` if not. - [[nodiscard]] ZKAPI bool is_save_game() const noexcept { - return saved.has_value(); - } + /// \brief The type of this VObject. + /// + ///

This field holds the type of the virtual object which determines its function in the game world. There + /// are lots of virtual objects which are diffentiated by this field. See the type hierarchy diagram of + /// zenkit::VirtualObject for an overview of availabe VObject types.

+ VirtualObjectType type = VirtualObjectType::UNKNOWN; + + /// \brief The index of this VObject in the archive it was read from. + /// \deprecated This value is only relevant with the specific world archive the object was loaded from. + /// Essentially, it exposes internal state of the archive parser to the outside. It should no longer + /// be used since it is not a real unique identifier of any single object and references internal + /// parser state. If you need to check, if two VObjects are equal, you should do a simple pointer + /// compare on the shared pointer it's wrapped in. + uint32_t id ZKREM("scheduled for removal; refer to documentation") = 0; + + /// \brief The bounding box of this VObject. + AxisAlignedBoundingBox bbox = AxisAlignedBoundingBox::zero(); - /// \brief Parses a base VOb from the given *ZenGin* archive. + /// \brief The position of this VObject in virtual space. + glm::vec3 position = glm::vec3 {0}; + + /// \brief The rotation of this VObject in virtual space. + glm::mat3x3 rotation = glm::identity(); + + /// \brief Indicates whether this VObject has should display its associated visual. + bool show_visual = false; + + /// \brief Indicates how this VObject should be aligned in relation to the camera. /// - ///

This implementation is heavily based on the implementation found in - /// [ZenLib](https://github.com/Try/ZenLib).

+ ///

The value of this field indicates, if and how this VObject should align itself with the camera. This may + /// be used with grass or flowers which only consist of a 2-dimensional sprite to have it always face the + /// camera, for example. See zenkit::SpriteAlignment for additional details.

+ SpriteAlignment sprite_camera_facing_mode = SpriteAlignment::NONE; + + /// \brief Indicates whether this VObject should collide with other VObjects. /// - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - ZKREM("use ::load()") ZKAPI static void parse(VirtualObject& obj, ReadArchive& ctx, GameVersion version); + ///

This is used for placing the object in the ZenGin map editor, the Spacer, where it will prevent + /// the VObject being placed wither other VObjects. This setting is irrelevant for runtime collision + /// detection

+ bool cd_static = true; + + /// \brief Indicates whether this VObject should collide with dynamic objects. + /// + ///

For this purpose, dynamic objects are the player, NPCs and items. If this flag is set, implementations + /// should apply collision detection to this VObject.

+ bool cd_dynamic = true; + + /// \brief Indicates whether this VObject should be included during static lighting calculations. + /// + ///

These lighting calculations are done at compile-time and will bake VObjects with this flag into the + /// light-maps available from the world mesh. If set to `true`, this VObject may be excluded from dynamic + /// lighting if the light-maps are used.

+ bool vob_static = false; - // TODO(lmichaelis): Return a constant value from this! - [[nodiscard]] ObjectType get_type() const override { - return this->type; - } + /// \brief The type of dynamic shadow to be used. + /// + ///

See zenkit::ShadowType for information about available shadow types.

+ ShadowType dynamic_shadows = ShadowType::NONE; + + /// \brief Indicates whether this VObject has enabled physics. + /// + ///

This field represents internal state of the ZenGin which is written to disk only for a certain world + /// format type. It is not possible to set this field ZenGin's world editor, the Spacer, for example. + /// This makes this field unreliable, since it is only available for some VObjects.

+ bool physics_enabled = true; + + /// \brief The type of wind animation to apply to the VObject. + AnimationType anim_mode = AnimationType::NONE; + + /// \brief The depth-bias for this VObject. + /// + ///

This value is passed directly to Direct3D when rendering the associated visual of this VObject. Sadly, + /// because documentation is not really available for the very old Direct3D version used by the ZenGin, the + /// exact behavior it would have resulted in are unknown.

+ std::int32_t bias = 0; + + /// \brief Indicates that this VObject is ambient. + /// + ///

It looks like this VObject setting was a system used duing development when access to the game's source + /// code was available. Basically, the global variable `zCWorld::s_bAmbientVobsEnabled` could be used to hide or + /// show VObjects which have the `isAmbient` flag set. In release builds, this variable is always set to `true`, + /// thus the `isAmbient` flag does not have any percievable effect on the game.

+ ///

It follows, that this field should be ignored by most implementations.

+ bool ambient = false; + + /// \brief Indicates the strength of the animation set through #anim_mode. + /// + ///

Essentialy, this controls the strength of the wind to be animated using the given #anim_mode. This value + /// is ignored if #anim_mode is AnimationType::NONE

+ float anim_strength = 0; + float far_clip_scale = 2.0; + + std::string preset_name; + + /// \brief The name of this VObject. + /// + ///

The name of this VObject. VObject names are not necessarily unique but are sometimes helpful for + /// identfying them in ZenGin's original map editor, the Spacer.

+ std::string vob_name; + + std::string visual_name ZKREM("use VirtualObject::visual::name instead") {}; + VisualType associated_visual_type ZKREM("use VirtualObject::visual::type instead") {}; + std::optional visual_decal ZKREM("use VirtualObject::visual instead") {}; + + /// \brief The visual data associated with this VObject. + /// + ///

All supported visuals except the zenkit::VisualDecal do not contain any additional information. To + /// determine the type of attached visual, simply access zenkit::VisualDecal::type

+ std::shared_ptr visual = nullptr; + + std::shared_ptr ai = nullptr; + + std::uint8_t sleep_mode = 0; + float next_on_timer = 0; + std::optional rigid_body {}; + + /// \brief The children of this VOb. + std::vector> children {}; + + ZKREM("use ::load()") ZKAPI static void parse(VirtualObject& obj, ReadArchive& ctx, GameVersion version); ZKAPI void load(ReadArchive& r, GameVersion version) override; }; + + struct VSpot final : VirtualObject { + ZK_OBJECT(ObjectType::zCVobSpot); + }; + + struct VStair final : VirtualObject { + ZK_OBJECT(ObjectType::zCVobStair); + }; + + struct VStartPoint final : VirtualObject { + ZK_OBJECT(ObjectType::zCVobStartpoint); + }; + + struct VLevel final : VirtualObject { + ZK_OBJECT(ObjectType::zCVobLevelCompo); + }; } // namespace zenkit diff --git a/include/zenkit/vobs/Zone.hh b/include/zenkit/vobs/Zone.hh index b1b40d90..dfbd60b6 100644 --- a/include/zenkit/vobs/Zone.hh +++ b/include/zenkit/vobs/Zone.hh @@ -12,62 +12,81 @@ namespace zenkit { class ReadArchive; - namespace vobs { - /// \brief A VOb which defines the background music in a certain zone. - struct ZoneMusic : VirtualObject { - bool enabled {false}; - std::int32_t priority {0}; - bool ellipsoid {false}; - float reverb {0}; - float volume {0}; - bool loop {false}; - - // Save-game only variables - bool s_local_enabled {true}; - bool s_day_entrance_done {false}; - bool s_night_entrance_done {false}; - - /// \brief Parses a zone music VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(ZoneMusic& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - - /// \brief A VOb which defines the far plane settings in a certain zone. - struct ZoneFarPlane : VirtualObject { - float vob_far_plane_z; - float inner_range_percentage; - - /// \brief Parses a zone far plane VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(ZoneFarPlane& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - - /// \brief A VOb which defines the fog in a certain zone. - struct ZoneFog : VirtualObject { - float range_center {0}; - float inner_range_percentage {0}; - glm::u8vec4 color {}; - bool fade_out_sky {false}; - bool override_color {false}; - - /// \brief Parses a zone fog VOb the given *ZenGin* archive. - /// \param[out] obj The object to read. - /// \param[in,out] ctx The archive reader to read from. - /// \note After this function returns the position of \p ctx will be at the end of the parsed object. - /// \throws ParserError if parsing fails. - /// \see vob::parse - ZKREM("use ::load()") ZKAPI static void parse(ZoneFog& obj, ReadArchive& ctx, GameVersion version); - ZKAPI void load(ReadArchive& r, GameVersion version) override; - }; - } // namespace vobs + /// \brief A VOb which defines the background music in a certain zone. + struct VZoneMusic : VirtualObject { + ZK_OBJECT(ObjectType::oCZoneMusic); + + public: + bool enabled {false}; + std::int32_t priority {0}; + bool ellipsoid {false}; + float reverb {0}; + float volume {0}; + bool loop {false}; + + // Save-game only variables + bool s_local_enabled {true}; + bool s_day_entrance_done {false}; + bool s_night_entrance_done {false}; + + /// \brief Parses a zone music VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VZoneMusic& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + struct VZoneMusicDefault : VZoneMusic { + ZK_OBJECT(ObjectType::oCZoneMusicDefault); + }; + + /// \brief A VOb which defines the far plane settings in a certain zone. + struct VZoneFarPlane : VirtualObject { + ZK_OBJECT(ObjectType::zCZoneVobFarPlane); + + public: + float vob_far_plane_z; + float inner_range_percentage; + + /// \brief Parses a zone far plane VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VZoneFarPlane& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + struct VZoneFarPlaneDefault : VZoneFarPlane { + ZK_OBJECT(ObjectType::zCZoneVobFarPlaneDefault); + }; + + /// \brief A VOb which defines the fog in a certain zone. + struct VZoneFog : VirtualObject { + ZK_OBJECT(ObjectType::zCZoneZFog); + + public: + float range_center {0}; + float inner_range_percentage {0}; + glm::u8vec4 color {}; + bool fade_out_sky {false}; + bool override_color {false}; + + /// \brief Parses a zone fog VOb the given *ZenGin* archive. + /// \param[out] obj The object to read. + /// \param[in,out] ctx The archive reader to read from. + /// \note After this function returns the position of \p ctx will be at the end of the parsed object. + /// \throws ParserError if parsing fails. + /// \see vob::parse + ZKREM("use ::load()") ZKAPI static void parse(VZoneFog& obj, ReadArchive& ctx, GameVersion version); + ZKAPI void load(ReadArchive& r, GameVersion version) override; + }; + + struct VZoneFogDefault : VZoneFog { + ZK_OBJECT(ObjectType::zCZoneZFogDefault); + }; } // namespace zenkit diff --git a/src/Archive.cc b/src/Archive.cc index ddf8acd0..a5d690d7 100644 --- a/src/Archive.cc +++ b/src/Archive.cc @@ -221,11 +221,10 @@ namespace zenkit { type = it->second; } - // TODO(lmichaelis): The VOb type/id assignment is a hacky workaround! Create separate types! std::shared_ptr syn; switch (type) { case ObjectType::oCNpcTalent: - syn = std::make_shared(); + syn = std::make_shared(); break; case ObjectType::zCEventManager: syn = std::make_shared(); @@ -264,182 +263,149 @@ namespace zenkit { syn = std::make_shared(); break; case ObjectType::zCVobLevelCompo: + syn = std::make_shared(); + break; case ObjectType::zCVobStartpoint: + syn = std::make_shared(); + break; case ObjectType::zCVobStair: + syn = std::make_shared(); + break; case ObjectType::zCVobSpot: + syn = std::make_shared(); + break; case ObjectType::zCVob: syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; break; case ObjectType::zCVobScreenFX: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCCSCamera: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCCamTrj_KeyFrame: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCVobAnimate: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCZoneVobFarPlane: + syn = std::make_shared(); + break; case ObjectType::zCZoneVobFarPlaneDefault: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCZoneZFogDefault: + syn = std::make_shared(); + break; case ObjectType::zCZoneZFog: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCVobLensFlare: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCItem: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCTrigger: + syn = std::make_shared(); + break; case ObjectType::oCCSTrigger: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCMOB: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCMobInter: + syn = std::make_shared(); + break; case ObjectType::oCMobLadder: + syn = std::make_shared(); + break; case ObjectType::oCMobSwitch: + syn = std::make_shared(); + break; case ObjectType::oCMobWheel: + syn = std::make_shared(); + break; case ObjectType::oCMobBed: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCMobFire: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCMobContainer: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCMobDoor: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCPFXController: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCVobLight: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCVobSound: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCVobSoundDaytime: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCZoneMusic: + syn = std::make_shared(); + break; case ObjectType::oCZoneMusicDefault: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCMessageFilter: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCCodeMaster: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCTriggerList: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCTriggerScript: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCMover: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCTriggerChangeLevel: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCTriggerWorldStart: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCTouchDamage: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCTriggerUntouch: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCEarthquake: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::zCMoverController: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; case ObjectType::oCNpc: - syn = std::make_shared(); - reinterpret_cast(syn.get())->type = type; - reinterpret_cast(syn.get())->id = obj.index; + syn = std::make_shared(); break; default: ZKLOGE("ReadArchive", "Unknown object type: %s", obj.class_name.c_str()); break; } + // TODO(lmichaelis): The VOb type/id assignment is a hacky workaround! Create separate types! + if (is_vobject(type)) { + VirtualObjectType vtype = static_cast(type); + reinterpret_cast(syn.get())->type = vtype; + reinterpret_cast(syn.get())->id = obj.index; + } + _m_cache.insert_or_assign(obj.index, syn); if (syn != nullptr) { diff --git a/src/Object.cc b/src/Object.cc index 2243ecd3..c3f7ff50 100644 --- a/src/Object.cc +++ b/src/Object.cc @@ -1,5 +1,9 @@ #include "zenkit/Object.hh" namespace zenkit { + ObjectType Object::get_object_type() const { + return ObjectType::unknown; + } + void Object::load(ReadArchive& r, GameVersion version) {} } // namespace zenkit \ No newline at end of file diff --git a/src/World.cc b/src/World.cc index 43b3d93e..cf2ca1ac 100644 --- a/src/World.cc +++ b/src/World.cc @@ -157,7 +157,7 @@ namespace zenkit { auto npc_count = archive->read_int(); // npcCount this->npcs.resize(npc_count); for (auto i = 0; i < npc_count; ++i) { - this->npcs[i] = archive->read_object(version); + this->npcs[i] = archive->read_object(version); } // After that, read all NPC spawn locations @@ -165,9 +165,9 @@ namespace zenkit { this->npc_spawns.resize(npc_spawn_count); for (auto& spawn : this->npc_spawns) { - spawn.npc = archive->read_object(version); // npc - spawn.position = archive->read_vec3(); // spawnPos - spawn.timer = archive->read_float(); // timer + spawn.npc = archive->read_object(version); // npc + spawn.position = archive->read_vec3(); // spawnPos + spawn.timer = archive->read_float(); // timer } this->npc_spawn_enabled = archive->read_bool(); // spawningEnabled diff --git a/src/vobs/Camera.cc b/src/vobs/Camera.cc index 11b73c5e..e1e0797d 100644 --- a/src/vobs/Camera.cc +++ b/src/vobs/Camera.cc @@ -5,14 +5,14 @@ #include "../Internal.hh" -namespace zenkit::vobs { - std::unique_ptr CameraTrajectoryFrame::parse(ReadArchive& r, GameVersion version) { - auto obj = std::make_unique(); +namespace zenkit { + std::unique_ptr VCameraTrajectoryFrame::parse(ReadArchive& r, GameVersion version) { + auto obj = std::make_unique(); obj->load(r, version); return obj; } - void CameraTrajectoryFrame::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VCameraTrajectoryFrame::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->time = r.read_float(); // time this->roll_angle = r.read_float(); // angleRollDeg @@ -31,11 +31,11 @@ namespace zenkit::vobs { this->original_pose = buf->read_mat4(); } - void CutsceneCamera::parse(CutsceneCamera& obj, ReadArchive& r, GameVersion version) { + void VCutsceneCamera::parse(VCutsceneCamera& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void CutsceneCamera::load(ReadArchive& r, GameVersion version) { + void VCutsceneCamera::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->trajectory_for = static_cast(r.read_enum()); // camTrjFOR this->target_trajectory_for = static_cast(r.read_enum()); // targetTrjFOR @@ -55,16 +55,16 @@ namespace zenkit::vobs { this->target_count = r.read_int(); // numTargets for (auto i = 0; i < this->position_count + this->target_count; ++i) { - auto obj = r.read_object(version); + auto obj = r.read_object(version); this->frames.push_back(obj); } if (r.is_save_game() && version == GameVersion::GOTHIC_2) { // In save-games, cutscene cameras contain extra variables - this->s_paused = r.read_bool(); // paused - this->s_started = r.read_bool(); // started - this->s_goto_time_mode = r.read_bool(); // gotoTimeMode - this->s_cs_time = r.read_float(); // csTime + this->paused = r.read_bool(); // paused + this->started = r.read_bool(); // started + this->goto_time_mode = r.read_bool(); // gotoTimeMode + this->cs_time = r.read_float(); // csTime } } -} // namespace zenkit::vobs +} // namespace zenkit diff --git a/src/vobs/Light.cc b/src/vobs/Light.cc index 4a3abf8e..1603ef15 100644 --- a/src/vobs/Light.cc +++ b/src/vobs/Light.cc @@ -7,12 +7,12 @@ #include -namespace zenkit::vobs { +namespace zenkit { void LightPreset::parse(LightPreset& obj, ReadArchive& in, GameVersion version) { obj.load(in, version); } - void LightPreset::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void LightPreset::load(ReadArchive& r, GameVersion version) { this->preset = r.read_string(); // lightPresetInUse this->light_type = static_cast(r.read_enum()); // lightType this->range = r.read_float(); // range @@ -85,12 +85,12 @@ namespace zenkit::vobs { return preset; } - void Light::parse(Light& obj, ReadArchive& ctx, GameVersion version) { + void VLight::parse(VLight& obj, ReadArchive& ctx, GameVersion version) { obj.load(ctx, version); } - void Light::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VLight::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); LightPreset::load(r, version); } -} // namespace zenkit::vobs +} // namespace zenkit diff --git a/src/vobs/Misc.cc b/src/vobs/Misc.cc index 173b26d3..cba5a3e7 100644 --- a/src/vobs/Misc.cc +++ b/src/vobs/Misc.cc @@ -5,12 +5,12 @@ #include "../Internal.hh" -namespace zenkit::vobs { - void Animate::parse(Animate& obj, ReadArchive& r, GameVersion version) { +namespace zenkit { + void VAnimate::parse(VAnimate& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void Animate::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VAnimate::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->start_on = r.read_bool(); // startOn @@ -20,11 +20,11 @@ namespace zenkit::vobs { } } - void Item::parse(Item& obj, ReadArchive& r, GameVersion version) { + void VItem::parse(VItem& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void Item::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VItem::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->instance = r.read_string(); // itemInstance @@ -35,42 +35,42 @@ namespace zenkit::vobs { } } - void LensFlare::parse(LensFlare& obj, ReadArchive& r, GameVersion version) { + void VLensFlare::parse(VLensFlare& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void LensFlare::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VLensFlare::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->fx = r.read_string(); // lensflareFX } - void ParticleEffectController::parse(ParticleEffectController& obj, ReadArchive& r, GameVersion version) { + void VParticleEffectController::parse(VParticleEffectController& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void ParticleEffectController::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VParticleEffectController::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->pfx_name = r.read_string(); // pfxName this->kill_when_done = r.read_bool(); // killVobWhenDone this->initially_running = r.read_bool(); // pfxStartOn } - void MessageFilter::parse(MessageFilter& obj, ReadArchive& r, GameVersion version) { + void VMessageFilter::parse(VMessageFilter& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void MessageFilter::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VMessageFilter::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->target = r.read_string(); // triggerTarget this->on_trigger = static_cast(r.read_enum()); // onTrigger this->on_untrigger = static_cast(r.read_enum()); // onUntrigger } - void CodeMaster::parse(CodeMaster& obj, ReadArchive& r, GameVersion version) { + void VCodeMaster::parse(VCodeMaster& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void CodeMaster::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VCodeMaster::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->target = r.read_string(); // triggerTarget this->ordered = r.read_bool(); // orderRelevant @@ -83,7 +83,7 @@ namespace zenkit::vobs { this->slaves.emplace_back(r.read_string()); // slaveVobName[i] } - if (this->saved && version == GameVersion::GOTHIC_2) { + if (r.is_save_game() && version == GameVersion::GOTHIC_2) { // In Gothic II save-games, code masters contain extra variables this->s_num_triggered_slaves = r.read_byte(); // numSlavesTriggered @@ -94,11 +94,11 @@ namespace zenkit::vobs { } } - void MoverController::parse(MoverController& obj, ReadArchive& r, GameVersion version) { + void VMoverController::parse(VMoverController& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void MoverController::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VMoverController::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->target = r.read_string(); // triggerTarget @@ -111,11 +111,11 @@ namespace zenkit::vobs { this->key = r.read_int(); // gotoFixedKey } - void TouchDamage::parse(TouchDamage& obj, ReadArchive& r, GameVersion version) { + void VTouchDamage::parse(VTouchDamage& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void TouchDamage::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VTouchDamage::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->damage = r.read_float(); // damage this->barrier = r.read_bool(); // Barrier @@ -131,28 +131,28 @@ namespace zenkit::vobs { this->collision = static_cast(r.read_enum()); // damageCollType } - void Earthquake::parse(Earthquake& obj, ReadArchive& r, GameVersion version) { + void VEarthquake::parse(VEarthquake& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void Earthquake::load(ReadArchive& r, GameVersion version) { + void VEarthquake::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->radius = r.read_float(); // radius this->duration = r.read_float(); // timeSec this->amplitude = r.read_vec3(); // amplitudeCM } - void Npc::Talent::load(ReadArchive& r, GameVersion version) { + void VNpc::Talent::load(ReadArchive& r, GameVersion version) { this->talent = r.read_int(); // talent this->value = r.read_int(); // value this->skill = r.read_int(); // skill } - void Npc::parse(Npc& obj, ReadArchive& r, GameVersion version) { + void VNpc::parse(VNpc& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void Npc::load(ReadArchive& r, GameVersion version) { + void VNpc::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->npc_instance = r.read_string(); // npcInstance @@ -223,12 +223,12 @@ namespace zenkit::vobs { if (news_count != 0) { ZKLOGE("VOb.Npc", "!!! IMPORTANT !!! This save-game contains news entries and cannot be loaded currently. Please " - "open an issue at https://github.com/GothicKit/phoenix providing your save-game as a ZIP file."); - throw ParserError {"vobs::Npc"}; + "open an issue at https://github.com/GothicKit/ZenKit providing your save-game as a ZIP file."); + throw ParserError {"VNpc"}; } - r.skip_object(false); // [carryVob % 0 0] - r.skip_object(false); // [enemy % 0 0] + (void) /* TODO(lmichaelis): carryVob = */ r.read_object(version); // [carryVob % 0 0] + (void) /* TODO(lmichaelis): enemy = */ r.read_object(version); // [enemy % 0 0] this->move_lock = r.read_bool(); // moveLock @@ -252,7 +252,7 @@ namespace zenkit::vobs { this->items.resize(item_count); for (auto i = 0u; i < item_count; ++i) { - this->items[i] = r.read_object(version); + this->items[i] = r.read_object(version); if ((this->items[i]->s_flags & 0x200) != 0) { (void) r.read_int(); // shortKey // TODO @@ -266,7 +266,7 @@ namespace zenkit::vobs { this->slots[i].name = r.read_string(); // name if (this->slots[i].used) { - this->slots[i].item = r.read_object(version); + this->slots[i].item = r.read_object(version); this->slots[i].in_inventory = r.read_bool(); // inInv } } @@ -305,7 +305,7 @@ namespace zenkit::vobs { } } - void ScreenEffect::load(ReadArchive& r, GameVersion version) { + void VScreenEffect::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); if (r.is_save_game()) { @@ -317,4 +317,4 @@ namespace zenkit::vobs { (void) r.read_vec2(); // fovSaved1st } } -} // namespace zenkit::vobs +} // namespace zenkit diff --git a/src/vobs/MovableObject.cc b/src/vobs/MovableObject.cc index f766d99a..9be0e7cc 100644 --- a/src/vobs/MovableObject.cc +++ b/src/vobs/MovableObject.cc @@ -5,12 +5,12 @@ #include "../Internal.hh" -namespace zenkit::vobs { - void MovableObject::parse(MovableObject& obj, ReadArchive& r, GameVersion version) { +namespace zenkit { + void VMovableObject::parse(VMovableObject& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void MovableObject::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VMovableObject::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->name = r.read_string(); // focusName this->hp = r.read_int(); // hitpoints @@ -25,12 +25,12 @@ namespace zenkit::vobs { this->destroyed = r.read_bool(); // isDestroyed } - void InteractiveObject::parse(InteractiveObject& obj, ReadArchive& r, GameVersion version) { + void VInteractiveObject::parse(VInteractiveObject& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void InteractiveObject::load(ReadArchive& r, zenkit::GameVersion version) { - MovableObject::load(r, version); + void VInteractiveObject::load(ReadArchive& r, GameVersion version) { + VMovableObject::load(r, version); this->state = r.read_int(); // stateNum this->target = r.read_string(); // triggerTarget this->item = r.read_string(); // useWithItem @@ -39,12 +39,12 @@ namespace zenkit::vobs { this->rewind = r.read_bool(); // rewind } - void Container::parse(Container& obj, ReadArchive& r, GameVersion version) { + void VContainer::parse(VContainer& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void Container::load(ReadArchive& r, zenkit::GameVersion version) { - InteractiveObject::load(r, version); + void VContainer::load(ReadArchive& r, GameVersion version) { + VInteractiveObject::load(r, version); this->locked = r.read_bool(); // locked this->key = r.read_string(); // keyInstance this->pick_string = r.read_string(); // pickLockStr @@ -56,29 +56,29 @@ namespace zenkit::vobs { this->s_items.resize(item_count); for (auto i = 0u; i < item_count; ++i) { - this->s_items[i] = r.read_object(version); + this->s_items[i] = r.read_object(version); } } } - void Door::parse(Door& obj, ReadArchive& r, GameVersion version) { + void VDoor::parse(VDoor& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void Door::load(ReadArchive& r, GameVersion version) { - InteractiveObject::load(r, version); + void VDoor::load(ReadArchive& r, GameVersion version) { + VInteractiveObject::load(r, version); this->locked = r.read_bool(); // locked this->key = r.read_string(); // keyInstance this->pick_string = r.read_string(); // pickLockStr } - void Fire::parse(Fire& obj, ReadArchive& r, GameVersion version) { + void VFire::parse(VFire& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void Fire::load(ReadArchive& r, GameVersion version) { - InteractiveObject::load(r, version); + void VFire::load(ReadArchive& r, GameVersion version) { + VInteractiveObject::load(r, version); this->slot = r.read_string(); // fireSlot this->vob_tree = r.read_string(); // fireVobtreeName } -} // namespace zenkit::vobs +} // namespace zenkit diff --git a/src/vobs/Sound.cc b/src/vobs/Sound.cc index f9e004ea..c428e3e9 100644 --- a/src/vobs/Sound.cc +++ b/src/vobs/Sound.cc @@ -3,12 +3,12 @@ #include "zenkit/vobs/Sound.hh" #include "zenkit/Archive.hh" -namespace zenkit::vobs { - void Sound::parse(Sound& obj, ReadArchive& r, GameVersion version) { +namespace zenkit { + void VSound::parse(VSound& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void Sound::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VSound::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->volume = r.read_float(); // sndVolume this->mode = static_cast(r.read_enum()); // sndMode @@ -29,14 +29,14 @@ namespace zenkit::vobs { } } - void SoundDaytime::parse(SoundDaytime& obj, ReadArchive& r, GameVersion version) { + void VSoundDaytime::parse(VSoundDaytime& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void SoundDaytime::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { - Sound::load(r, version); + void VSoundDaytime::load(ReadArchive& r, GameVersion version) { + VSound::load(r, version); this->start_time = r.read_float(); // sndStartTime this->end_time = r.read_float(); // sndEndTime this->sound_name2 = r.read_string(); // sndName2 } -} // namespace zenkit::vobs +} // namespace zenkit diff --git a/src/vobs/Trigger.cc b/src/vobs/Trigger.cc index 0d25b67e..1acea2ce 100644 --- a/src/vobs/Trigger.cc +++ b/src/vobs/Trigger.cc @@ -3,12 +3,12 @@ #include "zenkit/vobs/Trigger.hh" #include "zenkit/Archive.hh" -namespace zenkit::vobs { - void Trigger::parse(Trigger& obj, ReadArchive& r, GameVersion version) { +namespace zenkit { + void VTrigger::parse(VTrigger& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void Trigger::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VTrigger::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->target = r.read_string(); // triggerTarget this->flags = r.read_raw(1)->read_ubyte(); // flags @@ -33,12 +33,12 @@ namespace zenkit::vobs { } } - void Mover::parse(Mover& obj, ReadArchive& r, GameVersion version) { + void VMover::parse(VMover& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void Mover::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { - Trigger::load(r, version); + void VMover::load(ReadArchive& r, GameVersion version) { + VTrigger::load(r, version); this->behavior = static_cast(r.read_enum()); // moverBehavior this->touch_blocker_damage = r.read_float(); // touchBlockerDamage this->stay_open_time_sec = r.read_float(); // stayOpenTimeSec @@ -92,12 +92,12 @@ namespace zenkit::vobs { this->sfx_use_locked = r.read_string(); // sfxUseLocked } - void TriggerList::parse(TriggerList& obj, ReadArchive& r, GameVersion version) { + void VTriggerList::parse(VTriggerList& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void TriggerList::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { - Trigger::load(r, version); + void VTriggerList::load(ReadArchive& r, GameVersion version) { + VTrigger::load(r, version); this->mode = static_cast(r.read_enum()); // listProcess auto target_count = r.read_byte(); // numTarget @@ -115,30 +115,30 @@ namespace zenkit::vobs { } } - void TriggerScript::parse(TriggerScript& obj, ReadArchive& r, GameVersion version) { + void VTriggerScript::parse(VTriggerScript& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void TriggerScript::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { - Trigger::load(r, version); + void VTriggerScript::load(ReadArchive& r, GameVersion version) { + VTrigger::load(r, version); this->function = r.read_string(); // scriptFunc } - void TriggerChangeLevel::parse(TriggerChangeLevel& obj, ReadArchive& r, GameVersion version) { + void VTriggerChangeLevel::parse(VTriggerChangeLevel& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void TriggerChangeLevel::load(zenkit::ReadArchive& r, GameVersion version) { - Trigger::load(r, version); + void VTriggerChangeLevel::load(ReadArchive& r, GameVersion version) { + VTrigger::load(r, version); this->level_name = r.read_string(); // levelName this->start_vob = r.read_string(); // startVobName } - void TriggerWorldStart::parse(TriggerWorldStart& obj, ReadArchive& r, GameVersion version) { + void VTriggerWorldStart::parse(VTriggerWorldStart& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void TriggerWorldStart::load(ReadArchive& r, GameVersion version) { + void VTriggerWorldStart::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->target = r.read_string(); // triggerTarget this->fire_once = r.read_bool(); // fireOnlyFirstTime @@ -149,12 +149,12 @@ namespace zenkit::vobs { } } - void TriggerUntouch::parse(TriggerUntouch& obj, ReadArchive& r, GameVersion version) { + void VTriggerUntouch::parse(VTriggerUntouch& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void TriggerUntouch::load(zenkit::ReadArchive& r, zenkit::GameVersion version) { + void VTriggerUntouch::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->target = r.read_string(); // triggerTarget } -} // namespace zenkit::vobs +} // namespace zenkit diff --git a/src/vobs/VirtualObject.cc b/src/vobs/VirtualObject.cc index 13d9ad66..9b5fc491 100644 --- a/src/vobs/VirtualObject.cc +++ b/src/vobs/VirtualObject.cc @@ -4,6 +4,8 @@ #include "zenkit/Archive.hh" #include "zenkit/vobs/Misc.hh" +#include "../Internal.hh" + #include namespace zenkit { @@ -134,24 +136,27 @@ namespace zenkit { } if (has_visual_object) { - this->visual = r.read_object(version); + this->visual = std::dynamic_pointer_cast(r.read_object(version)); if (visual != nullptr) { - auto it = visual_type_map.find(visual->get_type()); + auto it = visual_type_map.find(visual->get_object_type()); if (it == visual_type_map.end()) { this->associated_visual_type = VisualType::UNKNOWN; } else { this->associated_visual_type = it->second; } - if (this->visual->get_type() == ObjectType::zCDecal) { + this->visual->name = this->visual_name; + this->visual->type = it->second; + + if (this->visual->type == VisualType::DECAL) { this->visual_decal.emplace(*std::reinterpret_pointer_cast(this->visual)); } } } if (has_ai_object) { - this->ai = r.read_object(version); + this->ai = std::reinterpret_pointer_cast(r.read_object(version)); } if (has_event_manager_object) { @@ -161,12 +166,11 @@ namespace zenkit { if (r.get_header().save) { // save-games contain two extra values for each VOb // TODO: These are technically from oCVob! - this->saved = SaveState {}; - this->saved->sleep_mode = r.read_byte(); // sleepMode - this->saved->next_on_timer = r.read_float(); // nextOnTimer + this->sleep_mode = r.read_byte(); // sleepMode + this->next_on_timer = r.read_float(); // nextOnTimer if (this->physics_enabled) { - this->saved->rigid_body.emplace().load(r, version); + this->rigid_body.emplace().load(r, version); } } } @@ -196,7 +200,7 @@ namespace zenkit { fall_dist_y = r.read_float(); // fallDistY fall_start_y = r.read_float(); // fallStartY - npc = r.read_object(version); // aiNpc + npc = r.read_object(version); // aiNpc walk_mode = r.read_int(); // walkMode weapon_mode = r.read_int(); // weaponMode @@ -208,6 +212,6 @@ namespace zenkit { void AiMove::load(ReadArchive& r, GameVersion version) { vob = std::reinterpret_pointer_cast(r.read_object(version)); // vob - owner = r.read_object(version); // owner + owner = r.read_object(version); // owner } } // namespace zenkit diff --git a/src/vobs/Zone.cc b/src/vobs/Zone.cc index 4a30c2e0..fe9fad21 100644 --- a/src/vobs/Zone.cc +++ b/src/vobs/Zone.cc @@ -3,12 +3,12 @@ #include "zenkit/vobs/Zone.hh" #include "zenkit/Archive.hh" -namespace zenkit::vobs { - void ZoneMusic::parse(ZoneMusic& obj, ReadArchive& r, GameVersion version) { +namespace zenkit { + void VZoneMusic::parse(VZoneMusic& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void ZoneMusic::load(ReadArchive& r, GameVersion version) { + void VZoneMusic::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->enabled = r.read_bool(); // enabled this->priority = r.read_int(); // priority @@ -25,21 +25,21 @@ namespace zenkit::vobs { } } - void ZoneFarPlane::parse(ZoneFarPlane& obj, ReadArchive& r, GameVersion version) { + void VZoneFarPlane::parse(VZoneFarPlane& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void ZoneFarPlane::load(ReadArchive& r, GameVersion version) { + void VZoneFarPlane::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->vob_far_plane_z = r.read_float(); // vobFarPlaneZ this->inner_range_percentage = r.read_float(); // innerRangePerc } - void ZoneFog::parse(ZoneFog& obj, ReadArchive& r, GameVersion version) { + void VZoneFog::parse(VZoneFog& obj, ReadArchive& r, GameVersion version) { obj.load(r, version); } - void ZoneFog::load(ReadArchive& r, GameVersion version) { + void VZoneFog::load(ReadArchive& r, GameVersion version) { VirtualObject::load(r, version); this->range_center = r.read_float(); // fogRangeCenter this->inner_range_percentage = r.read_float(); // innerRangePerc @@ -50,4 +50,4 @@ namespace zenkit::vobs { this->override_color = r.read_bool(); // overrideColor } } -} // namespace zenkit::vobs +} // namespace zenkit diff --git a/src/world/VobTree.cc b/src/world/VobTree.cc index f7a4254f..72baae12 100644 --- a/src/world/VobTree.cc +++ b/src/world/VobTree.cc @@ -2,18 +2,7 @@ // SPDX-License-Identifier: MIT #include "zenkit/world/VobTree.hh" #include "zenkit/Archive.hh" -#include "zenkit/vobs/Camera.hh" -#include "zenkit/vobs/Light.hh" -#include "zenkit/vobs/Misc.hh" -#include "zenkit/vobs/MovableObject.hh" -#include "zenkit/vobs/Sound.hh" -#include "zenkit/vobs/Trigger.hh" #include "zenkit/vobs/VirtualObject.hh" -#include "zenkit/vobs/Zone.hh" - -#include "../Internal.hh" - -#include namespace zenkit { std::shared_ptr parse_vob_tree(ReadArchive& in, GameVersion version) { diff --git a/src/world/WayNet.cc b/src/world/WayNet.cc index 8ea66dca..04b83535 100644 --- a/src/world/WayNet.cc +++ b/src/world/WayNet.cc @@ -19,7 +19,7 @@ namespace zenkit { ArchiveObject obj; if (!in.read_object_begin(obj)) { - throw zenkit::ParserError {"WayNet", "root object missing"}; + throw ParserError {"WayNet", "root object missing"}; } (void) /* auto version = */ in.read_int(); // waynetVersion @@ -30,7 +30,7 @@ namespace zenkit { for (auto i = 0u; i < count; ++i) { if (!in.read_object_begin(obj) || obj.class_name != "zCWaypoint") { - throw zenkit::ParserError {"WayNet", "missing waypoint object #" + std::to_string(i)}; + throw ParserError {"WayNet", "missing waypoint object #" + std::to_string(i)}; } auto& wp = this->waypoints.emplace_back(); @@ -51,7 +51,7 @@ namespace zenkit { for (int32_t j = 0; j < 2; ++j) { if (!in.read_object_begin(obj)) { - throw zenkit::ParserError {"WayNet", "missing edge object #" + std::to_string(i)}; + throw ParserError {"WayNet", "missing edge object #" + std::to_string(i)}; } std::uint32_t wp; @@ -65,9 +65,9 @@ namespace zenkit { obj_id_to_wp[obj.index] = static_cast(this->waypoints.size() - 1); wp = static_cast(this->waypoints.size() - 1); } else { - throw zenkit::ParserError {"WayNet", - "failed to parse edge #" + std::to_string(i) + ": unknown class name '" + - obj.class_name + "'"}; + throw ParserError {"WayNet", + "failed to parse edge #" + std::to_string(i) + ": unknown class name '" + + obj.class_name + "'"}; } if (j == 0) { diff --git a/tests/TestFont.cc b/tests/TestFont.cc index 4271f2b5..655a602c 100644 --- a/tests/TestFont.cc +++ b/tests/TestFont.cc @@ -7,13 +7,13 @@ using namespace zenkit; -static const FontGlyph G1_GLYPH0 {0, {glm::vec2 {0.0f, 0.0f}, glm::vec2 {0.0f, 0.0f}}}; -static const FontGlyph G1_GLYPH127 {8, {glm::vec2 {0.3984375f, 0.23828125f}, glm::vec2 {0.412109375f, 0.30859375f}}}; -static const FontGlyph G1_GLYPH255 {9, {glm::vec2 {0.95703125f, 0.55078125f}, glm::vec2 {0.97265625f, 0.62109375f}}}; +static FontGlyph const G1_GLYPH0 {0, {glm::vec2 {0.0f, 0.0f}, glm::vec2 {0.0f, 0.0f}}}; +static FontGlyph const G1_GLYPH127 {8, {glm::vec2 {0.3984375f, 0.23828125f}, glm::vec2 {0.412109375f, 0.30859375f}}}; +static FontGlyph const G1_GLYPH255 {9, {glm::vec2 {0.95703125f, 0.55078125f}, glm::vec2 {0.97265625f, 0.62109375f}}}; -static const FontGlyph G2_GLYPH0 {0, {glm::vec2 {0.0f, 0.0f}, glm::vec2 {0.0f, 0.0f}}}; -static const FontGlyph G2_GLYPH127 {8, {glm::vec2 {0.3984375f, 0.23828125f}, glm::vec2 {0.412109375f, 0.30859375f}}}; -static const FontGlyph G2_GLYPH255 {10, {glm::vec2 {0.958984375f, 0.55078125f}, glm::vec2 {0.9765625f, 0.62109375f}}}; +static FontGlyph const G2_GLYPH0 {0, {glm::vec2 {0.0f, 0.0f}, glm::vec2 {0.0f, 0.0f}}}; +static FontGlyph const G2_GLYPH127 {8, {glm::vec2 {0.3984375f, 0.23828125f}, glm::vec2 {0.412109375f, 0.30859375f}}}; +static FontGlyph const G2_GLYPH255 {10, {glm::vec2 {0.958984375f, 0.55078125f}, glm::vec2 {0.9765625f, 0.62109375f}}}; TEST_SUITE("Font") { TEST_CASE("Font.load(GOTHIC1)") { diff --git a/tests/TestModelAnimation.cc b/tests/TestModelAnimation.cc index 7cb5f2a2..4dddfed1 100644 --- a/tests/TestModelAnimation.cc +++ b/tests/TestModelAnimation.cc @@ -6,24 +6,24 @@ using namespace zenkit; -static const std::vector G1_NODE_INDICES {0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 15, +static std::vector const G1_NODE_INDICES {0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 15, 16, 17, 18, 19, 26, 27, 28, 29, 30, 31, 32, 33}; -static const std::vector G2_NODE_INDICES {0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 15, +static std::vector const G2_NODE_INDICES {0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 15, 16, 17, 18, 19, 26, 27, 28, 29, 30, 31, 32, 33}; -static const AnimationSample G1_SAMPLE0 {glm::vec3 {12.635274887084961f, 88.75251770019531f, -1.093428611755371f}, +static AnimationSample const G1_SAMPLE0 {glm::vec3 {12.635274887084961f, 88.75251770019531f, -1.093428611755371f}, glm::quat {0.7771535515785217f, 0.0f, 0.6293110251426697f, 0.0f}}; -static const AnimationSample G1_SAMPLE249 {glm::vec3 {12.626323699951172f, -0.00145721435546875f, 22.643518447875977f}, +static AnimationSample const G1_SAMPLE249 {glm::vec3 {12.626323699951172f, -0.00145721435546875f, 22.643518447875977f}, glm::quat {0.7071319222450256f, 0.0f, 0.70708167552948f, 0.0f}}; -static const AnimationSample G1_SAMPLE499 {glm::vec3 {12.626323699951172, -0.00145721435546875, 22.643518447875977}, +static AnimationSample const G1_SAMPLE499 {glm::vec3 {12.626323699951172, -0.00145721435546875, 22.643518447875977}, glm::quat {0.7071319222450256, 0.0, 0.70708167552948, 0.0}}; -static const AnimationSample G2_SAMPLE0 {glm::vec3 {12.635274887084961f, 88.75251770019531f, -1.093428611755371f}, +static AnimationSample const G2_SAMPLE0 {glm::vec3 {12.635274887084961f, 88.75251770019531f, -1.093428611755371f}, glm::quat {0.7771535515785217f, 0.0f, 0.6293110251426697f, 0.0f}}; -static const AnimationSample G2_SAMPLE249 {glm::vec3 {12.626323699951172f, -0.00145721435546875f, 22.643518447875977f}, +static AnimationSample const G2_SAMPLE249 {glm::vec3 {12.626323699951172f, -0.00145721435546875f, 22.643518447875977f}, glm::quat {0.7071319222450256f, 0.0f, 0.70708167552948f, 0.0f}}; -static const AnimationSample G2_SAMPLE499 {glm::vec3 {12.626323699951172, -0.00145721435546875, 22.643518447875977}, +static AnimationSample const G2_SAMPLE499 {glm::vec3 {12.626323699951172, -0.00145721435546875, 22.643518447875977}, glm::quat {0.7071319222450256, 0.0, 0.70708167552948, 0.0}}; TEST_SUITE("ModelAnimation") { diff --git a/tests/TestSaveGame.cc b/tests/TestSaveGame.cc index ce3fdcb2..5e32e2ff 100644 --- a/tests/TestSaveGame.cc +++ b/tests/TestSaveGame.cc @@ -56,6 +56,7 @@ TEST_SUITE("SaveGame") { } TEST_CASE("SaveGame.load(GOTHIC2)") { + zenkit::Logger::set_default(zenkit::LogLevel::DEBUG); zenkit::unstable::SaveGame save {}; save.load("./samples/G2/Save"); diff --git a/tests/TestVobsG1.cc b/tests/TestVobsG1.cc index a486da10..33c59d00 100644 --- a/tests/TestVobsG1.cc +++ b/tests/TestVobsG1.cc @@ -44,15 +44,13 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.bias, 0); CHECK_FALSE(vob.ambient); CHECK_EQ(vob.anim_strength, 0.0f); - CHECK_EQ(vob.far_clip_scale, 0.0f); + CHECK_EQ(vob.far_clip_scale, 2.0f); CHECK_EQ(vob.preset_name, ""); CHECK_EQ(vob.vob_name, ""); - CHECK_EQ(vob.visual_name, "FIRE.pfx"); - CHECK_EQ(vob.associated_visual_type, zenkit::VisualType::PARTICLE_EFFECT); + CHECK_EQ(vob.visual->name, "FIRE.pfx"); + CHECK_EQ(vob.visual->type, zenkit::VisualType::PARTICLE_EFFECT); CHECK_EQ(vob.visual_decal, std::nullopt); - CHECK_EQ(vob.saved, std::nullopt); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -63,12 +61,11 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCVobAnimate:zCVob"); - zenkit::vobs::Animate vob {}; + zenkit::VAnimate vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_FALSE(vob.start_on); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -79,13 +76,12 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCZoneVobFarPlane:zCVob"); - zenkit::vobs::ZoneFarPlane vob {}; + zenkit::VZoneFarPlane vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.vob_far_plane_z, 9000.0f); CHECK_EQ(vob.inner_range_percentage, 0.699999988f); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -96,7 +92,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCZoneZFog:zCVob"); - zenkit::vobs::ZoneFog vob {}; + zenkit::VZoneFog vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.range_center, 8000.0f); @@ -105,7 +101,6 @@ TEST_SUITE("vobs") { CHECK_FALSE(vob.fade_out_sky); CHECK_FALSE(vob.override_color); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -116,12 +111,11 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCVobLensFlare:zCVob"); - zenkit::vobs::LensFlare vob {}; + zenkit::VLensFlare vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.fx, "TORCHFX01"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -132,12 +126,11 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCItem:zCVob"); - zenkit::vobs::Item vob {}; + zenkit::VItem vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.instance, "ITMW_1H_AXE_01"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -148,7 +141,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCCSTrigger:zCTrigger:zCVob"); - zenkit::vobs::Trigger vob {}; + zenkit::VTrigger vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.target, "AMB_PSI_CS003.CS"); @@ -160,7 +153,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.damage_threshold, 0.0f); CHECK_EQ(vob.fire_delay_sec, 0.0f); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -171,7 +163,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCMOB:zCVob"); - zenkit::vobs::MovableObject vob {}; + zenkit::VMovableObject vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.name, ""); @@ -186,7 +178,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.owner_guild, ""); CHECK_FALSE(vob.destroyed); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -197,7 +188,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCMobInter:oCMOB:zCVob"); - zenkit::vobs::InteractiveObject vob {}; + zenkit::VInteractiveObject vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.state, 1); @@ -207,7 +198,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.on_state_change_function, ""); CHECK_FALSE(vob.rewind); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -218,13 +208,12 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCMobFire:oCMobInter:oCMOB:zCVob"); - zenkit::vobs::Fire vob {}; + zenkit::VFire vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.slot, "BIP01 FIRE"); CHECK_EQ(vob.vob_tree, "FIRETREE_MEDIUM.ZEN"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -235,7 +224,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCMobContainer:oCMobInter:oCMOB:zCVob"); - zenkit::vobs::Container vob {}; + zenkit::VContainer vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_FALSE(vob.locked); @@ -243,7 +232,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.pick_string, ""); CHECK_EQ(vob.contents, ""); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -254,14 +242,13 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCMobDoor:oCMobInter:oCMOB:zCVob"); - zenkit::vobs::Door vob {}; + zenkit::VDoor vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_FALSE(vob.locked); CHECK_EQ(vob.key, ""); CHECK_EQ(vob.pick_string, ""); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -272,19 +259,18 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCPFXControler:zCVob"); - zenkit::vobs::ParticleEffectController vob {}; + zenkit::VParticleEffectController vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.pfx_name, "CS_miltenfog.PFX"); CHECK(vob.kill_when_done); CHECK(vob.initially_running); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } - static const std::vector G1_LIGHT_RANGE_ANIMATION_SCALE {}; - static const std::vector G1_LIGHT_COLOR_ANIMATION_LIST { + static std::vector const G1_LIGHT_RANGE_ANIMATION_SCALE {}; + static std::vector const G1_LIGHT_COLOR_ANIMATION_LIST { glm::u8vec4 {211, 147, 107, 255}, glm::u8vec4 {223, 173, 117, 255}, glm::u8vec4 {211, 147, 107, 255}, glm::u8vec4 {223, 173, 117, 255}, glm::u8vec4 {225, 197, 100, 255}, glm::u8vec4 {223, 173, 117, 255}, glm::u8vec4 {227, 209, 106, 255}, glm::u8vec4 {223, 173, 117, 255}, glm::u8vec4 {211, 147, 107, 255}, @@ -305,7 +291,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCVobLight:zCVob"); - zenkit::vobs::Light vob {}; + zenkit::VLight vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.preset, ""); @@ -325,7 +311,6 @@ TEST_SUITE("vobs") { CHECK_FALSE(vob.color_animation_smooth); CHECK(vob.can_move); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -336,7 +321,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCVobSound:zCVob"); - zenkit::vobs::Sound vob {}; + zenkit::VSound vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.volume, 100.0f); @@ -351,7 +336,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.radius, 1500.0f); CHECK_EQ(vob.sound_name, "FIRE_MEDIUM"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -362,14 +346,13 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCVobSoundDaytime:zCVobSound:zCVob"); - zenkit::vobs::SoundDaytime vob {}; + zenkit::VSoundDaytime vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.start_time, 8.0f); CHECK_EQ(vob.end_time, 18.0f); CHECK_EQ(vob.sound_name2, "INSECTS_AND_NIGHTINGALES"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -380,7 +363,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCZoneMusic:zCVob"); - zenkit::vobs::ZoneMusic vob {}; + zenkit::VZoneMusic vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK(vob.enabled); @@ -390,11 +373,10 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.volume, 1.0f); CHECK(vob.loop); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } - static const std::vector G1_TRIGGER_LIST_TARGETS { + static std::vector const G1_TRIGGER_LIST_TARGETS { {"EVT_CASTLE_PLATE", 0.0f}, {"EVT_CASTLE_FLOOR_5", 6.0f}, {"EVT_CASTLE_FLOOR_4", 2.0f}, @@ -410,13 +392,12 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCTriggerList:zCTrigger:zCVob"); - zenkit::vobs::TriggerList vob {}; + zenkit::VTriggerList vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.mode, zenkit::TriggerBatchMode::ALL); CHECK_EQ(vob.targets, G1_TRIGGER_LIST_TARGETS); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -427,16 +408,15 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCTriggerScript:zCTrigger:zCVob"); - zenkit::vobs::TriggerScript vob {}; + zenkit::VTriggerScript vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.function, "ON_NC_GATE_TRIGGER"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } - static const std::vector G1_MOVER_KEYFRAMES { + static std::vector const G1_MOVER_KEYFRAMES { {glm::vec3 {-23325.1992f, 3438.91333f, -21834.9473f}, glm::quat {0.105035283f, 0.091305837f, 0.747364759f, 0.649674594f}}, {glm::vec3 {-23325.1543f, 3438.91333f, -21844.3672f}, @@ -450,7 +430,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCMover:zCTrigger:zCVob"); - zenkit::vobs::Mover vob {}; + zenkit::VMover vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.behavior, zenkit::MoverBehavior::TRIGGER_CONTROL); @@ -472,7 +452,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.sfx_unlock, ""); CHECK_EQ(vob.sfx_use_locked, ""); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -483,13 +462,12 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCTriggerChangeLevel:zCTrigger:zCVob"); - zenkit::vobs::TriggerChangeLevel vob {}; + zenkit::VTriggerChangeLevel vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_1); CHECK_EQ(vob.level_name, "ORCTEMPEL.ZEN"); CHECK_EQ(vob.start_vob, "ENTRANCE_ORCTEMPLE_SURFACE"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } diff --git a/tests/TestVobsG2.cc b/tests/TestVobsG2.cc index ac2ec444..b6786e16 100644 --- a/tests/TestVobsG2.cc +++ b/tests/TestVobsG2.cc @@ -48,12 +48,10 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.far_clip_scale, 1.0f); CHECK_EQ(vob.preset_name, ""); CHECK_EQ(vob.vob_name, ""); - CHECK_EQ(vob.visual_name, "OW_MISC_WALL_TORCH_01.3DS"); - CHECK_EQ(vob.associated_visual_type, zenkit::VisualType::MULTI_RESOLUTION_MESH); + CHECK_EQ(vob.visual->name, "OW_MISC_WALL_TORCH_01.3DS"); + CHECK_EQ(vob.visual->type, zenkit::VisualType::MULTI_RESOLUTION_MESH); CHECK_EQ(vob.visual_decal, std::nullopt); - CHECK_EQ(vob.saved, std::nullopt); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -64,7 +62,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCCSCamera:zCVob"); - zenkit::vobs::CutsceneCamera vob {}; + zenkit::VCutsceneCamera vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.trajectory_for, zenkit::CameraTrajectory::WORLD); @@ -145,7 +143,6 @@ TEST_SUITE("vobs") { {82642.8984f, 3899.0f, 29397.9844f, 1.0f}, }); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -156,12 +153,11 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCVobAnimate:zCVob"); - zenkit::vobs::Animate vob {}; + zenkit::VAnimate vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK(vob.start_on); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -172,13 +168,12 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCZoneVobFarPlane:zCVob"); - zenkit::vobs::ZoneFarPlane vob {}; + zenkit::VZoneFarPlane vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.vob_far_plane_z, 6500.0f); CHECK_EQ(vob.inner_range_percentage, 0.699999988f); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -189,7 +184,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCZoneZFog:zCVob"); - zenkit::vobs::ZoneFog vob {}; + zenkit::VZoneFog vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.range_center, 16000.0f); @@ -198,7 +193,6 @@ TEST_SUITE("vobs") { CHECK_FALSE(vob.fade_out_sky); CHECK_FALSE(vob.override_color); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -209,12 +203,11 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCItem:zCVob"); - zenkit::vobs::Item vob {}; + zenkit::VItem vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.instance, "ITPL_BLUEPLANT"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -225,7 +218,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCTrigger:zCVob"); - zenkit::vobs::Trigger vob {}; + zenkit::VTrigger vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.target, ""); @@ -237,7 +230,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.damage_threshold, 0.0f); CHECK_EQ(vob.fire_delay_sec, 0.0f); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -248,7 +240,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCMOB:zCVob"); - zenkit::vobs::MovableObject vob {}; + zenkit::VMovableObject vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.name, "MOBNAME_GRAVE_18"); @@ -263,7 +255,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.owner_guild, ""); CHECK_FALSE(vob.destroyed); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -274,7 +265,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCMobInter:oCMOB:zCVob"); - zenkit::vobs::InteractiveObject vob {}; + zenkit::VInteractiveObject vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.state, 1); @@ -284,7 +275,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.on_state_change_function, "PRAYIDOL"); CHECK_FALSE(vob.rewind); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -295,13 +285,12 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCMobFire:oCMobInter:oCMOB:zCVob"); - zenkit::vobs::Fire vob {}; + zenkit::VFire vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.slot, "BIP01 FIRE"); CHECK_EQ(vob.vob_tree, "FIRETREE_LAMP.ZEN"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -312,7 +301,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCMobContainer:oCMobInter:oCMOB:zCVob"); - zenkit::vobs::Container vob {}; + zenkit::VContainer vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_FALSE(vob.locked); @@ -320,7 +309,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.pick_string, ""); CHECK_EQ(vob.contents, "ItMi_Gold:35"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -331,14 +319,13 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCMobDoor:oCMobInter:oCMOB:zCVob"); - zenkit::vobs::Door vob {}; + zenkit::VDoor vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_FALSE(vob.locked); CHECK_EQ(vob.key, ""); CHECK_EQ(vob.pick_string, ""); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -349,19 +336,18 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCPFXControler:zCVob"); - zenkit::vobs::ParticleEffectController vob {}; + zenkit::VParticleEffectController vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.pfx_name, "STARGATE_EDGES.PFX"); CHECK_FALSE(vob.kill_when_done); CHECK_FALSE(vob.initially_running); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } - static const std::vector G2_LIGHT_RANGE_ANIMATION_SCALE {}; - static const std::vector G2_LIGHT_COLOR_ANIMATION_LIST {}; + static std::vector const G2_LIGHT_RANGE_ANIMATION_SCALE {}; + static std::vector const G2_LIGHT_COLOR_ANIMATION_LIST {}; TEST_CASE("zCVobLight(GOTHIC2)") { auto buf = zenkit::Read::from("./samples/G2/VOb/zCVobLight.zen"); @@ -370,7 +356,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCVobLight:zCVob"); - zenkit::vobs::Light vob {}; + zenkit::VLight vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.preset, "NW_STANDART_FIRE_STATIC"); @@ -390,7 +376,6 @@ TEST_SUITE("vobs") { CHECK(vob.color_animation_smooth); CHECK(vob.can_move); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -401,7 +386,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCVobSound:zCVob"); - zenkit::vobs::Sound vob {}; + zenkit::VSound vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.volume, 80.0f); @@ -416,7 +401,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.radius, 3000.0f); CHECK_EQ(vob.sound_name, "OW_CROW"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -427,14 +411,13 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCVobSoundDaytime:zCVobSound:zCVob"); - zenkit::vobs::SoundDaytime vob {}; + zenkit::VSoundDaytime vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.start_time, 5.0f); CHECK_EQ(vob.end_time, 21.0f); CHECK_EQ(vob.sound_name2, "InsectsFrogs_Night"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -445,7 +428,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCZoneMusic:zCVob"); - zenkit::vobs::ZoneMusic vob {}; + zenkit::VZoneMusic vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK(vob.enabled); @@ -455,7 +438,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.volume, 1.0f); CHECK(vob.loop); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -466,18 +448,17 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCMessageFilter:zCVob"); - zenkit::vobs::MessageFilter vob {}; + zenkit::VMessageFilter vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.target, "EVT_ADDON_TROLLPORTAL_CAMERA_01"); CHECK_EQ(vob.on_trigger, zenkit::MessageFilterAction::UNTRIGGER); CHECK_EQ(vob.on_untrigger, zenkit::MessageFilterAction::UNTRIGGER); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } - static const std::vector G2_CODE_MASTER_SLAVES { + static std::vector const G2_CODE_MASTER_SLAVES { "EVT_ORNAMENT_SWITCH_BIGFARM_01", "EVT_ORNAMENT_SWITCH_BIGFARM_02", "EVT_ORNAMENT_SWITCH_BIGFARM_03", @@ -490,7 +471,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCCodeMaster:zCVob"); - zenkit::vobs::CodeMaster vob {}; + zenkit::VCodeMaster vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.target, "EVT_ORNAMENT_TRIGGER_BIGFARM_01"); @@ -500,11 +481,10 @@ TEST_SUITE("vobs") { CHECK_FALSE(vob.untriggered_cancels); CHECK_EQ(vob.slaves, G2_CODE_MASTER_SLAVES); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } - static const std::vector G2_TRIGGER_LIST_TARGETS { + static std::vector const G2_TRIGGER_LIST_TARGETS { {"EVT_ADDON_TROLLPORTAL_MASTERTRIGGERLIST_ALPHA_01", 0.0f}, {"EVT_ADDON_TROLLPORTAL_TRIGGERSCRIPT_01", 0.0f}, }; @@ -516,13 +496,12 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCTriggerList:zCTrigger:zCVob"); - zenkit::vobs::TriggerList vob {}; + zenkit::VTriggerList vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.mode, zenkit::TriggerBatchMode::ALL); CHECK_EQ(vob.targets, G2_TRIGGER_LIST_TARGETS); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -533,16 +512,15 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCTriggerScript:zCTrigger:zCVob"); - zenkit::vobs::TriggerScript vob {}; + zenkit::VTriggerScript vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.function, "EVT_CAVALORNSGOBBOS_FUNC"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } - static const std::vector G1_MOVER_KEYFRAMES { + static std::vector const G1_MOVER_KEYFRAMES { {glm::vec3 {29785.9609f, 5140.81982f, -16279.8477f}, glm::quat {0.999809802f, -0.000760567724f, 0.0174517576f, 0.00869333092f}}, {glm::vec3 {29785.9609f, 5720.81982f, -16279.8477f}, @@ -556,7 +534,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCMover:zCTrigger:zCVob"); - zenkit::vobs::Mover vob {}; + zenkit::VMover vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.behavior, zenkit::MoverBehavior::TOGGLE); @@ -578,7 +556,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.sfx_unlock, ""); CHECK_EQ(vob.sfx_use_locked, ""); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -589,13 +566,12 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCTriggerChangeLevel:zCTrigger:zCVob"); - zenkit::vobs::TriggerChangeLevel vob {}; + zenkit::VTriggerChangeLevel vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.level_name, "ADDON\\ADDONWORLD.ZEN"); CHECK_EQ(vob.start_vob, "START_ADDON"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -606,13 +582,12 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCTriggerWorldStart:zCVob"); - zenkit::vobs::TriggerWorldStart vob {}; + zenkit::VTriggerWorldStart vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.target, "EVT_TROLL_GRAVE_MOVER_01"); CHECK(vob.fire_once); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -623,12 +598,11 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCTriggerUntouch:zCVob"); - zenkit::vobs::TriggerUntouch vob {}; + zenkit::VTriggerUntouch vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.target, "EVT_TROLL_GRAVE_TRIGGERLIST_01"); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -639,14 +613,13 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "zCEarthquake:zCVob"); - zenkit::vobs::Earthquake vob {}; + zenkit::VEarthquake vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.radius, 1000.0f); CHECK_EQ(vob.duration, 5.0f); CHECK_EQ(vob.amplitude, glm::vec3 {2.0f, 10.0f, 2.0f}); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } @@ -657,7 +630,7 @@ TEST_SUITE("vobs") { CHECK(ar->read_object_begin(obj)); CHECK_EQ(obj.class_name, "oCTouchDamage:zCTouchDamage:zCVob"); - zenkit::vobs::TouchDamage vob {}; + zenkit::VTouchDamage vob {}; vob.load(*ar, zenkit::GameVersion::GOTHIC_2); CHECK_EQ(vob.damage, 1000.0f); @@ -673,7 +646,6 @@ TEST_SUITE("vobs") { CHECK_EQ(vob.volume_scale, 1.0f); CHECK_EQ(vob.collision, zenkit::TouchCollisionType::BOX); - CHECK_FALSE(vob.is_save_game()); CHECK(ar->read_object_end()); } diff --git a/tests/TestWorld.cc b/tests/TestWorld.cc index 1ccbd3cb..324d8d87 100644 --- a/tests/TestWorld.cc +++ b/tests/TestWorld.cc @@ -216,7 +216,7 @@ TEST_SUITE("World") { CHECK_EQ(vob0->sprite_camera_facing_mode, zenkit::SpriteAlignment::NONE); CHECK_EQ(vob0->anim_mode, zenkit::AnimationType::NONE); CHECK_EQ(vob0->anim_strength, 0.0f); - CHECK_EQ(vob0->far_clip_scale, 0.0f); + CHECK_EQ(vob0->far_clip_scale, 2.0f); CHECK(vob0->cd_static); CHECK_FALSE(vob0->cd_dynamic); CHECK_FALSE(vob0->vob_static); @@ -256,7 +256,7 @@ TEST_SUITE("World") { CHECK_EQ(child1->sprite_camera_facing_mode, zenkit::SpriteAlignment::NONE); CHECK_EQ(child1->anim_mode, zenkit::AnimationType::NONE); CHECK_EQ(child1->anim_strength, 0.0f); - CHECK_EQ(child1->far_clip_scale, 0.0f); + CHECK_EQ(child1->far_clip_scale, 2.0f); CHECK_FALSE(child1->cd_static); CHECK_FALSE(child1->cd_dynamic); CHECK_FALSE(child1->vob_static); @@ -293,7 +293,7 @@ TEST_SUITE("World") { CHECK_EQ(vob13->sprite_camera_facing_mode, zenkit::SpriteAlignment::NONE); CHECK_EQ(vob13->anim_mode, zenkit::AnimationType::NONE); CHECK_EQ(vob13->anim_strength, 0.0f); - CHECK_EQ(vob13->far_clip_scale, 0.0f); + CHECK_EQ(vob13->far_clip_scale, 2.0f); CHECK_FALSE(vob13->cd_static); CHECK_FALSE(vob13->cd_dynamic); CHECK_FALSE(vob13->vob_static);