diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js index 7cebbe856e..7d9e9e185b 100644 --- a/binaries/data/mods/public/gui/session/session.js +++ b/binaries/data/mods/public/gui/session/session.js @@ -359,6 +359,11 @@ function getSavedGameData() function restoreSavedGameData(data) { + // Restore camera if any + if (data.camera) + Engine.SetCameraData(data.camera.PosX, data.camera.PosY, data.camera.PosZ, + data.camera.RotX, data.camera.RotY, data.camera.Zoom); + // Clear selection when loading a game g_Selection.reset(); diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index 81e19117c0..c1464da1db 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -963,6 +963,54 @@ float CGameView::GetCameraZ() return pivot.Z; } +float CGameView::GetCameraPosX() +{ + return m->PosX.GetValue(); +} + +float CGameView::GetCameraPosY() +{ + return m->PosY.GetValue(); +} + +float CGameView::GetCameraPosZ() +{ + return m->PosZ.GetValue(); +} + +float CGameView::GetCameraRotX() +{ + return m->RotateX.GetValue(); +} + +float CGameView::GetCameraRotY() +{ + return m->RotateY.GetValue(); +} + +float CGameView::GetCameraZoom() +{ + return m->Zoom.GetValue(); +} + +void CGameView::SetCamera(CVector3D Pos, float RotX, float RotY, float zoom) +{ + m->PosX.SetValue(Pos.X); + m->PosY.SetValue(Pos.Y); + m->PosZ.SetValue(Pos.Z); + m->RotateX.SetValue(RotX); + m->RotateY.SetValue(RotY); + m->Zoom.SetValue(zoom); + + FocusHeight(m, false); + + SetupCameraMatrixNonSmooth(m, &m->ViewCamera.m_Orientation); + m->ViewCamera.UpdateFrustum(); + + // Break out of following mode so the camera really moves to the target + m->FollowEntity = INVALID_ENTITY; +} + void CGameView::MoveCameraTarget(const CVector3D& target) { // Maintain the same orientation and level of zoom, if we can diff --git a/source/graphics/GameView.h b/source/graphics/GameView.h index c79d542845..a95072b595 100644 --- a/source/graphics/GameView.h +++ b/source/graphics/GameView.h @@ -84,6 +84,13 @@ public: float GetCameraX(); float GetCameraZ(); + float GetCameraPosX(); + float GetCameraPosY(); + float GetCameraPosZ(); + float GetCameraRotX(); + float GetCameraRotY(); + float GetCameraZoom(); + void SetCamera(CVector3D Pos, float RotX, float RotY, float Zoom); void MoveCameraTarget(const CVector3D& target); void ResetCameraTarget(const CVector3D& target); void ResetCameraAngleZoom(); diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp index f55cc4a815..b8b50462c8 100644 --- a/source/gui/scripting/ScriptFunctions.cpp +++ b/source/gui/scripting/ScriptFunctions.cpp @@ -450,6 +450,23 @@ void CameraFollowFPS(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), entity_id_t g_Game->GetView()->CameraFollow(entityid, true); } +/** + * Set the data (position, orientation and zoom) of the camera + */ +void SetCameraData(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), entity_pos_t x, entity_pos_t y, entity_pos_t z, entity_pos_t rotx, entity_pos_t roty, entity_pos_t zoom) +{ + // called from JS; must not fail + if(!(g_Game && g_Game->GetWorld() && g_Game->GetView() && g_Game->GetWorld()->GetTerrain())) + return; + + CVector3D Pos = CVector3D(x.ToFloat(), y.ToFloat(), z.ToFloat()); + float RotX = rotx.ToFloat(); + float RotY = roty.ToFloat(); + float Zoom = zoom.ToFloat(); + + g_Game->GetView()->SetCamera(Pos, RotX, RotY, Zoom); +} + /// Move camera to a 2D location void CameraMoveTo(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), entity_pos_t x, entity_pos_t z) { @@ -849,6 +866,7 @@ void GuiScriptingInit(ScriptInterface& scriptInterface) scriptInterface.RegisterFunction("CameraGetZ"); scriptInterface.RegisterFunction("CameraFollow"); scriptInterface.RegisterFunction("CameraFollowFPS"); + scriptInterface.RegisterFunction("SetCameraData"); scriptInterface.RegisterFunction("CameraMoveTo"); scriptInterface.RegisterFunction("GetFollowedEntity"); scriptInterface.RegisterFunction("HotkeyIsPressed"); diff --git a/source/ps/SavedGame.cpp b/source/ps/SavedGame.cpp index ab6a4d4996..3347ff4159 100644 --- a/source/ps/SavedGame.cpp +++ b/source/ps/SavedGame.cpp @@ -19,11 +19,13 @@ #include "SavedGame.h" +#include "graphics/GameView.h" #include "gui/GUIManager.h" #include "lib/allocators/shared_ptr.h" #include "lib/file/archive/archive_zip.h" #include "ps/CLogger.h" #include "ps/Filesystem.h" +#include "ps/Game.h" #include "scriptinterface/ScriptInterface.h" #include "simulation2/Simulation2.h" @@ -84,6 +86,17 @@ Status SavedGames::Save(const std::wstring& name, const std::wstring& descriptio simulation.GetScriptInterface().SetProperty(metadata.get(), "initAttributes", simulation.GetInitAttributes()); CScriptVal guiMetadata = simulation.GetScriptInterface().ReadStructuredClone(guiMetadataClone); + + // get some camera data + CScriptVal cameraMetadata; + simulation.GetScriptInterface().Eval("({})", cameraMetadata); + simulation.GetScriptInterface().SetProperty(cameraMetadata.get(), "PosX", g_Game->GetView()->GetCameraPosX()); + simulation.GetScriptInterface().SetProperty(cameraMetadata.get(), "PosY", g_Game->GetView()->GetCameraPosY()); + simulation.GetScriptInterface().SetProperty(cameraMetadata.get(), "PosZ", g_Game->GetView()->GetCameraPosZ()); + simulation.GetScriptInterface().SetProperty(cameraMetadata.get(), "RotX", g_Game->GetView()->GetCameraRotX()); + simulation.GetScriptInterface().SetProperty(cameraMetadata.get(), "RotY", g_Game->GetView()->GetCameraRotY()); + simulation.GetScriptInterface().SetProperty(cameraMetadata.get(), "Zoom", g_Game->GetView()->GetCameraZoom()); + simulation.GetScriptInterface().SetProperty(guiMetadata.get(), "camera", cameraMetadata); simulation.GetScriptInterface().SetProperty(metadata.get(), "gui", guiMetadata); simulation.GetScriptInterface().SetProperty(metadata.get(), "description", description);